swarm_cli 2.1.13 → 3.0.0.alpha2

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -0
  3. data/exe/swarm3 +11 -0
  4. data/lib/swarm_cli/v3/activity_indicator.rb +168 -0
  5. data/lib/swarm_cli/v3/ansi_colors.rb +70 -0
  6. data/lib/swarm_cli/v3/cli.rb +721 -0
  7. data/lib/swarm_cli/v3/command_completer.rb +112 -0
  8. data/lib/swarm_cli/v3/display.rb +607 -0
  9. data/lib/swarm_cli/v3/dropdown.rb +130 -0
  10. data/lib/swarm_cli/v3/event_renderer.rb +161 -0
  11. data/lib/swarm_cli/v3/file_completer.rb +143 -0
  12. data/lib/swarm_cli/v3/raw_input_reader.rb +304 -0
  13. data/lib/swarm_cli/v3/reboot_tool.rb +123 -0
  14. data/lib/swarm_cli/v3/text_input.rb +235 -0
  15. data/lib/swarm_cli/v3.rb +52 -0
  16. metadata +30 -245
  17. data/exe/swarm +0 -6
  18. data/lib/swarm_cli/cli.rb +0 -201
  19. data/lib/swarm_cli/command_registry.rb +0 -61
  20. data/lib/swarm_cli/commands/mcp_serve.rb +0 -130
  21. data/lib/swarm_cli/commands/mcp_tools.rb +0 -148
  22. data/lib/swarm_cli/commands/migrate.rb +0 -55
  23. data/lib/swarm_cli/commands/run.rb +0 -173
  24. data/lib/swarm_cli/config_loader.rb +0 -98
  25. data/lib/swarm_cli/formatters/human_formatter.rb +0 -811
  26. data/lib/swarm_cli/formatters/json_formatter.rb +0 -62
  27. data/lib/swarm_cli/interactive_repl.rb +0 -895
  28. data/lib/swarm_cli/mcp_serve_options.rb +0 -44
  29. data/lib/swarm_cli/mcp_tools_options.rb +0 -59
  30. data/lib/swarm_cli/migrate_options.rb +0 -54
  31. data/lib/swarm_cli/migrator.rb +0 -132
  32. data/lib/swarm_cli/options.rb +0 -151
  33. data/lib/swarm_cli/ui/components/agent_badge.rb +0 -33
  34. data/lib/swarm_cli/ui/components/content_block.rb +0 -120
  35. data/lib/swarm_cli/ui/components/divider.rb +0 -57
  36. data/lib/swarm_cli/ui/components/panel.rb +0 -62
  37. data/lib/swarm_cli/ui/components/usage_stats.rb +0 -70
  38. data/lib/swarm_cli/ui/formatters/cost.rb +0 -49
  39. data/lib/swarm_cli/ui/formatters/number.rb +0 -58
  40. data/lib/swarm_cli/ui/formatters/text.rb +0 -77
  41. data/lib/swarm_cli/ui/formatters/time.rb +0 -73
  42. data/lib/swarm_cli/ui/icons.rb +0 -36
  43. data/lib/swarm_cli/ui/renderers/event_renderer.rb +0 -188
  44. data/lib/swarm_cli/ui/state/agent_color_cache.rb +0 -45
  45. data/lib/swarm_cli/ui/state/depth_tracker.rb +0 -40
  46. data/lib/swarm_cli/ui/state/spinner_manager.rb +0 -170
  47. data/lib/swarm_cli/ui/state/usage_tracker.rb +0 -62
  48. data/lib/swarm_cli/version.rb +0 -5
  49. data/lib/swarm_cli.rb +0 -46
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmCLI
4
- module UI
5
- module State
6
- # Manages active spinners with elapsed time display
7
- class SpinnerManager
8
- def initialize
9
- @active_spinners = {}
10
- @time_updaters = {}
11
- end
12
-
13
- # Start a spinner with elapsed time tracking
14
- #
15
- # @param key [Symbol, String] Unique key for this spinner
16
- # @param message [String] Spinner message
17
- # @param format [Symbol] Spinner format (:dots, :pulse, etc.)
18
- # @return [TTY::Spinner] The spinner instance
19
- def start(key, message, format: :dots)
20
- # Stop any existing spinner with this key
21
- stop(key) if @active_spinners[key]
22
-
23
- # Create spinner with elapsed time token
24
- spinner = TTY::Spinner.new(
25
- "[:spinner] #{message} (:elapsed)",
26
- format: format,
27
- hide_cursor: true,
28
- )
29
-
30
- spinner.auto_spin
31
-
32
- # Spawn thread to update elapsed time every 1 second
33
- # This is 10x slower than spinner animation (100ms), preventing flicker
34
- @time_updaters[key] = Thread.new do
35
- loop do
36
- elapsed = spinner.duration
37
- break unless elapsed
38
-
39
- formatted_time = format_duration(elapsed)
40
- spinner.update(elapsed: formatted_time)
41
- sleep(1.0) # 1s refresh rate - smooth without flicker
42
- rescue StandardError
43
- break
44
- end
45
- end
46
-
47
- @active_spinners[key] = spinner
48
- spinner
49
- end
50
-
51
- # Stop spinner with success
52
- #
53
- # @param key [Symbol, String] Spinner key
54
- # @param message [String] Success message
55
- def success(key, message = "completed")
56
- spinner = @active_spinners[key]
57
- return unless spinner
58
-
59
- # Kill time updater
60
- kill_updater(key)
61
-
62
- # Show final time
63
- final_time = format_duration(spinner.duration || 0)
64
- spinner.success("#{message} (#{final_time})")
65
-
66
- cleanup(key)
67
- end
68
-
69
- # Stop spinner with error
70
- #
71
- # @param key [Symbol, String] Spinner key
72
- # @param message [String] Error message
73
- def error(key, message = "failed")
74
- spinner = @active_spinners[key]
75
- return unless spinner
76
-
77
- # Kill time updater
78
- kill_updater(key)
79
-
80
- # Show final time
81
- final_time = format_duration(spinner.duration || 0)
82
- spinner.error("#{message} (#{final_time})")
83
-
84
- cleanup(key)
85
- end
86
-
87
- # Stop spinner without success/error (just stop)
88
- #
89
- # @param key [Symbol, String] Spinner key
90
- def stop(key)
91
- spinner = @active_spinners[key]
92
- return unless spinner
93
-
94
- kill_updater(key)
95
- spinner.stop
96
- cleanup(key)
97
- end
98
-
99
- # Stop all active spinners
100
- def stop_all
101
- @active_spinners.keys.each { |key| stop(key) }
102
- end
103
-
104
- # Check if a spinner is active
105
- #
106
- # @param key [Symbol, String] Spinner key
107
- # @return [Boolean]
108
- def active?(key)
109
- @active_spinners.key?(key)
110
- end
111
-
112
- # Pause all active spinners (for interactive debugging)
113
- #
114
- # This temporarily stops spinner animation while preserving state,
115
- # allowing interactive sessions like binding.irb to run cleanly.
116
- #
117
- # @return [void]
118
- def pause_all
119
- @active_spinners.each_value do |spinner|
120
- spinner.stop if spinner.spinning?
121
- end
122
-
123
- # Keep time updaters running (they'll safely handle stopped spinners)
124
- end
125
-
126
- # Resume all paused spinners
127
- #
128
- # Restarts spinner animation for all spinners that were paused.
129
- #
130
- # @return [void]
131
- def resume_all
132
- @active_spinners.each_value do |spinner|
133
- spinner.auto_spin unless spinner.spinning?
134
- end
135
- end
136
-
137
- private
138
-
139
- def kill_updater(key)
140
- updater = @time_updaters[key]
141
- return unless updater
142
-
143
- updater.kill if updater.alive?
144
- @time_updaters.delete(key)
145
- end
146
-
147
- def cleanup(key)
148
- @active_spinners.delete(key)
149
- @time_updaters.delete(key)
150
- end
151
-
152
- def format_duration(seconds)
153
- if seconds < 1
154
- "#{(seconds * 1000).round}ms"
155
- elsif seconds < 60
156
- "#{seconds.round}s"
157
- elsif seconds < 3600
158
- minutes = (seconds / 60).floor
159
- secs = (seconds % 60).round
160
- "#{minutes}m #{secs}s"
161
- else
162
- hours = (seconds / 3600).floor
163
- minutes = ((seconds % 3600) / 60).floor
164
- "#{hours}h #{minutes}m"
165
- end
166
- end
167
- end
168
- end
169
- end
170
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmCLI
4
- module UI
5
- module State
6
- # Tracks cumulative usage statistics during swarm execution
7
- class UsageTracker
8
- attr_reader :total_cost, :total_tokens, :llm_requests, :tool_calls
9
-
10
- def initialize
11
- @total_cost = 0.0
12
- @total_tokens = 0
13
- @llm_requests = 0
14
- @tool_calls = 0
15
- @agents_seen = Set.new
16
- @recent_tool_calls = {} # tool_call_id => tool_name for matching
17
- end
18
-
19
- # Track an LLM API call
20
- def track_llm_request(usage_data)
21
- @llm_requests += 1
22
-
23
- if usage_data
24
- @total_cost += usage_data[:total_cost] || 0.0
25
- @total_tokens += usage_data[:total_tokens] || 0
26
- end
27
- end
28
-
29
- # Track a tool call
30
- def track_tool_call(tool_call_id: nil, tool_name: nil)
31
- @tool_calls += 1
32
- @recent_tool_calls[tool_call_id] = tool_name if tool_call_id && tool_name
33
- end
34
-
35
- # Track agent usage
36
- def track_agent(agent_name)
37
- @agents_seen.add(agent_name)
38
- end
39
-
40
- # Get list of agents seen
41
- def agents
42
- @agents_seen.to_a
43
- end
44
-
45
- # Get tool name from call ID
46
- def tool_name_for(tool_call_id)
47
- @recent_tool_calls[tool_call_id]
48
- end
49
-
50
- # Reset all counters (for testing)
51
- def reset
52
- @total_cost = 0.0
53
- @total_tokens = 0
54
- @llm_requests = 0
55
- @tool_calls = 0
56
- @agents_seen.clear
57
- @recent_tool_calls.clear
58
- end
59
- end
60
- end
61
- end
62
- end
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmCLI
4
- VERSION = "2.1.13"
5
- end
data/lib/swarm_cli.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "fileutils"
4
- require "json"
5
- require "pathname"
6
- require "yaml"
7
-
8
- require "reline"
9
- require "pastel"
10
- require "tty-box"
11
- require "tty-screen"
12
- require "tty/link"
13
- require "tty/markdown"
14
- require "tty/option"
15
- require "tty/spinner"
16
- require "tty/spinner/multi"
17
- require "tty/tree"
18
-
19
- require "swarm_sdk"
20
-
21
- require_relative "swarm_cli/version"
22
-
23
- require "zeitwerk"
24
- loader = Zeitwerk::Loader.new
25
- loader.tag = File.basename(__FILE__, ".rb")
26
- loader.push_dir("#{__dir__}/swarm_cli", namespace: SwarmCLI)
27
- loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
28
- loader.inflector.inflect(
29
- "cli" => "CLI",
30
- "ui" => "UI",
31
- "interactive_repl" => "InteractiveREPL",
32
- )
33
- loader.setup
34
-
35
- module SwarmCLI
36
- class Error < StandardError; end
37
- class ConfigurationError < Error; end
38
- class ExecutionError < Error; end
39
- end
40
-
41
- # Try to load swarm_memory gem if available (for CLI command extensions)
42
- begin
43
- require "swarm_memory"
44
- rescue LoadError
45
- # swarm_memory not installed - that's fine, memory commands won't be available
46
- end