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.
- checksums.yaml +7 -0
- data/CLA.md +91 -0
- data/CLAUDE.md +2226 -0
- data/CONTRIBUTING.md +104 -0
- data/LICENSE +108 -0
- data/LICENSE-COMMERCIAL.md +39 -0
- data/PLAN.md +161 -0
- data/README.md +1155 -0
- data/exe/superkick +6 -0
- data/lib/superkick/agent/runtime.rb +82 -0
- data/lib/superkick/agent/runtimes/local.rb +74 -0
- data/lib/superkick/agent/runtimes.rb +4 -0
- data/lib/superkick/agent.rb +209 -0
- data/lib/superkick/agent_store.rb +85 -0
- data/lib/superkick/attach/client.rb +245 -0
- data/lib/superkick/attach/protocol.rb +71 -0
- data/lib/superkick/attach/server.rb +371 -0
- data/lib/superkick/budget_checker.rb +120 -0
- data/lib/superkick/buffer/client.rb +91 -0
- data/lib/superkick/buffer/server.rb +127 -0
- data/lib/superkick/cli/agent.rb +524 -0
- data/lib/superkick/cli/completion.rb +591 -0
- data/lib/superkick/cli/goal.rb +71 -0
- data/lib/superkick/cli/mcp.rb +34 -0
- data/lib/superkick/cli/monitor.rb +47 -0
- data/lib/superkick/cli/notifier.rb +39 -0
- data/lib/superkick/cli/repository.rb +46 -0
- data/lib/superkick/cli/server.rb +106 -0
- data/lib/superkick/cli/setup.rb +166 -0
- data/lib/superkick/cli/spawner.rb +85 -0
- data/lib/superkick/cli/team.rb +407 -0
- data/lib/superkick/cli.rb +175 -0
- data/lib/superkick/client_registry.rb +30 -0
- data/lib/superkick/configuration.rb +178 -0
- data/lib/superkick/connection.rb +56 -0
- data/lib/superkick/control/client.rb +78 -0
- data/lib/superkick/control/reply.rb +43 -0
- data/lib/superkick/control/server.rb +1271 -0
- data/lib/superkick/cost_accumulator.rb +53 -0
- data/lib/superkick/cost_extractor.rb +65 -0
- data/lib/superkick/cost_poller.rb +70 -0
- data/lib/superkick/driver/profile_source.rb +134 -0
- data/lib/superkick/driver.rb +179 -0
- data/lib/superkick/drivers/claude_code.rb +110 -0
- data/lib/superkick/drivers/codex.rb +57 -0
- data/lib/superkick/drivers/copilot.rb +75 -0
- data/lib/superkick/drivers/gemini.rb +86 -0
- data/lib/superkick/drivers/goose.rb +74 -0
- data/lib/superkick/drivers.rb +16 -0
- data/lib/superkick/drop.rb +80 -0
- data/lib/superkick/drops.rb +76 -0
- data/lib/superkick/environment_executor.rb +90 -0
- data/lib/superkick/goal.rb +95 -0
- data/lib/superkick/goals/agent_exit.rb +41 -0
- data/lib/superkick/goals/agent_signal.rb +42 -0
- data/lib/superkick/goals/command.rb +103 -0
- data/lib/superkick/history_buffer.rb +38 -0
- data/lib/superkick/hosted/attach/bridge.rb +52 -0
- data/lib/superkick/hosted/attach/client.rb +208 -0
- data/lib/superkick/hosted/attach/relay.rb +313 -0
- data/lib/superkick/hosted/attach/relay_store.rb +48 -0
- data/lib/superkick/hosted/bridge.rb +263 -0
- data/lib/superkick/hosted/buffer/bridge.rb +42 -0
- data/lib/superkick/hosted/buffer/client.rb +63 -0
- data/lib/superkick/hosted/buffer/relay.rb +126 -0
- data/lib/superkick/hosted/buffer/relay_store.rb +42 -0
- data/lib/superkick/hosted/control/client.rb +84 -0
- data/lib/superkick/hosted/mcp_proxy.rb +144 -0
- data/lib/superkick/inject_handler.rb +24 -0
- data/lib/superkick/injection_guard.rb +26 -0
- data/lib/superkick/injection_queue.rb +177 -0
- data/lib/superkick/injector.rb +65 -0
- data/lib/superkick/input_buffer.rb +171 -0
- data/lib/superkick/integrations/bugsnag/README.md +98 -0
- data/lib/superkick/integrations/bugsnag/spawner.rb +307 -0
- data/lib/superkick/integrations/bugsnag/templates/error_opened.liquid +17 -0
- data/lib/superkick/integrations/bugsnag.rb +7 -0
- data/lib/superkick/integrations/circleci/README.md +75 -0
- data/lib/superkick/integrations/circleci/monitor.rb +185 -0
- data/lib/superkick/integrations/circleci/probe.rb +36 -0
- data/lib/superkick/integrations/circleci/templates/ci_failure.liquid +8 -0
- data/lib/superkick/integrations/circleci/templates/ci_success.liquid +1 -0
- data/lib/superkick/integrations/circleci.rb +8 -0
- data/lib/superkick/integrations/datadog/README.md +253 -0
- data/lib/superkick/integrations/datadog/alert_goal.rb +94 -0
- data/lib/superkick/integrations/datadog/alert_monitor.rb +163 -0
- data/lib/superkick/integrations/datadog/alert_spawner.rb +201 -0
- data/lib/superkick/integrations/datadog/notification_templates/default.liquid +10 -0
- data/lib/superkick/integrations/datadog/notifier.rb +294 -0
- data/lib/superkick/integrations/datadog/spawner.rb +201 -0
- data/lib/superkick/integrations/datadog/templates/alert_changed.liquid +8 -0
- data/lib/superkick/integrations/datadog/templates/alert_escalated.liquid +8 -0
- data/lib/superkick/integrations/datadog/templates/alert_recovered.liquid +14 -0
- data/lib/superkick/integrations/datadog/templates/alert_triggered.liquid +29 -0
- data/lib/superkick/integrations/datadog/templates/error_opened.liquid +15 -0
- data/lib/superkick/integrations/datadog.rb +14 -0
- data/lib/superkick/integrations/docker/README.md +256 -0
- data/lib/superkick/integrations/docker/client.rb +295 -0
- data/lib/superkick/integrations/docker/runtime.rb +218 -0
- data/lib/superkick/integrations/docker.rb +4 -0
- data/lib/superkick/integrations/git/repository_source.rb +66 -0
- data/lib/superkick/integrations/git/version_control.rb +119 -0
- data/lib/superkick/integrations/git.rb +8 -0
- data/lib/superkick/integrations/github/README.md +300 -0
- data/lib/superkick/integrations/github/check_failed_spawner.rb +199 -0
- data/lib/superkick/integrations/github/drops.rb +114 -0
- data/lib/superkick/integrations/github/goal.rb +135 -0
- data/lib/superkick/integrations/github/issue_goal.rb +104 -0
- data/lib/superkick/integrations/github/issue_spawner.rb +160 -0
- data/lib/superkick/integrations/github/monitor.rb +251 -0
- data/lib/superkick/integrations/github/probe.rb +30 -0
- data/lib/superkick/integrations/github/repository_source.rb +228 -0
- data/lib/superkick/integrations/github/templates/check_failed.liquid +10 -0
- data/lib/superkick/integrations/github/templates/ci_failure.liquid +5 -0
- data/lib/superkick/integrations/github/templates/ci_success.liquid +1 -0
- data/lib/superkick/integrations/github/templates/issue_opened.liquid +20 -0
- data/lib/superkick/integrations/github/templates/pr_comment.liquid +2 -0
- data/lib/superkick/integrations/github/templates/pr_review.liquid +4 -0
- data/lib/superkick/integrations/github.rb +16 -0
- data/lib/superkick/integrations/honeybadger/README.md +97 -0
- data/lib/superkick/integrations/honeybadger/notification_templates/default.liquid +8 -0
- data/lib/superkick/integrations/honeybadger/notifier.rb +250 -0
- data/lib/superkick/integrations/honeybadger/spawner.rb +214 -0
- data/lib/superkick/integrations/honeybadger/templates/error_opened.liquid +17 -0
- data/lib/superkick/integrations/honeybadger.rb +9 -0
- data/lib/superkick/integrations/shell/README.md +83 -0
- data/lib/superkick/integrations/shell/monitor.rb +87 -0
- data/lib/superkick/integrations/shell/templates/shell_alert.liquid +6 -0
- data/lib/superkick/integrations/shell/templates/shell_success.liquid +6 -0
- data/lib/superkick/integrations/shell.rb +7 -0
- data/lib/superkick/integrations/shortcut/README.md +193 -0
- data/lib/superkick/integrations/shortcut/drops.rb +91 -0
- data/lib/superkick/integrations/shortcut/monitor.rb +582 -0
- data/lib/superkick/integrations/shortcut/probe.rb +34 -0
- data/lib/superkick/integrations/shortcut/spawner.rb +264 -0
- data/lib/superkick/integrations/shortcut/templates/related_story_changed.liquid +6 -0
- data/lib/superkick/integrations/shortcut/templates/story_blocker.liquid +8 -0
- data/lib/superkick/integrations/shortcut/templates/story_comment.liquid +5 -0
- data/lib/superkick/integrations/shortcut/templates/story_description_changed.liquid +19 -0
- data/lib/superkick/integrations/shortcut/templates/story_owner_changed.liquid +10 -0
- data/lib/superkick/integrations/shortcut/templates/story_ready.liquid +41 -0
- data/lib/superkick/integrations/shortcut/templates/story_state_changed.liquid +9 -0
- data/lib/superkick/integrations/shortcut/templates/story_unblocked.liquid +5 -0
- data/lib/superkick/integrations/shortcut.rb +11 -0
- data/lib/superkick/integrations/slack/README.md +297 -0
- data/lib/superkick/integrations/slack/drops.rb +70 -0
- data/lib/superkick/integrations/slack/notifier.rb +426 -0
- data/lib/superkick/integrations/slack/spawner.rb +251 -0
- data/lib/superkick/integrations/slack/templates/default.liquid +17 -0
- data/lib/superkick/integrations/slack/templates/slack_reply.liquid +3 -0
- data/lib/superkick/integrations/slack/templates/spawn/slack_message.liquid +10 -0
- data/lib/superkick/integrations/slack/thread_monitor.rb +161 -0
- data/lib/superkick/integrations/slack.rb +12 -0
- data/lib/superkick/liquid.rb +129 -0
- data/lib/superkick/local/repository_source.rb +148 -0
- data/lib/superkick/mcp_server.rb +596 -0
- data/lib/superkick/monitor.rb +215 -0
- data/lib/superkick/notification_dispatcher.rb +280 -0
- data/lib/superkick/notifier.rb +173 -0
- data/lib/superkick/notifier_state_store.rb +55 -0
- data/lib/superkick/notifier_template.rb +121 -0
- data/lib/superkick/notifiers/command.rb +124 -0
- data/lib/superkick/notifiers/terminal_bell.rb +41 -0
- data/lib/superkick/output_logger.rb +54 -0
- data/lib/superkick/poller.rb +126 -0
- data/lib/superkick/process_runner.rb +87 -0
- data/lib/superkick/pty_proxy.rb +403 -0
- data/lib/superkick/registry.rb +75 -0
- data/lib/superkick/repository_source.rb +195 -0
- data/lib/superkick/server.rb +211 -0
- data/lib/superkick/session_recorder.rb +154 -0
- data/lib/superkick/setup.rb +160 -0
- data/lib/superkick/spawn/agent_spawner.rb +311 -0
- data/lib/superkick/spawn/approval_store.rb +113 -0
- data/lib/superkick/spawn/handler.rb +144 -0
- data/lib/superkick/spawn/injector.rb +119 -0
- data/lib/superkick/spawn/workflow_executor.rb +196 -0
- data/lib/superkick/spawn/workflow_validator.rb +77 -0
- data/lib/superkick/spawner.rb +67 -0
- data/lib/superkick/supervisor.rb +516 -0
- data/lib/superkick/team/artifact_store.rb +92 -0
- data/lib/superkick/team/log.rb +140 -0
- data/lib/superkick/team/log_entry_drop.rb +34 -0
- data/lib/superkick/team/log_monitor.rb +84 -0
- data/lib/superkick/team/log_notifier.rb +96 -0
- data/lib/superkick/team/log_store.rb +40 -0
- data/lib/superkick/template_filters.rb +24 -0
- data/lib/superkick/template_renderer.rb +223 -0
- data/lib/superkick/templates/team_log/planning_agent.liquid +38 -0
- data/lib/superkick/templates/team_log/team_digest.liquid +45 -0
- data/lib/superkick/templates/team_log/teammate_message.liquid +7 -0
- data/lib/superkick/templates/team_log/worker_kickoff.liquid +37 -0
- data/lib/superkick/templates/workflow/workflow_triggered.liquid +22 -0
- data/lib/superkick/version.rb +5 -0
- data/lib/superkick/version_control.rb +135 -0
- data/lib/superkick/yaml_config.rb +302 -0
- data/lib/superkick.rb +198 -0
- data/plan.md +267 -0
- metadata +404 -0
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Contributing to Superkick
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Superkick.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
Clone the repo and install dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/your-org/superkick.git
|
|
11
|
+
cd superkick
|
|
12
|
+
bundle install
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If you are working in the Claude Code sandbox, see the bootstrap steps in
|
|
16
|
+
[CLAUDE.md](CLAUDE.md#claude-code-sandbox-bootstrap) first.
|
|
17
|
+
|
|
18
|
+
## Running tests
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Full test suite + lint (the default)
|
|
22
|
+
bundle exec rake
|
|
23
|
+
|
|
24
|
+
# Tests only
|
|
25
|
+
bundle exec rake test
|
|
26
|
+
|
|
27
|
+
# Single test file
|
|
28
|
+
bundle exec rake test TEST=test/injector_test.rb
|
|
29
|
+
|
|
30
|
+
# Specific test by name
|
|
31
|
+
bundle exec rake test TEST=test/injector_test.rb TESTOPTS="-n test_returns_skipped_when_gate_refuses"
|
|
32
|
+
|
|
33
|
+
# Lint only
|
|
34
|
+
bundle exec rake standard
|
|
35
|
+
|
|
36
|
+
# Auto-fix lint violations
|
|
37
|
+
bundle exec rake standard:fix
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
All tests must pass and the linter must report no violations before a pull
|
|
41
|
+
request can be merged.
|
|
42
|
+
|
|
43
|
+
## Making changes
|
|
44
|
+
|
|
45
|
+
- Keep pull requests focused on a single concern.
|
|
46
|
+
- Follow the existing code style (StandardRB, zero config).
|
|
47
|
+
- Add or update tests for any behaviour you change.
|
|
48
|
+
- All lib files use `# frozen_string_literal: true` — keep it that way.
|
|
49
|
+
|
|
50
|
+
### Adding a new driver
|
|
51
|
+
|
|
52
|
+
See [skills/superkick-new-driver/SKILL.md](skills/superkick-new-driver/SKILL.md) for
|
|
53
|
+
the step-by-step guide.
|
|
54
|
+
|
|
55
|
+
### Adding a new monitor
|
|
56
|
+
|
|
57
|
+
See [skills/superkick-new-monitor/SKILL.md](skills/superkick-new-monitor/SKILL.md)
|
|
58
|
+
for the step-by-step guide.
|
|
59
|
+
|
|
60
|
+
### Adding a new spawner
|
|
61
|
+
|
|
62
|
+
See [skills/superkick-new-spawner/SKILL.md](skills/superkick-new-spawner/SKILL.md)
|
|
63
|
+
for the step-by-step guide. Spawners support workflow hooks (`on_complete:` /
|
|
64
|
+
`on_fail:`) for multi-stage pipelines — the skill covers designing spawners
|
|
65
|
+
that work well in chains.
|
|
66
|
+
|
|
67
|
+
### Adding a new goal
|
|
68
|
+
|
|
69
|
+
See [skills/superkick-new-goal/SKILL.md](skills/superkick-new-goal/SKILL.md) for the
|
|
70
|
+
step-by-step guide.
|
|
71
|
+
|
|
72
|
+
### Adding a new version control adapter
|
|
73
|
+
|
|
74
|
+
See [skills/superkick-new-version-control/SKILL.md](skills/superkick-new-version-control/SKILL.md)
|
|
75
|
+
for the step-by-step guide.
|
|
76
|
+
|
|
77
|
+
### Adding a new repository source
|
|
78
|
+
|
|
79
|
+
See [skills/superkick-new-repository-source/SKILL.md](skills/superkick-new-repository-source/SKILL.md)
|
|
80
|
+
for the step-by-step guide.
|
|
81
|
+
|
|
82
|
+
### Adding a new notifier
|
|
83
|
+
|
|
84
|
+
See [skills/superkick-new-notifier/SKILL.md](skills/superkick-new-notifier/SKILL.md)
|
|
85
|
+
for the step-by-step guide.
|
|
86
|
+
|
|
87
|
+
### Adding a new agent runtime
|
|
88
|
+
|
|
89
|
+
See [skills/superkick-new-runtime/SKILL.md](skills/superkick-new-runtime/SKILL.md)
|
|
90
|
+
for the step-by-step guide.
|
|
91
|
+
|
|
92
|
+
## Submitting a pull request
|
|
93
|
+
|
|
94
|
+
1. Fork the repository and create a branch from `main`.
|
|
95
|
+
2. Make your changes, ensuring tests pass and the linter is clean.
|
|
96
|
+
3. Open a pull request with a clear description of what changes you made and
|
|
97
|
+
why.
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
By submitting a contribution, you agree to the terms of the
|
|
102
|
+
[Contributor License Agreement](CLA.md). In short: you retain ownership of your
|
|
103
|
+
work, and you grant the Maintainer the right to distribute it under both the
|
|
104
|
+
[Business Source License 1.1](LICENSE) and a [commercial license](LICENSE-COMMERCIAL.md).
|
data/LICENSE
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
|
4
|
+
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
|
5
|
+
|
|
6
|
+
-----------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
Parameters
|
|
9
|
+
|
|
10
|
+
Licensor: Superkick Systems, Inc.
|
|
11
|
+
|
|
12
|
+
Licensed Work: Superkick
|
|
13
|
+
The Licensed Work is (c) 2026 Superkick Systems, Inc.
|
|
14
|
+
|
|
15
|
+
Additional Use Grant: You may make production use of the Licensed Work,
|
|
16
|
+
provided your use does not include offering the Licensed
|
|
17
|
+
Work to third parties on a hosted, managed, or embedded
|
|
18
|
+
basis in a manner that competes with the Licensor's paid
|
|
19
|
+
or commercial versions of the Licensed Work. For purposes
|
|
20
|
+
of this license, "compete" means offering a product or
|
|
21
|
+
service whose primary value derives substantially from
|
|
22
|
+
the functionality of the Licensed Work.
|
|
23
|
+
|
|
24
|
+
Change Date: Four years from the date the Licensed Work is published.
|
|
25
|
+
|
|
26
|
+
Change License: Apache License, Version 2.0
|
|
27
|
+
|
|
28
|
+
-----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
Terms
|
|
31
|
+
|
|
32
|
+
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
33
|
+
works, redistribute, and make non-production use of the Licensed Work. The
|
|
34
|
+
Licensor may make an Additional Use Grant, above, permitting limited
|
|
35
|
+
production use.
|
|
36
|
+
|
|
37
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
38
|
+
available distribution of a specific version of the Licensed Work under this
|
|
39
|
+
License, whichever comes first, the Licensor hereby grants you rights under
|
|
40
|
+
the terms of the Change License, and the rights granted in the paragraph
|
|
41
|
+
above terminate.
|
|
42
|
+
|
|
43
|
+
If your use of the Licensed Work does not comply with the requirements
|
|
44
|
+
currently in effect as described in this License, you must purchase a
|
|
45
|
+
commercial license from the Licensor, its affiliated entities, or authorized
|
|
46
|
+
resellers, or you must refrain from using the Licensed Work.
|
|
47
|
+
|
|
48
|
+
All copies of the original and modified Licensed Work, and derivative works
|
|
49
|
+
of the Licensed Work, are subject to this License. This License applies
|
|
50
|
+
separately for each version of the Licensed Work and the Change Date may vary
|
|
51
|
+
for each version of the Licensed Work released by Licensor.
|
|
52
|
+
|
|
53
|
+
You must conspicuously display this License on each original or modified copy
|
|
54
|
+
of the Licensed Work. If you receive the Licensed Work in original or
|
|
55
|
+
modified form from a third party, the terms and conditions set forth in this
|
|
56
|
+
License apply to your use of that work.
|
|
57
|
+
|
|
58
|
+
Any use of the Licensed Work in violation of this License will automatically
|
|
59
|
+
terminate your rights under this License for the current and all other
|
|
60
|
+
versions of the Licensed Work.
|
|
61
|
+
|
|
62
|
+
This License does not grant you any right in any trademark or logo of
|
|
63
|
+
Licensor or its affiliates (provided that you may use a trademark or logo of
|
|
64
|
+
Licensor as expressly required by this License).
|
|
65
|
+
|
|
66
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
|
67
|
+
AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
|
68
|
+
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
|
69
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
|
70
|
+
TITLE.
|
|
71
|
+
|
|
72
|
+
MariaDB hereby grants you permission to use this License's text to license
|
|
73
|
+
your works, and to refer to it using the trademark "Business Source License",
|
|
74
|
+
as long as you comply with the Covenants of Licensor below.
|
|
75
|
+
|
|
76
|
+
-----------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
Covenants of Licensor
|
|
79
|
+
|
|
80
|
+
In consideration of the right to use this License's text and the "Business
|
|
81
|
+
Source License" name and trademark, Licensor covenants to MariaDB, and to all
|
|
82
|
+
other recipients of the licensed work to be provided by Licensor:
|
|
83
|
+
|
|
84
|
+
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
|
85
|
+
or a license that is compatible with GPL Version 2.0 or a later version,
|
|
86
|
+
where "compatible" means that software provided under the Change License can
|
|
87
|
+
be included in a program with software provided under GPL Version 2.0 or a
|
|
88
|
+
later version. Licensor may specify additional Change Licenses without
|
|
89
|
+
limitation.
|
|
90
|
+
|
|
91
|
+
2. To either: (a) specify an additional grant of rights to use that does not
|
|
92
|
+
impose any additional restriction on the right granted in this License, as
|
|
93
|
+
the Additional Use Grant; or (b) insert the text "None".
|
|
94
|
+
|
|
95
|
+
3. To specify a Change Date.
|
|
96
|
+
|
|
97
|
+
4. Not to modify this License in any other way.
|
|
98
|
+
|
|
99
|
+
-----------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
Notice
|
|
102
|
+
|
|
103
|
+
The Business Source License (this document, or the "License") is not an Open
|
|
104
|
+
Source license. However, the Licensed Work will eventually be made available
|
|
105
|
+
under an Open Source License, as stated in this License.
|
|
106
|
+
|
|
107
|
+
For more information on the use of the Business Source License, please visit:
|
|
108
|
+
https://mariadb.com/bsl11/
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Superkick Commercial License
|
|
2
|
+
|
|
3
|
+
The Superkick source code is made available under the Business Source License 1.1
|
|
4
|
+
(see [LICENSE](LICENSE)). The BSL permits non-production use and production use
|
|
5
|
+
that does not compete with the Licensor's offerings.
|
|
6
|
+
|
|
7
|
+
## When you need a commercial license
|
|
8
|
+
|
|
9
|
+
You need a separate commercial license if your use of Superkick falls outside the
|
|
10
|
+
BSL's Additional Use Grant — for example, if you are offering Superkick (or a
|
|
11
|
+
product built substantially on Superkick) to third parties as a hosted, managed, or
|
|
12
|
+
SaaS product.
|
|
13
|
+
|
|
14
|
+
## What the commercial license provides
|
|
15
|
+
|
|
16
|
+
A commercial license grants you:
|
|
17
|
+
|
|
18
|
+
- **Production use** without the BSL's non-compete restriction
|
|
19
|
+
- **Redistribution rights** for embedding Superkick in your own product
|
|
20
|
+
- **Priority support** and direct access to the maintainer
|
|
21
|
+
- **Custom terms** tailored to your use case
|
|
22
|
+
|
|
23
|
+
## Pricing
|
|
24
|
+
|
|
25
|
+
Commercial licenses are priced on a case-by-case basis depending on the nature
|
|
26
|
+
and scale of your use. Founder-friendly terms are available for startups and
|
|
27
|
+
small teams.
|
|
28
|
+
|
|
29
|
+
## Contact
|
|
30
|
+
|
|
31
|
+
To discuss commercial licensing, please reach out:
|
|
32
|
+
|
|
33
|
+
- **Email:** licensing@superkick.ai
|
|
34
|
+
- **GitHub:** Open a [licensing inquiry](https://github.com/admtnnr/superkick/issues/new?title=Commercial+License+Inquiry)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
*This document is informational and does not constitute a license. The binding
|
|
39
|
+
license terms are in [LICENSE](LICENSE).*
|
data/PLAN.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Docker Runtime Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Add `Agent::Runtime::Docker` — a Docker container runtime that provisions spawned agents in Docker containers via the Docker Engine API. Uses Faraday for HTTP (Unix socket and TCP+TLS), following established codebase patterns.
|
|
6
|
+
|
|
7
|
+
## Existing plumbing
|
|
8
|
+
|
|
9
|
+
`Configuration#build_agent_runtime` (line 107) already has a `when :docker` branch that passes the `docker:` config hash to the constructor. We just need to build the class it instantiates.
|
|
10
|
+
|
|
11
|
+
## Implementation steps
|
|
12
|
+
|
|
13
|
+
### Step 1: Docker Engine API client (`lib/superkick/docker/client.rb`)
|
|
14
|
+
|
|
15
|
+
A thin Faraday-based wrapper around the Docker Engine API endpoints we need. Accepts `connection:` for test injection.
|
|
16
|
+
|
|
17
|
+
**Constructor:** `initialize(host:, tls: nil, connection: nil)`
|
|
18
|
+
- `host` — `unix:///var/run/docker.sock` or `tcp://host:port`
|
|
19
|
+
- `tls` — optional Hash `{ ca:, cert:, key: }` for TCP+TLS
|
|
20
|
+
- `connection` — injected Faraday connection (tests)
|
|
21
|
+
|
|
22
|
+
**Methods:**
|
|
23
|
+
- `create_container(name:, config:)` → Hash (container ID, warnings)
|
|
24
|
+
- `start_container(id:)` → nil
|
|
25
|
+
- `stop_container(id:, timeout: 30)` → nil
|
|
26
|
+
- `remove_container(id:, force: false)` → nil
|
|
27
|
+
- `inspect_container(id:)` → Hash (full container state)
|
|
28
|
+
- `pull_image(image:, auth: nil)` → nil (blocks until complete)
|
|
29
|
+
- `image_exists?(image:)` → Boolean
|
|
30
|
+
- `ping` → Boolean (health check)
|
|
31
|
+
|
|
32
|
+
**Faraday Unix socket:** Faraday supports Unix sockets via the URL scheme `http+unix:///path/to/socket`. The base URL becomes `http+unix:///var/run/docker.sock/` and paths are appended normally (`/v1.47/containers/create`).
|
|
33
|
+
|
|
34
|
+
**API version:** Pin to `v1.47` (Docker 27.x). All endpoints are prefixed with this version.
|
|
35
|
+
|
|
36
|
+
**Error handling:** Define `Docker::Client::Error` (base), `Docker::Client::NotFound` (404), `Docker::Client::Conflict` (409). Map HTTP status codes to these.
|
|
37
|
+
|
|
38
|
+
### Step 2: Docker runtime (`lib/superkick/agent/runtimes/docker.rb`)
|
|
39
|
+
|
|
40
|
+
**Constructor:** `initialize(image:, host: nil, tls: nil, registry: nil, pull_policy: :missing, memory: nil, cpu: nil, network: nil, stop_timeout: 30, auto_remove: true, env: nil, volumes: nil, labels: nil, connection: nil)`
|
|
41
|
+
|
|
42
|
+
All config keys from the YAML `docker:` section map directly to constructor kwargs. The `connection:` param is for test injection into the underlying `Docker::Client`.
|
|
43
|
+
|
|
44
|
+
**Handle:** `Data.define(:container_id, :container_name)`
|
|
45
|
+
|
|
46
|
+
**`provision(agent_id:, config:)`:**
|
|
47
|
+
1. Pull image (respecting `pull_policy`)
|
|
48
|
+
2. Build container config hash:
|
|
49
|
+
- `Image` — from constructor
|
|
50
|
+
- `Cmd` — from `config[:command]`
|
|
51
|
+
- `Env` — merge runtime-level `env` with `config[:env]` (config wins)
|
|
52
|
+
- `WorkingDir` — from `config[:working_dir]`
|
|
53
|
+
- `HostConfig.Memory` — parse memory string (e.g. `"4G"` → bytes)
|
|
54
|
+
- `HostConfig.NanoCpus` — parse cpu (e.g. `2` → 2_000_000_000)
|
|
55
|
+
- `HostConfig.Binds` — from `volumes`
|
|
56
|
+
- `HostConfig.NetworkMode` — from `network`
|
|
57
|
+
- `Labels` — merge runtime labels with `{ "superkick.agent_id" => agent_id }`
|
|
58
|
+
- `StopTimeout` — from `stop_timeout`
|
|
59
|
+
3. Create container with name `superkick-#{agent_id}`
|
|
60
|
+
4. Start container
|
|
61
|
+
5. Return `Handle.new(container_id:, container_name:)`
|
|
62
|
+
|
|
63
|
+
**`terminate(handle:)`:**
|
|
64
|
+
1. Stop container (with `stop_timeout`)
|
|
65
|
+
2. Remove container if `auto_remove` is true
|
|
66
|
+
3. Rescue `Docker::Client::NotFound` silently (already gone)
|
|
67
|
+
|
|
68
|
+
**`alive?(handle:)`:**
|
|
69
|
+
1. Inspect container
|
|
70
|
+
2. Return `state["Running"]`
|
|
71
|
+
3. Rescue `Docker::Client::NotFound` → false
|
|
72
|
+
|
|
73
|
+
**`metadata(handle:)`:**
|
|
74
|
+
```ruby
|
|
75
|
+
{ container_id: handle.container_id, container_name: handle.container_name }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Step 3: Memory size parser (private helper)
|
|
79
|
+
|
|
80
|
+
Parse Docker memory strings: `"4G"` → `4_294_967_296`, `"512M"` → `536_870_912`, `"1024K"` → `1_048_576`. If already an Integer, pass through. Lives as a private method on the Docker runtime class.
|
|
81
|
+
|
|
82
|
+
### Step 4: Update `Configuration#build_agent_runtime`
|
|
83
|
+
|
|
84
|
+
The existing `when :docker` branch needs updating. Current code:
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
when :docker
|
|
88
|
+
docker_config = @runtime[:docker] || {}
|
|
89
|
+
klass.new(**docker_config.except(:socket).merge(
|
|
90
|
+
socket: docker_config[:socket] || "/var/run/docker.sock"
|
|
91
|
+
))
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Update to pass `host:` instead of `socket:` (since the config key is `host:`), and pass the full docker config hash through:
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
when :docker
|
|
98
|
+
docker_config = @runtime[:docker] || {}
|
|
99
|
+
klass.new(**docker_config)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The Docker runtime constructor handles all defaults internally.
|
|
103
|
+
|
|
104
|
+
### Step 5: Register and require
|
|
105
|
+
|
|
106
|
+
1. Self-register at bottom of `docker.rb`: `Superkick::Agent::Runtime.register(Superkick::Agent::Runtime::Docker)`
|
|
107
|
+
2. Add `require_relative "runtimes/docker"` to `lib/superkick/agent/runtimes.rb`
|
|
108
|
+
|
|
109
|
+
### Step 6: Tests
|
|
110
|
+
|
|
111
|
+
**`test/docker/client_test.rb`** — test the Faraday-based Docker client:
|
|
112
|
+
- `ping` — success and failure
|
|
113
|
+
- `create_container` — sends correct JSON, returns container ID
|
|
114
|
+
- `start_container` / `stop_container` / `remove_container` — correct HTTP methods and paths
|
|
115
|
+
- `inspect_container` — parses response
|
|
116
|
+
- `pull_image` — correct endpoint, sends auth header when registry config provided
|
|
117
|
+
- `image_exists?` — true on 200, false on 404
|
|
118
|
+
- Error mapping (404 → NotFound, 409 → Conflict, 500 → Error)
|
|
119
|
+
|
|
120
|
+
All tests use `Faraday::Adapter::Test::Stubs` with `connection:` injection.
|
|
121
|
+
|
|
122
|
+
**`test/agent/runtimes/docker_test.rb`** — test the runtime:
|
|
123
|
+
- `type` returns `:docker`
|
|
124
|
+
- `provision` — pulls image (when policy requires it), creates container with correct config, starts it, returns Handle
|
|
125
|
+
- `provision` — merges env correctly (config env overrides runtime env)
|
|
126
|
+
- `provision` — parses memory/cpu into Docker API format
|
|
127
|
+
- `provision` — skips pull when `pull_policy: :never`
|
|
128
|
+
- `terminate` — stops and removes container
|
|
129
|
+
- `terminate` — handles already-removed container
|
|
130
|
+
- `alive?` — returns true/false based on container state
|
|
131
|
+
- `alive?` — returns false when container not found
|
|
132
|
+
- `metadata` — returns container_id and container_name
|
|
133
|
+
- Memory parser — various units and passthrough
|
|
134
|
+
|
|
135
|
+
Tests stub the `Docker::Client` methods rather than HTTP, keeping them focused on runtime logic.
|
|
136
|
+
|
|
137
|
+
### Step 7: Documentation
|
|
138
|
+
|
|
139
|
+
1. **CLAUDE.md** — update directory structure (add `docker/` dir), add Docker runtime to Key Classes section, update `build_agent_runtime` description, update runtime config example
|
|
140
|
+
2. **README.md** — add Docker runtime section under configuration/deployment
|
|
141
|
+
3. **`docs/tutorials/first-spawner-pipeline.md`** — mention Docker runtime as an option
|
|
142
|
+
4. **`docs/explanation/spawner-workflows.md`** — note runtime choice affects agent isolation
|
|
143
|
+
|
|
144
|
+
## File list
|
|
145
|
+
|
|
146
|
+
New files:
|
|
147
|
+
- `lib/superkick/docker/client.rb`
|
|
148
|
+
- `test/docker/client_test.rb`
|
|
149
|
+
- `lib/superkick/agent/runtimes/docker.rb`
|
|
150
|
+
- `test/agent/runtimes/docker_test.rb`
|
|
151
|
+
|
|
152
|
+
Modified files:
|
|
153
|
+
- `lib/superkick/agent/runtimes.rb` (add require)
|
|
154
|
+
- `lib/superkick/configuration.rb` (update `build_agent_runtime`)
|
|
155
|
+
- `lib/superkick.rb` (add require for `docker/client`)
|
|
156
|
+
- `CLAUDE.md` (docs)
|
|
157
|
+
- `README.md` (docs)
|
|
158
|
+
|
|
159
|
+
## Open questions
|
|
160
|
+
|
|
161
|
+
None — config surface is agreed, patterns are clear from existing code.
|