superkick 0.1.0

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 (199) hide show
  1. checksums.yaml +7 -0
  2. data/CLA.md +91 -0
  3. data/CLAUDE.md +2226 -0
  4. data/CONTRIBUTING.md +104 -0
  5. data/LICENSE +108 -0
  6. data/LICENSE-COMMERCIAL.md +39 -0
  7. data/PLAN.md +161 -0
  8. data/README.md +1155 -0
  9. data/exe/superkick +6 -0
  10. data/lib/superkick/agent/runtime.rb +82 -0
  11. data/lib/superkick/agent/runtimes/local.rb +74 -0
  12. data/lib/superkick/agent/runtimes.rb +4 -0
  13. data/lib/superkick/agent.rb +209 -0
  14. data/lib/superkick/agent_store.rb +85 -0
  15. data/lib/superkick/attach/client.rb +245 -0
  16. data/lib/superkick/attach/protocol.rb +71 -0
  17. data/lib/superkick/attach/server.rb +371 -0
  18. data/lib/superkick/budget_checker.rb +120 -0
  19. data/lib/superkick/buffer/client.rb +91 -0
  20. data/lib/superkick/buffer/server.rb +127 -0
  21. data/lib/superkick/cli/agent.rb +524 -0
  22. data/lib/superkick/cli/completion.rb +591 -0
  23. data/lib/superkick/cli/goal.rb +71 -0
  24. data/lib/superkick/cli/mcp.rb +34 -0
  25. data/lib/superkick/cli/monitor.rb +47 -0
  26. data/lib/superkick/cli/notifier.rb +39 -0
  27. data/lib/superkick/cli/repository.rb +46 -0
  28. data/lib/superkick/cli/server.rb +106 -0
  29. data/lib/superkick/cli/setup.rb +166 -0
  30. data/lib/superkick/cli/spawner.rb +85 -0
  31. data/lib/superkick/cli/team.rb +407 -0
  32. data/lib/superkick/cli.rb +175 -0
  33. data/lib/superkick/client_registry.rb +30 -0
  34. data/lib/superkick/configuration.rb +178 -0
  35. data/lib/superkick/connection.rb +56 -0
  36. data/lib/superkick/control/client.rb +78 -0
  37. data/lib/superkick/control/reply.rb +43 -0
  38. data/lib/superkick/control/server.rb +1271 -0
  39. data/lib/superkick/cost_accumulator.rb +53 -0
  40. data/lib/superkick/cost_extractor.rb +65 -0
  41. data/lib/superkick/cost_poller.rb +70 -0
  42. data/lib/superkick/driver/profile_source.rb +134 -0
  43. data/lib/superkick/driver.rb +179 -0
  44. data/lib/superkick/drivers/claude_code.rb +110 -0
  45. data/lib/superkick/drivers/codex.rb +57 -0
  46. data/lib/superkick/drivers/copilot.rb +75 -0
  47. data/lib/superkick/drivers/gemini.rb +86 -0
  48. data/lib/superkick/drivers/goose.rb +74 -0
  49. data/lib/superkick/drivers.rb +16 -0
  50. data/lib/superkick/drop.rb +80 -0
  51. data/lib/superkick/drops.rb +76 -0
  52. data/lib/superkick/environment_executor.rb +90 -0
  53. data/lib/superkick/goal.rb +95 -0
  54. data/lib/superkick/goals/agent_exit.rb +41 -0
  55. data/lib/superkick/goals/agent_signal.rb +42 -0
  56. data/lib/superkick/goals/command.rb +103 -0
  57. data/lib/superkick/history_buffer.rb +38 -0
  58. data/lib/superkick/hosted/attach/bridge.rb +52 -0
  59. data/lib/superkick/hosted/attach/client.rb +208 -0
  60. data/lib/superkick/hosted/attach/relay.rb +313 -0
  61. data/lib/superkick/hosted/attach/relay_store.rb +48 -0
  62. data/lib/superkick/hosted/bridge.rb +263 -0
  63. data/lib/superkick/hosted/buffer/bridge.rb +42 -0
  64. data/lib/superkick/hosted/buffer/client.rb +63 -0
  65. data/lib/superkick/hosted/buffer/relay.rb +126 -0
  66. data/lib/superkick/hosted/buffer/relay_store.rb +42 -0
  67. data/lib/superkick/hosted/control/client.rb +84 -0
  68. data/lib/superkick/hosted/mcp_proxy.rb +144 -0
  69. data/lib/superkick/inject_handler.rb +24 -0
  70. data/lib/superkick/injection_guard.rb +26 -0
  71. data/lib/superkick/injection_queue.rb +177 -0
  72. data/lib/superkick/injector.rb +65 -0
  73. data/lib/superkick/input_buffer.rb +171 -0
  74. data/lib/superkick/integrations/bugsnag/README.md +98 -0
  75. data/lib/superkick/integrations/bugsnag/spawner.rb +307 -0
  76. data/lib/superkick/integrations/bugsnag/templates/error_opened.liquid +17 -0
  77. data/lib/superkick/integrations/bugsnag.rb +7 -0
  78. data/lib/superkick/integrations/circleci/README.md +75 -0
  79. data/lib/superkick/integrations/circleci/monitor.rb +185 -0
  80. data/lib/superkick/integrations/circleci/probe.rb +36 -0
  81. data/lib/superkick/integrations/circleci/templates/ci_failure.liquid +8 -0
  82. data/lib/superkick/integrations/circleci/templates/ci_success.liquid +1 -0
  83. data/lib/superkick/integrations/circleci.rb +8 -0
  84. data/lib/superkick/integrations/datadog/README.md +253 -0
  85. data/lib/superkick/integrations/datadog/alert_goal.rb +94 -0
  86. data/lib/superkick/integrations/datadog/alert_monitor.rb +163 -0
  87. data/lib/superkick/integrations/datadog/alert_spawner.rb +201 -0
  88. data/lib/superkick/integrations/datadog/notification_templates/default.liquid +10 -0
  89. data/lib/superkick/integrations/datadog/notifier.rb +294 -0
  90. data/lib/superkick/integrations/datadog/spawner.rb +201 -0
  91. data/lib/superkick/integrations/datadog/templates/alert_changed.liquid +8 -0
  92. data/lib/superkick/integrations/datadog/templates/alert_escalated.liquid +8 -0
  93. data/lib/superkick/integrations/datadog/templates/alert_recovered.liquid +14 -0
  94. data/lib/superkick/integrations/datadog/templates/alert_triggered.liquid +29 -0
  95. data/lib/superkick/integrations/datadog/templates/error_opened.liquid +15 -0
  96. data/lib/superkick/integrations/datadog.rb +14 -0
  97. data/lib/superkick/integrations/docker/README.md +256 -0
  98. data/lib/superkick/integrations/docker/client.rb +295 -0
  99. data/lib/superkick/integrations/docker/runtime.rb +218 -0
  100. data/lib/superkick/integrations/docker.rb +4 -0
  101. data/lib/superkick/integrations/git/repository_source.rb +66 -0
  102. data/lib/superkick/integrations/git/version_control.rb +119 -0
  103. data/lib/superkick/integrations/git.rb +8 -0
  104. data/lib/superkick/integrations/github/README.md +300 -0
  105. data/lib/superkick/integrations/github/check_failed_spawner.rb +199 -0
  106. data/lib/superkick/integrations/github/drops.rb +114 -0
  107. data/lib/superkick/integrations/github/goal.rb +135 -0
  108. data/lib/superkick/integrations/github/issue_goal.rb +104 -0
  109. data/lib/superkick/integrations/github/issue_spawner.rb +160 -0
  110. data/lib/superkick/integrations/github/monitor.rb +251 -0
  111. data/lib/superkick/integrations/github/probe.rb +30 -0
  112. data/lib/superkick/integrations/github/repository_source.rb +228 -0
  113. data/lib/superkick/integrations/github/templates/check_failed.liquid +10 -0
  114. data/lib/superkick/integrations/github/templates/ci_failure.liquid +5 -0
  115. data/lib/superkick/integrations/github/templates/ci_success.liquid +1 -0
  116. data/lib/superkick/integrations/github/templates/issue_opened.liquid +20 -0
  117. data/lib/superkick/integrations/github/templates/pr_comment.liquid +2 -0
  118. data/lib/superkick/integrations/github/templates/pr_review.liquid +4 -0
  119. data/lib/superkick/integrations/github.rb +16 -0
  120. data/lib/superkick/integrations/honeybadger/README.md +97 -0
  121. data/lib/superkick/integrations/honeybadger/notification_templates/default.liquid +8 -0
  122. data/lib/superkick/integrations/honeybadger/notifier.rb +250 -0
  123. data/lib/superkick/integrations/honeybadger/spawner.rb +214 -0
  124. data/lib/superkick/integrations/honeybadger/templates/error_opened.liquid +17 -0
  125. data/lib/superkick/integrations/honeybadger.rb +9 -0
  126. data/lib/superkick/integrations/shell/README.md +83 -0
  127. data/lib/superkick/integrations/shell/monitor.rb +87 -0
  128. data/lib/superkick/integrations/shell/templates/shell_alert.liquid +6 -0
  129. data/lib/superkick/integrations/shell/templates/shell_success.liquid +6 -0
  130. data/lib/superkick/integrations/shell.rb +7 -0
  131. data/lib/superkick/integrations/shortcut/README.md +193 -0
  132. data/lib/superkick/integrations/shortcut/drops.rb +91 -0
  133. data/lib/superkick/integrations/shortcut/monitor.rb +582 -0
  134. data/lib/superkick/integrations/shortcut/probe.rb +34 -0
  135. data/lib/superkick/integrations/shortcut/spawner.rb +264 -0
  136. data/lib/superkick/integrations/shortcut/templates/related_story_changed.liquid +6 -0
  137. data/lib/superkick/integrations/shortcut/templates/story_blocker.liquid +8 -0
  138. data/lib/superkick/integrations/shortcut/templates/story_comment.liquid +5 -0
  139. data/lib/superkick/integrations/shortcut/templates/story_description_changed.liquid +19 -0
  140. data/lib/superkick/integrations/shortcut/templates/story_owner_changed.liquid +10 -0
  141. data/lib/superkick/integrations/shortcut/templates/story_ready.liquid +41 -0
  142. data/lib/superkick/integrations/shortcut/templates/story_state_changed.liquid +9 -0
  143. data/lib/superkick/integrations/shortcut/templates/story_unblocked.liquid +5 -0
  144. data/lib/superkick/integrations/shortcut.rb +11 -0
  145. data/lib/superkick/integrations/slack/README.md +297 -0
  146. data/lib/superkick/integrations/slack/drops.rb +70 -0
  147. data/lib/superkick/integrations/slack/notifier.rb +426 -0
  148. data/lib/superkick/integrations/slack/spawner.rb +251 -0
  149. data/lib/superkick/integrations/slack/templates/default.liquid +17 -0
  150. data/lib/superkick/integrations/slack/templates/slack_reply.liquid +3 -0
  151. data/lib/superkick/integrations/slack/templates/spawn/slack_message.liquid +10 -0
  152. data/lib/superkick/integrations/slack/thread_monitor.rb +161 -0
  153. data/lib/superkick/integrations/slack.rb +12 -0
  154. data/lib/superkick/liquid.rb +129 -0
  155. data/lib/superkick/local/repository_source.rb +148 -0
  156. data/lib/superkick/mcp_server.rb +596 -0
  157. data/lib/superkick/monitor.rb +215 -0
  158. data/lib/superkick/notification_dispatcher.rb +280 -0
  159. data/lib/superkick/notifier.rb +173 -0
  160. data/lib/superkick/notifier_state_store.rb +55 -0
  161. data/lib/superkick/notifier_template.rb +121 -0
  162. data/lib/superkick/notifiers/command.rb +124 -0
  163. data/lib/superkick/notifiers/terminal_bell.rb +41 -0
  164. data/lib/superkick/output_logger.rb +54 -0
  165. data/lib/superkick/poller.rb +126 -0
  166. data/lib/superkick/process_runner.rb +87 -0
  167. data/lib/superkick/pty_proxy.rb +403 -0
  168. data/lib/superkick/registry.rb +75 -0
  169. data/lib/superkick/repository_source.rb +195 -0
  170. data/lib/superkick/server.rb +211 -0
  171. data/lib/superkick/session_recorder.rb +154 -0
  172. data/lib/superkick/setup.rb +160 -0
  173. data/lib/superkick/spawn/agent_spawner.rb +311 -0
  174. data/lib/superkick/spawn/approval_store.rb +113 -0
  175. data/lib/superkick/spawn/handler.rb +144 -0
  176. data/lib/superkick/spawn/injector.rb +119 -0
  177. data/lib/superkick/spawn/workflow_executor.rb +196 -0
  178. data/lib/superkick/spawn/workflow_validator.rb +77 -0
  179. data/lib/superkick/spawner.rb +67 -0
  180. data/lib/superkick/supervisor.rb +516 -0
  181. data/lib/superkick/team/artifact_store.rb +92 -0
  182. data/lib/superkick/team/log.rb +140 -0
  183. data/lib/superkick/team/log_entry_drop.rb +34 -0
  184. data/lib/superkick/team/log_monitor.rb +84 -0
  185. data/lib/superkick/team/log_notifier.rb +96 -0
  186. data/lib/superkick/team/log_store.rb +40 -0
  187. data/lib/superkick/template_filters.rb +24 -0
  188. data/lib/superkick/template_renderer.rb +223 -0
  189. data/lib/superkick/templates/team_log/planning_agent.liquid +38 -0
  190. data/lib/superkick/templates/team_log/team_digest.liquid +45 -0
  191. data/lib/superkick/templates/team_log/teammate_message.liquid +7 -0
  192. data/lib/superkick/templates/team_log/worker_kickoff.liquid +37 -0
  193. data/lib/superkick/templates/workflow/workflow_triggered.liquid +22 -0
  194. data/lib/superkick/version.rb +5 -0
  195. data/lib/superkick/version_control.rb +135 -0
  196. data/lib/superkick/yaml_config.rb +302 -0
  197. data/lib/superkick.rb +198 -0
  198. data/plan.md +267 -0
  199. metadata +404 -0
data/lib/superkick.rb ADDED
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Standard library
4
+ require "fileutils"
5
+ require "json"
6
+ require "logger"
7
+ require "socket"
8
+ require "base64"
9
+ require "time"
10
+ require "yaml"
11
+ require "liquid"
12
+ require "faraday"
13
+ require "faraday/multipart"
14
+ require "timeout"
15
+ require "shellwords"
16
+
17
+ # Core (dependency-free)
18
+ require_relative "superkick/registry"
19
+ require_relative "superkick/version"
20
+ require_relative "superkick/drop"
21
+ require_relative "superkick/drops"
22
+ require_relative "superkick/configuration"
23
+ require_relative "superkick/injection_guard"
24
+ require_relative "superkick/connection"
25
+ require_relative "superkick/process_runner"
26
+
27
+ # Agent runtimes (process management backends)
28
+ require_relative "superkick/agent/runtimes"
29
+
30
+ # Persistence
31
+ require_relative "superkick/repository_source"
32
+ require_relative "superkick/local/repository_source"
33
+ require_relative "superkick/agent"
34
+ require_relative "superkick/environment_executor"
35
+ require_relative "superkick/agent_store"
36
+ require_relative "superkick/team/log"
37
+ require_relative "superkick/team/log_store"
38
+ require_relative "superkick/team/artifact_store"
39
+
40
+ # Client registry (shared by Control, Buffer, Attach)
41
+ require_relative "superkick/client_registry"
42
+
43
+ # Control plane
44
+ require_relative "superkick/control/reply"
45
+ require_relative "superkick/control/client"
46
+ require_relative "superkick/control/server"
47
+
48
+ # Buffer (agent↔server data plane)
49
+ require_relative "superkick/buffer/client"
50
+ require_relative "superkick/buffer/server"
51
+
52
+ # Pty
53
+ require_relative "superkick/input_buffer"
54
+ require_relative "superkick/output_logger"
55
+ require_relative "superkick/session_recorder"
56
+ require_relative "superkick/attach/protocol"
57
+ require_relative "superkick/history_buffer"
58
+ require_relative "superkick/attach/server"
59
+ require_relative "superkick/attach/client"
60
+
61
+ # Hosted mode — base class + all hosted overlays (after base classes they inherit from)
62
+ require_relative "superkick/hosted/bridge"
63
+ require_relative "superkick/hosted/control/client"
64
+ require_relative "superkick/hosted/buffer/client"
65
+ require_relative "superkick/hosted/buffer/relay"
66
+ require_relative "superkick/hosted/buffer/relay_store"
67
+ require_relative "superkick/hosted/buffer/bridge"
68
+ require_relative "superkick/hosted/attach/client"
69
+ require_relative "superkick/hosted/attach/relay"
70
+ require_relative "superkick/hosted/attach/relay_store"
71
+ require_relative "superkick/hosted/attach/bridge"
72
+ require_relative "superkick/pty_proxy"
73
+
74
+ # Injection queue + injection
75
+ require_relative "superkick/injection_queue"
76
+ require_relative "superkick/injector"
77
+ require_relative "superkick/inject_handler"
78
+ require_relative "superkick/template_filters"
79
+ require_relative "superkick/template_renderer"
80
+ require_relative "superkick/notifier_template"
81
+
82
+ # Notifiers (post-injection user notifications)
83
+ require_relative "superkick/notifier_state_store"
84
+ require_relative "superkick/notifier"
85
+ require_relative "superkick/notification_dispatcher"
86
+ require_relative "superkick/notifiers/terminal_bell"
87
+ require_relative "superkick/notifiers/command"
88
+ require_relative "superkick/team/log_notifier"
89
+
90
+ # Polling base class + monitor and spawner base classes
91
+ require_relative "superkick/poller"
92
+ require_relative "superkick/monitor"
93
+ require_relative "superkick/team/log_entry_drop"
94
+ require_relative "superkick/team/log_monitor"
95
+ require_relative "superkick/spawner"
96
+ require_relative "superkick/supervisor"
97
+
98
+ # Version control adapters
99
+ require_relative "superkick/version_control"
100
+
101
+ # Goals (spawned agent completion checks)
102
+ require_relative "superkick/goal"
103
+ require_relative "superkick/goals/agent_exit"
104
+ require_relative "superkick/goals/command"
105
+ require_relative "superkick/goals/agent_signal"
106
+
107
+ # Cost tracking
108
+ require_relative "superkick/cost_accumulator"
109
+ require_relative "superkick/cost_extractor"
110
+ require_relative "superkick/cost_poller"
111
+ require_relative "superkick/budget_checker"
112
+
113
+ # Spawner infrastructure
114
+ require_relative "superkick/spawn/handler"
115
+ require_relative "superkick/spawn/injector"
116
+ require_relative "superkick/spawn/agent_spawner"
117
+ require_relative "superkick/spawn/approval_store"
118
+ require_relative "superkick/spawn/workflow_validator"
119
+ require_relative "superkick/spawn/workflow_executor"
120
+
121
+ # Integrations (monitors, spawners, notifiers, runtimes)
122
+ require_relative "superkick/integrations/git"
123
+ require_relative "superkick/integrations/docker"
124
+ require_relative "superkick/integrations/github"
125
+ require_relative "superkick/integrations/shell"
126
+ require_relative "superkick/integrations/circleci"
127
+ require_relative "superkick/integrations/shortcut"
128
+ require_relative "superkick/integrations/bugsnag"
129
+ require_relative "superkick/integrations/slack"
130
+ require_relative "superkick/integrations/datadog"
131
+ require_relative "superkick/integrations/honeybadger"
132
+
133
+ # Drivers — loads Driver base class then all built-in driver subclasses.
134
+ require_relative "superkick/drivers"
135
+ require_relative "superkick/driver/profile_source"
136
+
137
+ # Config loading
138
+ require_relative "superkick/yaml_config"
139
+
140
+ # Setup wizard
141
+ require_relative "superkick/setup"
142
+
143
+ # MCP server + CLI
144
+ require_relative "superkick/mcp_server"
145
+ require_relative "superkick/hosted/mcp_proxy"
146
+ require_relative "superkick/server"
147
+ require_relative "superkick/cli"
148
+
149
+ module Superkick
150
+ class << self
151
+ def config
152
+ @config ||= Configuration.new
153
+ end
154
+
155
+ def configure
156
+ yield config
157
+ end
158
+
159
+ def logger
160
+ @logger ||= begin
161
+ l = Logger.new($stderr)
162
+ l.level = config.log_level
163
+ l.formatter = proc do |severity, datetime, progname, msg|
164
+ "#{datetime.strftime("%Y-%m-%d %H:%M:%S")} #{severity.ljust(5)} [#{progname}] #{msg}\n"
165
+ end
166
+ l
167
+ end
168
+ end
169
+
170
+ attr_writer :logger
171
+
172
+ # The active driver instance, set by Superkick.use.
173
+ attr_reader :driver
174
+
175
+ # Look up a driver class by name, instantiate it with opts, and store it.
176
+ def use(driver_name, **opts)
177
+ klass = Driver.lookup(driver_name)
178
+ @driver = klass.new(**opts)
179
+ end
180
+
181
+ alias_method :configure_for, :use
182
+
183
+ # Load YAML config then Ruby config from base_dir.
184
+ def load_config!
185
+ yaml_path = File.join(config.base_dir, "config.yml")
186
+ rb_path = File.join(config.base_dir, "config.rb")
187
+
188
+ YamlConfig.load!(yaml_path) if File.exist?(yaml_path)
189
+ load(rb_path) if File.exist?(rb_path)
190
+ end
191
+
192
+ def reset_config!
193
+ @config = Configuration.new
194
+ @driver = nil
195
+ TemplateRenderer.reset_environments!
196
+ end
197
+ end
198
+ end
data/plan.md ADDED
@@ -0,0 +1,267 @@
1
+ # Plan: `superkick setup` Command
2
+
3
+ ## Overview
4
+
5
+ Add an interactive `superkick setup` command that walks first-time users through creating a well-documented `config.yml`, configuring MCP, and installing shell completions. Each integration (monitor, spawner, notifier, repository source) provides its own YAML config template so the generated config is self-documenting with comments, reasonable defaults, and `env()` ERB helpers for secrets.
6
+
7
+ Uses the [`tty-prompt`](https://github.com/piotrmurach/tty-prompt) gem for interactive multi-select menus, single-select driver choice, and yes/no prompts.
8
+
9
+ ## Design
10
+
11
+ ### Config Template System
12
+
13
+ Each extensibility point (Monitor, Spawner, Notifier, RepositorySource) gains an optional `self.setup_config` class method that returns a YAML string snippet. This is raw YAML text (not a hash) so it can include comments. The setup command concatenates selected snippets into the final `config.yml`.
14
+
15
+ ```ruby
16
+ # Example: on Integrations::GitHub::Monitor
17
+ def self.setup_config
18
+ <<~YAML
19
+ github:
20
+ token: <%%= env("GITHUB_TOKEN") %>
21
+ # repo and branch are auto-detected from git remote.
22
+ # Uncomment to override:
23
+ # repo: org/repo
24
+ # branch: main
25
+ YAML
26
+ end
27
+ ```
28
+
29
+ **Why raw YAML strings instead of structured hashes?** Because comments are the whole point — they make the generated config self-documenting. `YAML.dump` cannot produce comments. Each integration knows its own config best and can provide contextual help inline.
30
+
31
+ The base classes (`Poller`, `Notifier`, `RepositorySource`) define `self.setup_config = nil` as the default. Integrations that want to participate in setup override it.
32
+
33
+ ### Gate: `setup_label`
34
+
35
+ Each base class also gains `self.setup_label = nil`. This returns a short human-readable name for the setup menu (e.g., `"GitHub"`, `"CircleCI"`, `"Slack"`). When nil, the integration doesn't appear in setup. When both `setup_config` and `setup_label` are defined, the integration is selectable.
36
+
37
+ This keeps things simple: internal-only integrations like `Slack::ThreadMonitor` (auto-attached by spawner) just don't define `setup_label`.
38
+
39
+ ### Setup Flow
40
+
41
+ 1. **Welcome** — brief explanation of what setup does
42
+ 2. **Check for existing config** — if `config.yml` exists, ask to overwrite or abort
43
+ 3. **Choose driver** — auto-detect installed AI CLIs from `$PATH`, present as `tty-prompt` `select` menu with detected ones marked
44
+ 4. **Select monitors** — `tty-prompt` `multi_select` of all monitors with `setup_label`. Each shows label + first line of `description`
45
+ 5. **Select spawners** — same pattern. Skip section entirely if user selects none (spawners are advanced)
46
+ 6. **Select notifications** — same pattern. Default pre-selects `terminal_bell`
47
+ 7. **Select repository sources** — same pattern. Skip if none
48
+ 8. **Generate `config.yml`** — assemble from driver + selected templates + commented-out tuning section
49
+ 9. **Install MCP** — call `driver.install_mcp(exe_path:)`
50
+ 10. **Shell completions** — offer to print the `eval` line for their shell
51
+ 11. **Print next steps** — `superkick server start -d` then `superkick agent start`
52
+
53
+ ### Generated Config Structure
54
+
55
+ ```yaml
56
+ # Superkick configuration
57
+ # Generated by `superkick setup` on 2026-03-21
58
+ # Docs: https://github.com/admtnnr/superkick
59
+
60
+ driver: claude_code
61
+
62
+ # ── Monitors ─────────────────────────────────────────────
63
+ # Monitors watch external services and inject context into your AI CLI.
64
+ # Config values like repo and branch are auto-detected at runtime.
65
+ monitors:
66
+ github:
67
+ token: <%%= env("GITHUB_TOKEN") %>
68
+ # repo and branch are auto-detected from git remote.
69
+ # Uncomment to override:
70
+ # repo: org/repo
71
+ # branch: main
72
+
73
+ disk_check:
74
+ type: shell
75
+ command: .superkick/shell/disk-check
76
+ # timeout: 30
77
+ # report_success: false
78
+
79
+ # ── Notifications ────────────────────────────────────────
80
+ # Notifications fire after injections and agent lifecycle events.
81
+ notifications:
82
+ - type: terminal_bell
83
+
84
+ # ── Settings ─────────────────────────────────────────────
85
+ # Uncomment to customize. Defaults are shown.
86
+ # superkick:
87
+ # poll_interval: 30 # seconds between monitor ticks
88
+ # idle_threshold: 5.0 # seconds CLI must be idle before injection
89
+ # log_level: info # debug, info, warn, error
90
+ ```
91
+
92
+ Sections are only included when the user selected items for that category. The settings section is always appended (commented out).
93
+
94
+ ## Implementation Steps
95
+
96
+ ### Step 1: Add `tty-prompt` dependency
97
+
98
+ Add `spec.add_dependency "tty-prompt", "~> 0.23"` to `superkick.gemspec`.
99
+
100
+ ### Step 2: Add `self.setup_config` and `self.setup_label` to base classes
101
+
102
+ Add default `nil` implementations to:
103
+ - `Superkick::Poller` (covers Monitor and Spawner via inheritance)
104
+ - `Superkick::Notifier`
105
+ - `Superkick::RepositorySource`
106
+
107
+ ### Step 3: Add `setup_config` and `setup_label` to built-in integrations
108
+
109
+ Each snippet uses `<%= env("...") %>` for secrets, shows required keys uncommented, optional keys commented with defaults, and inline help comments.
110
+
111
+ **Monitors:**
112
+ - `Integrations::GitHub::Monitor` — label: `"GitHub"`, token via env, repo/branch commented (auto-detected)
113
+ - `Integrations::CircleCI::Monitor` — label: `"CircleCI"`, token via env, project_slug/branch commented (auto-detected)
114
+ - `Integrations::Shortcut::Monitor` — label: `"Shortcut"`, token via env, story_id commented (auto-detected from branch)
115
+ - `Integrations::Shell::Monitor` — label: `"Shell"`, command placeholder, timeout/report_success commented
116
+ - `Integrations::Datadog::AlertMonitor` — label: `"Datadog Alert"`, monitor_id placeholder, api_key/app_key via env
117
+ - (Skip `Slack::ThreadMonitor` — auto-attached by spawner, not user-configured)
118
+
119
+ **Spawners:**
120
+ - `Integrations::GitHub::IssueSpawner` — label: `"GitHub Issues"`, repo, token, labels, goal config
121
+ - `Integrations::GitHub::CheckFailedSpawner` — label: `"GitHub Check Failures"`, repo, branches, token
122
+ - `Integrations::Shortcut::Spawner` — label: `"Shortcut"`, query, token
123
+ - `Integrations::Slack::Spawner` — label: `"Slack"`, channel, token
124
+ - `Integrations::Bugsnag::Spawner` — label: `"Bugsnag"`, project_id, token
125
+ - `Integrations::Datadog::Spawner` — label: `"Datadog Errors"`, service, environment, api_key/app_key
126
+ - `Integrations::Datadog::AlertSpawner` — label: `"Datadog Alerts"`, tags, statuses, api_key/app_key
127
+ - `Integrations::Honeybadger::Spawner` — label: `"Honeybadger"`, project_id, token
128
+
129
+ **Notifiers:**
130
+ - `Notifiers::TerminalBell` — label: `"Terminal Bell"`, just `type: terminal_bell`
131
+ - `Notifiers::Command` — label: `"Command"`, run command with example
132
+ - `Integrations::Slack::Notifier` — label: `"Slack"`, webhook_url or token+channel
133
+ - `Integrations::Datadog::Notifier` — label: `"Datadog"`, statsd_host, statsd_port, prefix
134
+ - `Integrations::Honeybadger::Notifier` — label: `"Honeybadger"`, api_key
135
+
136
+ **Repository Sources:**
137
+ - `Local::RepositorySource` — label: `"Local"`, path example
138
+ - `Integrations::Git::RepositorySource` — label: `"Git URL"`, url example
139
+ - `Integrations::GitHub::OrganizationRepositorySource` — label: `"GitHub Organization"`, organization, token
140
+
141
+ ### Step 4: Implement `Superkick::Setup` class
142
+
143
+ Create `lib/superkick/setup.rb`. This class encapsulates config generation logic, keeping it separate from the Thor command for testability.
144
+
145
+ ```ruby
146
+ module Superkick
147
+ class Setup
148
+ def initialize(base_dir:)
149
+
150
+ # Returns Array of { name:, cli_command:, installed: } for each registered driver
151
+ def detect_drivers
152
+
153
+ # Returns Array of { type:, label:, description: } for each monitor with setup_label
154
+ def available_monitors
155
+
156
+ # Same pattern for spawners, notifiers, repository_sources
157
+ def available_spawners
158
+ def available_notifiers
159
+ def available_repository_sources
160
+
161
+ # Assembles the final config.yml string from selected components
162
+ # driver: Symbol, monitors/spawners/notifiers/repository_sources: Array of type Symbols
163
+ def generate_config(driver:, monitors: [], spawners: [], notifiers: [], repository_sources: [])
164
+ end
165
+ end
166
+ ```
167
+
168
+ `generate_config` builds the YAML string by:
169
+ 1. Writing header comment with timestamp
170
+ 2. Writing `driver:` line
171
+ 3. For each section (monitors, spawners, etc.), writing section header comment + concatenated `setup_config` snippets from selected types, indented appropriately under the YAML key
172
+ 4. Appending the commented-out settings section
173
+
174
+ ### Step 5: Implement `CLI::Setup` Thor subcommand
175
+
176
+ Create `lib/superkick/cli/setup.rb`. Single default command `start` that drives the interactive flow.
177
+
178
+ Uses `TTY::Prompt` for all interactive prompts:
179
+ - `prompt.select("Which AI CLI driver?", choices)` — for driver
180
+ - `prompt.multi_select("Which monitors?", choices)` — for monitors, spawners, etc.
181
+ - `prompt.yes?("Configure MCP?")` — for MCP and completions
182
+
183
+ Options for non-interactive/partial use:
184
+ - `--driver DRIVER` — skip driver prompt
185
+ - `--force` — overwrite existing config
186
+ - `--skip-mcp` — skip MCP configuration step
187
+ - `--skip-completions` — skip shell completion offer
188
+
189
+ Register in `cli.rb`:
190
+ ```ruby
191
+ require_relative "cli/setup"
192
+ register CLI::Setup, "setup", "setup", "Interactive first-time setup"
193
+ ```
194
+
195
+ ### Step 6: Tests
196
+
197
+ **`test/setup_test.rb`** — tests for the `Setup` class:
198
+ - `generate_config` with various combinations produces valid YAML (after ERB substitution)
199
+ - `detect_drivers` returns all registered drivers with installed status
200
+ - `available_*` methods return only integrations with `setup_label`
201
+ - Generated config preserves ERB `env()` helpers literally (not evaluated)
202
+ - Sections are omitted when no items selected for that category
203
+ - Settings section is always present (commented out)
204
+
205
+ **`test/setup_config_test.rb`** — validates all integration `setup_config` implementations:
206
+ - Every integration with `setup_label` also has `setup_config`
207
+ - Each `setup_config` returns a non-empty string
208
+ - Each `setup_config` is valid YAML after substituting dummy values for ERB `env()` calls
209
+ - Required config keys from `required_config` appear in the setup_config (either uncommented or as comments)
210
+
211
+ ### Step 7: Documentation updates
212
+
213
+ - **`CLAUDE.md`** — add `Setup` to key classes, add `setup_config`/`setup_label` to Poller/Notifier/RepositorySource class docs, update CLI commands section, update directory structure
214
+ - **`README.md`** — update quickstart to lead with `superkick setup`
215
+ - **`docs/tutorials/getting-started.md`** — replace manual config creation steps with `superkick setup` as step 1
216
+ - **Skills** (`superkick-new-monitor`, `superkick-new-spawner`, `superkick-new-notifier`) — mention `setup_config` and `setup_label` as optional methods
217
+ - **`lib/superkick/cli/completion.rb`** — add `setup` to top-level completions
218
+
219
+ ## File Changes Summary
220
+
221
+ **New files:**
222
+ - `lib/superkick/setup.rb`
223
+ - `lib/superkick/cli/setup.rb`
224
+ - `test/setup_test.rb`
225
+ - `test/setup_config_test.rb`
226
+
227
+ **Modified — base classes (add `setup_config` + `setup_label` defaults):**
228
+ - `lib/superkick/poller.rb`
229
+ - `lib/superkick/notifier.rb`
230
+ - `lib/superkick/repository_source.rb`
231
+
232
+ **Modified — integration `setup_config` + `setup_label` additions:**
233
+ - `lib/superkick/integrations/github/monitor.rb`
234
+ - `lib/superkick/integrations/circleci/monitor.rb`
235
+ - `lib/superkick/integrations/shortcut/monitor.rb`
236
+ - `lib/superkick/integrations/shell/monitor.rb`
237
+ - `lib/superkick/integrations/datadog/alert_monitor.rb`
238
+ - `lib/superkick/integrations/github/issue_spawner.rb`
239
+ - `lib/superkick/integrations/github/check_failed_spawner.rb`
240
+ - `lib/superkick/integrations/shortcut/spawner.rb`
241
+ - `lib/superkick/integrations/slack/spawner.rb`
242
+ - `lib/superkick/integrations/bugsnag/spawner.rb`
243
+ - `lib/superkick/integrations/datadog/spawner.rb`
244
+ - `lib/superkick/integrations/datadog/alert_spawner.rb`
245
+ - `lib/superkick/integrations/honeybadger/spawner.rb`
246
+ - `lib/superkick/notifiers/terminal_bell.rb`
247
+ - `lib/superkick/notifiers/command.rb`
248
+ - `lib/superkick/integrations/slack/notifier.rb`
249
+ - `lib/superkick/integrations/datadog/notifier.rb`
250
+ - `lib/superkick/integrations/honeybadger/notifier.rb`
251
+ - `lib/superkick/local/repository_source.rb`
252
+ - `lib/superkick/integrations/git/repository_source.rb`
253
+ - `lib/superkick/integrations/github/repository_source.rb`
254
+
255
+ **Modified — wiring:**
256
+ - `superkick.gemspec` — add `tty-prompt` dependency
257
+ - `lib/superkick/cli.rb` — register Setup subcommand
258
+ - `lib/superkick.rb` — require `setup`
259
+ - `lib/superkick/cli/completion.rb` — add `setup` to completions
260
+
261
+ **Documentation:**
262
+ - `CLAUDE.md`
263
+ - `README.md`
264
+ - `docs/tutorials/getting-started.md`
265
+ - `skills/superkick-new-monitor/SKILL.md`
266
+ - `skills/superkick-new-spawner/SKILL.md`
267
+ - `skills/superkick-new-notifier/SKILL.md`