rubyn-code 0.1.0 → 0.2.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 +4 -4
- data/README.md +269 -467
- data/db/migrations/009_create_teams.sql +6 -6
- data/db/migrations/011_fix_mailbox_messages_columns.rb +35 -0
- data/db/migrations/012_expand_mailbox_message_types.rb +37 -0
- data/exe/rubyn-code +1 -1
- data/lib/rubyn_code/agent/RUBYN.md +17 -0
- data/lib/rubyn_code/agent/conversation.rb +68 -19
- data/lib/rubyn_code/agent/loop.rb +312 -54
- data/lib/rubyn_code/agent/loop_detector.rb +6 -6
- data/lib/rubyn_code/auth/RUBYN.md +19 -0
- data/lib/rubyn_code/auth/oauth.rb +40 -35
- data/lib/rubyn_code/auth/server.rb +16 -12
- data/lib/rubyn_code/auth/token_store.rb +22 -22
- data/lib/rubyn_code/autonomous/RUBYN.md +14 -0
- data/lib/rubyn_code/autonomous/daemon.rb +115 -79
- data/lib/rubyn_code/autonomous/idle_poller.rb +4 -8
- data/lib/rubyn_code/autonomous/task_claimer.rb +11 -11
- data/lib/rubyn_code/background/RUBYN.md +13 -0
- data/lib/rubyn_code/background/notifier.rb +0 -2
- data/lib/rubyn_code/background/worker.rb +60 -15
- data/lib/rubyn_code/cli/RUBYN.md +30 -0
- data/lib/rubyn_code/cli/app.rb +85 -9
- data/lib/rubyn_code/cli/commands/RUBYN.md +133 -0
- data/lib/rubyn_code/cli/commands/base.rb +53 -0
- data/lib/rubyn_code/cli/commands/budget.rb +24 -0
- data/lib/rubyn_code/cli/commands/clear.rb +16 -0
- data/lib/rubyn_code/cli/commands/compact.rb +21 -0
- data/lib/rubyn_code/cli/commands/context.rb +44 -0
- data/lib/rubyn_code/cli/commands/context_info.rb +56 -0
- data/lib/rubyn_code/cli/commands/cost.rb +23 -0
- data/lib/rubyn_code/cli/commands/diff.rb +30 -0
- data/lib/rubyn_code/cli/commands/doctor.rb +112 -0
- data/lib/rubyn_code/cli/commands/help.rb +41 -0
- data/lib/rubyn_code/cli/commands/model.rb +37 -0
- data/lib/rubyn_code/cli/commands/plan.rb +22 -0
- data/lib/rubyn_code/cli/commands/quit.rb +17 -0
- data/lib/rubyn_code/cli/commands/registry.rb +64 -0
- data/lib/rubyn_code/cli/commands/resume.rb +51 -0
- data/lib/rubyn_code/cli/commands/review.rb +26 -0
- data/lib/rubyn_code/cli/commands/skill.rb +32 -0
- data/lib/rubyn_code/cli/commands/spawn.rb +24 -0
- data/lib/rubyn_code/cli/commands/tasks.rb +32 -0
- data/lib/rubyn_code/cli/commands/tokens.rb +76 -0
- data/lib/rubyn_code/cli/commands/undo.rb +17 -0
- data/lib/rubyn_code/cli/commands/version.rb +16 -0
- data/lib/rubyn_code/cli/daemon_runner.rb +129 -0
- data/lib/rubyn_code/cli/input_handler.rb +20 -23
- data/lib/rubyn_code/cli/renderer.rb +25 -27
- data/lib/rubyn_code/cli/repl.rb +161 -194
- data/lib/rubyn_code/cli/setup.rb +117 -0
- data/lib/rubyn_code/cli/spinner.rb +40 -40
- data/lib/rubyn_code/cli/stream_formatter.rb +29 -28
- data/lib/rubyn_code/cli/version_check.rb +94 -0
- data/lib/rubyn_code/config/RUBYN.md +14 -0
- data/lib/rubyn_code/config/defaults.rb +28 -19
- data/lib/rubyn_code/config/project_config.rb +7 -9
- data/lib/rubyn_code/config/settings.rb +3 -3
- data/lib/rubyn_code/context/RUBYN.md +20 -0
- data/lib/rubyn_code/context/auto_compact.rb +7 -7
- data/lib/rubyn_code/context/compactor.rb +2 -2
- data/lib/rubyn_code/context/context_collapse.rb +45 -0
- data/lib/rubyn_code/context/manager.rb +20 -3
- data/lib/rubyn_code/context/manual_compact.rb +7 -7
- data/lib/rubyn_code/context/micro_compact.rb +12 -12
- data/lib/rubyn_code/db/RUBYN.md +40 -0
- data/lib/rubyn_code/db/connection.rb +13 -13
- data/lib/rubyn_code/db/migrator.rb +67 -27
- data/lib/rubyn_code/db/schema.rb +6 -6
- data/lib/rubyn_code/debug.rb +74 -0
- data/lib/rubyn_code/hooks/RUBYN.md +17 -0
- data/lib/rubyn_code/hooks/built_in.rb +9 -9
- data/lib/rubyn_code/hooks/registry.rb +5 -5
- data/lib/rubyn_code/hooks/runner.rb +1 -1
- data/lib/rubyn_code/hooks/user_hooks.rb +16 -16
- data/lib/rubyn_code/learning/RUBYN.md +16 -0
- data/lib/rubyn_code/learning/extractor.rb +22 -22
- data/lib/rubyn_code/learning/injector.rb +17 -18
- data/lib/rubyn_code/learning/instinct.rb +18 -14
- data/lib/rubyn_code/llm/RUBYN.md +15 -0
- data/lib/rubyn_code/llm/client.rb +121 -55
- data/lib/rubyn_code/llm/message_builder.rb +19 -15
- data/lib/rubyn_code/llm/streaming.rb +80 -50
- data/lib/rubyn_code/mcp/RUBYN.md +21 -0
- data/lib/rubyn_code/mcp/client.rb +25 -24
- data/lib/rubyn_code/mcp/config.rb +7 -7
- data/lib/rubyn_code/mcp/sse_transport.rb +27 -26
- data/lib/rubyn_code/mcp/stdio_transport.rb +22 -19
- data/lib/rubyn_code/mcp/tool_bridge.rb +32 -32
- data/lib/rubyn_code/memory/RUBYN.md +17 -0
- data/lib/rubyn_code/memory/models.rb +3 -3
- data/lib/rubyn_code/memory/search.rb +17 -17
- data/lib/rubyn_code/memory/session_persistence.rb +49 -34
- data/lib/rubyn_code/memory/store.rb +17 -17
- data/lib/rubyn_code/observability/RUBYN.md +19 -0
- data/lib/rubyn_code/observability/budget_enforcer.rb +16 -15
- data/lib/rubyn_code/observability/cost_calculator.rb +3 -3
- data/lib/rubyn_code/observability/token_counter.rb +1 -1
- data/lib/rubyn_code/observability/usage_reporter.rb +35 -35
- data/lib/rubyn_code/output/RUBYN.md +11 -0
- data/lib/rubyn_code/output/diff_renderer.rb +6 -6
- data/lib/rubyn_code/output/formatter.rb +4 -4
- data/lib/rubyn_code/permissions/RUBYN.md +17 -0
- data/lib/rubyn_code/permissions/prompter.rb +8 -8
- data/lib/rubyn_code/protocols/RUBYN.md +14 -0
- data/lib/rubyn_code/protocols/interrupt_handler.rb +1 -1
- data/lib/rubyn_code/protocols/plan_approval.rb +9 -9
- data/lib/rubyn_code/protocols/shutdown_handshake.rb +9 -11
- data/lib/rubyn_code/skills/RUBYN.md +19 -0
- data/lib/rubyn_code/skills/catalog.rb +7 -7
- data/lib/rubyn_code/skills/document.rb +15 -15
- data/lib/rubyn_code/skills/loader.rb +6 -8
- data/lib/rubyn_code/sub_agents/RUBYN.md +12 -0
- data/lib/rubyn_code/sub_agents/runner.rb +15 -15
- data/lib/rubyn_code/sub_agents/summarizer.rb +1 -1
- data/lib/rubyn_code/tasks/RUBYN.md +13 -0
- data/lib/rubyn_code/tasks/dag.rb +12 -16
- data/lib/rubyn_code/tasks/manager.rb +24 -24
- data/lib/rubyn_code/tasks/models.rb +4 -4
- data/lib/rubyn_code/teams/RUBYN.md +14 -0
- data/lib/rubyn_code/teams/mailbox.rb +38 -18
- data/lib/rubyn_code/teams/manager.rb +19 -19
- data/lib/rubyn_code/teams/teammate.rb +3 -4
- data/lib/rubyn_code/tools/RUBYN.md +38 -0
- data/lib/rubyn_code/tools/background_run.rb +9 -11
- data/lib/rubyn_code/tools/base.rb +54 -3
- data/lib/rubyn_code/tools/bash.rb +16 -34
- data/lib/rubyn_code/tools/bundle_add.rb +10 -12
- data/lib/rubyn_code/tools/bundle_install.rb +9 -11
- data/lib/rubyn_code/tools/compact.rb +10 -9
- data/lib/rubyn_code/tools/db_migrate.rb +17 -15
- data/lib/rubyn_code/tools/edit_file.rb +12 -12
- data/lib/rubyn_code/tools/executor.rb +9 -4
- data/lib/rubyn_code/tools/git_commit.rb +29 -34
- data/lib/rubyn_code/tools/git_diff.rb +17 -18
- data/lib/rubyn_code/tools/git_log.rb +17 -19
- data/lib/rubyn_code/tools/git_status.rb +18 -20
- data/lib/rubyn_code/tools/glob.rb +7 -9
- data/lib/rubyn_code/tools/grep.rb +11 -9
- data/lib/rubyn_code/tools/load_skill.rb +7 -7
- data/lib/rubyn_code/tools/memory_search.rb +13 -12
- data/lib/rubyn_code/tools/memory_write.rb +14 -12
- data/lib/rubyn_code/tools/rails_generate.rb +16 -16
- data/lib/rubyn_code/tools/read_file.rb +8 -7
- data/lib/rubyn_code/tools/read_inbox.rb +5 -5
- data/lib/rubyn_code/tools/registry.rb +2 -2
- data/lib/rubyn_code/tools/review_pr.rb +55 -55
- data/lib/rubyn_code/tools/run_specs.rb +20 -19
- data/lib/rubyn_code/tools/schema.rb +9 -11
- data/lib/rubyn_code/tools/send_message.rb +10 -10
- data/lib/rubyn_code/tools/spawn_agent.rb +51 -23
- data/lib/rubyn_code/tools/spawn_teammate.rb +21 -21
- data/lib/rubyn_code/tools/task.rb +28 -28
- data/lib/rubyn_code/tools/web_fetch.rb +46 -31
- data/lib/rubyn_code/tools/web_search.rb +64 -66
- data/lib/rubyn_code/tools/write_file.rb +7 -6
- data/lib/rubyn_code/version.rb +1 -1
- data/lib/rubyn_code.rb +136 -105
- metadata +94 -21
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
3
|
+
require 'open3'
|
|
4
|
+
require 'cgi'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'faraday'
|
|
7
|
+
require_relative 'base'
|
|
8
|
+
require_relative 'registry'
|
|
9
9
|
|
|
10
10
|
module RubynCode
|
|
11
11
|
module Tools
|
|
12
12
|
class WebSearch < Base
|
|
13
|
-
TOOL_NAME =
|
|
14
|
-
DESCRIPTION =
|
|
13
|
+
TOOL_NAME = 'web_search'
|
|
14
|
+
DESCRIPTION = 'Search the web for information. Returns search results with titles, URLs, and snippets.'
|
|
15
15
|
PARAMETERS = {
|
|
16
|
-
query: { type: :string, required: true, description:
|
|
17
|
-
num_results: { type: :integer, required: false, default: 5, description:
|
|
16
|
+
query: { type: :string, required: true, description: 'The search query string' },
|
|
17
|
+
num_results: { type: :integer, required: false, default: 5, description: 'Number of results (default: 5)' }
|
|
18
18
|
}.freeze
|
|
19
19
|
RISK_LEVEL = :external
|
|
20
20
|
REQUIRES_CONFIRMATION = true
|
|
21
21
|
|
|
22
22
|
# Adapter registry — add new providers here
|
|
23
23
|
ADAPTERS = {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
'duckduckgo' => :search_duckduckgo,
|
|
25
|
+
'brave' => :search_brave,
|
|
26
|
+
'serpapi' => :search_serpapi,
|
|
27
|
+
'tavily' => :search_tavily,
|
|
28
|
+
'google' => :search_google
|
|
29
29
|
}.freeze
|
|
30
30
|
|
|
31
31
|
def execute(query:, num_results: 5)
|
|
@@ -47,21 +47,21 @@ module RubynCode
|
|
|
47
47
|
|
|
48
48
|
# Pick the best available provider based on env vars
|
|
49
49
|
def detect_provider
|
|
50
|
-
return
|
|
51
|
-
return
|
|
52
|
-
return
|
|
53
|
-
return
|
|
50
|
+
return 'tavily' if ENV['TAVILY_API_KEY']
|
|
51
|
+
return 'brave' if ENV['BRAVE_API_KEY']
|
|
52
|
+
return 'serpapi' if ENV['SERPAPI_API_KEY']
|
|
53
|
+
return 'google' if ENV['GOOGLE_SEARCH_API_KEY'] && ENV['GOOGLE_SEARCH_CX']
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
'duckduckgo'
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# ─── DuckDuckGo (no API key, free) ───
|
|
59
59
|
|
|
60
60
|
def search_duckduckgo(query, num_results)
|
|
61
61
|
encoded = CGI.escape(query)
|
|
62
|
-
stdout, _, status =
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
stdout, _, status = safe_capture3(
|
|
63
|
+
'curl', '-sL', '--max-time', '15',
|
|
64
|
+
'-H', 'User-Agent: Mozilla/5.0 (compatible; RubynCode/1.0)',
|
|
65
65
|
"https://lite.duckduckgo.com/lite/?q=#{encoded}"
|
|
66
66
|
)
|
|
67
67
|
return [] unless status.success?
|
|
@@ -71,18 +71,18 @@ module RubynCode
|
|
|
71
71
|
|
|
72
72
|
def parse_duckduckgo(html, max)
|
|
73
73
|
results = []
|
|
74
|
-
links = html.scan(
|
|
75
|
-
links = html.scan(
|
|
76
|
-
snippets = html.scan(
|
|
74
|
+
links = html.scan(%r{<a[^>]+rel="nofollow"[^>]+href="([^"]+)"[^>]*>(.*?)</a>}i)
|
|
75
|
+
links = html.scan(%r{<a[^>]+href="(https?://(?!lite\.duckduckgo)[^"]+)"[^>]*>(.*?)</a>}i) if links.empty?
|
|
76
|
+
snippets = html.scan(%r{<td[^>]*class="result-snippet"[^>]*>(.*?)</td>}im)
|
|
77
77
|
|
|
78
78
|
links.each_with_index do |match, idx|
|
|
79
79
|
break if results.length >= max
|
|
80
80
|
|
|
81
81
|
url = match[0].strip
|
|
82
82
|
title = strip_html(match[1]).strip
|
|
83
|
-
next if url.empty? || title.empty? || url.include?(
|
|
83
|
+
next if url.empty? || title.empty? || url.include?('duckduckgo.com')
|
|
84
84
|
|
|
85
|
-
snippet = snippets[idx] ? strip_html(snippets[idx][0]).strip :
|
|
85
|
+
snippet = snippets[idx] ? strip_html(snippets[idx][0]).strip : ''
|
|
86
86
|
results << { title: title, url: url, snippet: snippet }
|
|
87
87
|
end
|
|
88
88
|
|
|
@@ -92,44 +92,42 @@ module RubynCode
|
|
|
92
92
|
# ─── Brave Search (free tier: 2000 queries/mo) ───
|
|
93
93
|
|
|
94
94
|
def search_brave(query, num_results)
|
|
95
|
-
resp = Faraday.get(
|
|
96
|
-
req.params[
|
|
97
|
-
req.params[
|
|
98
|
-
req.headers[
|
|
99
|
-
req.headers[
|
|
100
|
-
req.headers[
|
|
95
|
+
resp = Faraday.get('https://api.search.brave.com/res/v1/web/search') do |req|
|
|
96
|
+
req.params['q'] = query
|
|
97
|
+
req.params['count'] = num_results
|
|
98
|
+
req.headers['Accept'] = 'application/json'
|
|
99
|
+
req.headers['Accept-Encoding'] = 'gzip'
|
|
100
|
+
req.headers['X-Subscription-Token'] = ENV.fetch('BRAVE_API_KEY', nil)
|
|
101
101
|
req.options.timeout = 15
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
data = JSON.parse(resp.body)
|
|
105
|
-
(data.dig(
|
|
106
|
-
{ title: r[
|
|
105
|
+
(data.dig('web', 'results') || []).map do |r|
|
|
106
|
+
{ title: r['title'], url: r['url'], snippet: r['description'] || '' }
|
|
107
107
|
end
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
# ─── Tavily (built for AI agents, free tier: 1000 queries/mo) ───
|
|
111
111
|
|
|
112
112
|
def search_tavily(query, num_results)
|
|
113
|
-
resp = Faraday.post(
|
|
114
|
-
req.headers[
|
|
113
|
+
resp = Faraday.post('https://api.tavily.com/search') do |req|
|
|
114
|
+
req.headers['Content-Type'] = 'application/json'
|
|
115
115
|
req.body = JSON.generate({
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
api_key: ENV.fetch('TAVILY_API_KEY', nil),
|
|
117
|
+
query: query,
|
|
118
|
+
max_results: num_results,
|
|
119
|
+
include_answer: true
|
|
120
|
+
})
|
|
121
121
|
req.options.timeout = 15
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
data = JSON.parse(resp.body)
|
|
125
|
-
results = (data[
|
|
126
|
-
{ title: r[
|
|
125
|
+
results = (data['results'] || []).map do |r|
|
|
126
|
+
{ title: r['title'], url: r['url'], snippet: r['content'] || '' }
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
# Tavily provides a direct answer — prepend it
|
|
130
|
-
if data[
|
|
131
|
-
results.unshift({ title: "AI Answer", url: "", snippet: data["answer"] })
|
|
132
|
-
end
|
|
130
|
+
results.unshift({ title: 'AI Answer', url: '', snippet: data['answer'] }) if data['answer']
|
|
133
131
|
|
|
134
132
|
results
|
|
135
133
|
end
|
|
@@ -137,44 +135,44 @@ module RubynCode
|
|
|
137
135
|
# ─── SerpAPI (free tier: 100 queries/mo) ───
|
|
138
136
|
|
|
139
137
|
def search_serpapi(query, num_results)
|
|
140
|
-
resp = Faraday.get(
|
|
141
|
-
req.params[
|
|
142
|
-
req.params[
|
|
143
|
-
req.params[
|
|
138
|
+
resp = Faraday.get('https://serpapi.com/search.json') do |req|
|
|
139
|
+
req.params['q'] = query
|
|
140
|
+
req.params['num'] = num_results
|
|
141
|
+
req.params['api_key'] = ENV.fetch('SERPAPI_API_KEY', nil)
|
|
144
142
|
req.options.timeout = 15
|
|
145
143
|
end
|
|
146
144
|
|
|
147
145
|
data = JSON.parse(resp.body)
|
|
148
|
-
(data[
|
|
149
|
-
{ title: r[
|
|
146
|
+
(data['organic_results'] || []).map do |r|
|
|
147
|
+
{ title: r['title'], url: r['link'], snippet: r['snippet'] || '' }
|
|
150
148
|
end
|
|
151
149
|
end
|
|
152
150
|
|
|
153
151
|
# ─── Google Custom Search (free tier: 100 queries/day) ───
|
|
154
152
|
|
|
155
153
|
def search_google(query, num_results)
|
|
156
|
-
resp = Faraday.get(
|
|
157
|
-
req.params[
|
|
158
|
-
req.params[
|
|
159
|
-
req.params[
|
|
160
|
-
req.params[
|
|
154
|
+
resp = Faraday.get('https://www.googleapis.com/customsearch/v1') do |req|
|
|
155
|
+
req.params['q'] = query
|
|
156
|
+
req.params['num'] = [num_results, 10].min
|
|
157
|
+
req.params['key'] = ENV.fetch('GOOGLE_SEARCH_API_KEY', nil)
|
|
158
|
+
req.params['cx'] = ENV.fetch('GOOGLE_SEARCH_CX', nil)
|
|
161
159
|
req.options.timeout = 15
|
|
162
160
|
end
|
|
163
161
|
|
|
164
162
|
data = JSON.parse(resp.body)
|
|
165
|
-
(data[
|
|
166
|
-
{ title: r[
|
|
163
|
+
(data['items'] || []).map do |r|
|
|
164
|
+
{ title: r['title'], url: r['link'], snippet: r['snippet'] || '' }
|
|
167
165
|
end
|
|
168
166
|
end
|
|
169
167
|
|
|
170
168
|
# ─── Shared ───
|
|
171
169
|
|
|
172
170
|
def strip_html(text)
|
|
173
|
-
return
|
|
171
|
+
return '' if text.nil?
|
|
174
172
|
|
|
175
|
-
text.gsub(/<[^>]*>/,
|
|
176
|
-
.gsub(
|
|
177
|
-
.gsub(
|
|
173
|
+
text.gsub(/<[^>]*>/, '').gsub('&', '&').gsub('<', '<')
|
|
174
|
+
.gsub('>', '>').gsub('"', '"').gsub(''', "'")
|
|
175
|
+
.gsub(' ', ' ').gsub(/\s+/, ' ').strip
|
|
178
176
|
end
|
|
179
177
|
|
|
180
178
|
def format_results(query, results, provider)
|
|
@@ -184,7 +182,7 @@ module RubynCode
|
|
|
184
182
|
lines << "#{idx + 1}. #{result[:title]}"
|
|
185
183
|
lines << " URL: #{result[:url]}" unless result[:url].empty?
|
|
186
184
|
lines << " #{result[:snippet]}" unless result[:snippet].empty?
|
|
187
|
-
lines <<
|
|
185
|
+
lines << ''
|
|
188
186
|
end
|
|
189
187
|
|
|
190
188
|
truncate(lines.join("\n"), max: 30_000)
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
3
|
+
require_relative 'base'
|
|
4
|
+
require_relative 'registry'
|
|
5
5
|
|
|
6
6
|
module RubynCode
|
|
7
7
|
module Tools
|
|
8
8
|
class WriteFile < Base
|
|
9
|
-
TOOL_NAME =
|
|
10
|
-
DESCRIPTION =
|
|
9
|
+
TOOL_NAME = 'write_file'
|
|
10
|
+
DESCRIPTION = 'Writes content to a file. Creates parent directories if needed.'
|
|
11
11
|
PARAMETERS = {
|
|
12
|
-
path: { type: :string, required: true,
|
|
13
|
-
|
|
12
|
+
path: { type: :string, required: true,
|
|
13
|
+
description: 'Path to the file to write (relative to project root or absolute)' },
|
|
14
|
+
content: { type: :string, required: true, description: 'Content to write to the file' }
|
|
14
15
|
}.freeze
|
|
15
16
|
RISK_LEVEL = :write
|
|
16
17
|
REQUIRES_CONFIRMATION = false
|
data/lib/rubyn_code/version.rb
CHANGED
data/lib/rubyn_code.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative 'rubyn_code/version'
|
|
4
|
+
require_relative 'rubyn_code/debug'
|
|
4
5
|
|
|
5
6
|
module RubynCode
|
|
6
7
|
class Error < StandardError; end
|
|
@@ -12,192 +13,222 @@ module RubynCode
|
|
|
12
13
|
class ConfigError < Error; end
|
|
13
14
|
|
|
14
15
|
# Infrastructure
|
|
15
|
-
autoload :Config,
|
|
16
|
+
autoload :Config, 'rubyn_code/config/settings'
|
|
16
17
|
|
|
17
18
|
# Database
|
|
18
19
|
module DB
|
|
19
|
-
autoload :Connection,
|
|
20
|
-
autoload :Migrator,
|
|
21
|
-
autoload :Schema,
|
|
20
|
+
autoload :Connection, 'rubyn_code/db/connection'
|
|
21
|
+
autoload :Migrator, 'rubyn_code/db/migrator'
|
|
22
|
+
autoload :Schema, 'rubyn_code/db/schema'
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
# Auth
|
|
25
26
|
module Auth
|
|
26
|
-
autoload :OAuth,
|
|
27
|
-
autoload :TokenStore,
|
|
28
|
-
autoload :Server,
|
|
27
|
+
autoload :OAuth, 'rubyn_code/auth/oauth'
|
|
28
|
+
autoload :TokenStore, 'rubyn_code/auth/token_store'
|
|
29
|
+
autoload :Server, 'rubyn_code/auth/server'
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
# LLM
|
|
32
33
|
module LLM
|
|
33
|
-
autoload :Client,
|
|
34
|
-
autoload :Streaming,
|
|
35
|
-
autoload :MessageBuilder,
|
|
34
|
+
autoload :Client, 'rubyn_code/llm/client'
|
|
35
|
+
autoload :Streaming, 'rubyn_code/llm/streaming'
|
|
36
|
+
autoload :MessageBuilder, 'rubyn_code/llm/message_builder'
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
# Layer 1: Agent Loop
|
|
39
40
|
module Agent
|
|
40
|
-
autoload :Loop,
|
|
41
|
-
autoload :LoopDetector,
|
|
42
|
-
autoload :Conversation,
|
|
41
|
+
autoload :Loop, 'rubyn_code/agent/loop'
|
|
42
|
+
autoload :LoopDetector, 'rubyn_code/agent/loop_detector'
|
|
43
|
+
autoload :Conversation, 'rubyn_code/agent/conversation'
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
# Layer 2: Tool System
|
|
46
47
|
module Tools
|
|
47
|
-
autoload :Base,
|
|
48
|
-
autoload :Registry,
|
|
49
|
-
autoload :Schema,
|
|
50
|
-
autoload :Executor,
|
|
51
|
-
autoload :ReadFile,
|
|
52
|
-
autoload :WriteFile,
|
|
53
|
-
autoload :EditFile,
|
|
54
|
-
autoload :Glob,
|
|
55
|
-
autoload :Grep,
|
|
56
|
-
autoload :Bash,
|
|
57
|
-
autoload :RailsGenerate,
|
|
58
|
-
autoload :DbMigrate,
|
|
59
|
-
autoload :RunSpecs,
|
|
60
|
-
autoload :BundleInstall,
|
|
61
|
-
autoload :BundleAdd,
|
|
62
|
-
autoload :Compact,
|
|
63
|
-
autoload :LoadSkill,
|
|
64
|
-
autoload :Task,
|
|
65
|
-
autoload :MemorySearch,
|
|
66
|
-
autoload :MemoryWrite,
|
|
67
|
-
autoload :SendMessage,
|
|
68
|
-
autoload :ReadInbox,
|
|
69
|
-
autoload :ReviewPr,
|
|
70
|
-
autoload :SpawnAgent,
|
|
71
|
-
autoload :BackgroundRun,
|
|
72
|
-
autoload :WebSearch,
|
|
73
|
-
autoload :WebFetch,
|
|
74
|
-
autoload :GitCommit,
|
|
75
|
-
autoload :GitDiff,
|
|
76
|
-
autoload :GitLog,
|
|
77
|
-
autoload :GitStatus,
|
|
78
|
-
autoload :SpawnTeammate,
|
|
48
|
+
autoload :Base, 'rubyn_code/tools/base'
|
|
49
|
+
autoload :Registry, 'rubyn_code/tools/registry'
|
|
50
|
+
autoload :Schema, 'rubyn_code/tools/schema'
|
|
51
|
+
autoload :Executor, 'rubyn_code/tools/executor'
|
|
52
|
+
autoload :ReadFile, 'rubyn_code/tools/read_file'
|
|
53
|
+
autoload :WriteFile, 'rubyn_code/tools/write_file'
|
|
54
|
+
autoload :EditFile, 'rubyn_code/tools/edit_file'
|
|
55
|
+
autoload :Glob, 'rubyn_code/tools/glob'
|
|
56
|
+
autoload :Grep, 'rubyn_code/tools/grep'
|
|
57
|
+
autoload :Bash, 'rubyn_code/tools/bash'
|
|
58
|
+
autoload :RailsGenerate, 'rubyn_code/tools/rails_generate'
|
|
59
|
+
autoload :DbMigrate, 'rubyn_code/tools/db_migrate'
|
|
60
|
+
autoload :RunSpecs, 'rubyn_code/tools/run_specs'
|
|
61
|
+
autoload :BundleInstall, 'rubyn_code/tools/bundle_install'
|
|
62
|
+
autoload :BundleAdd, 'rubyn_code/tools/bundle_add'
|
|
63
|
+
autoload :Compact, 'rubyn_code/tools/compact'
|
|
64
|
+
autoload :LoadSkill, 'rubyn_code/tools/load_skill'
|
|
65
|
+
autoload :Task, 'rubyn_code/tools/task'
|
|
66
|
+
autoload :MemorySearch, 'rubyn_code/tools/memory_search'
|
|
67
|
+
autoload :MemoryWrite, 'rubyn_code/tools/memory_write'
|
|
68
|
+
autoload :SendMessage, 'rubyn_code/tools/send_message'
|
|
69
|
+
autoload :ReadInbox, 'rubyn_code/tools/read_inbox'
|
|
70
|
+
autoload :ReviewPr, 'rubyn_code/tools/review_pr'
|
|
71
|
+
autoload :SpawnAgent, 'rubyn_code/tools/spawn_agent'
|
|
72
|
+
autoload :BackgroundRun, 'rubyn_code/tools/background_run'
|
|
73
|
+
autoload :WebSearch, 'rubyn_code/tools/web_search'
|
|
74
|
+
autoload :WebFetch, 'rubyn_code/tools/web_fetch'
|
|
75
|
+
autoload :GitCommit, 'rubyn_code/tools/git_commit'
|
|
76
|
+
autoload :GitDiff, 'rubyn_code/tools/git_diff'
|
|
77
|
+
autoload :GitLog, 'rubyn_code/tools/git_log'
|
|
78
|
+
autoload :GitStatus, 'rubyn_code/tools/git_status'
|
|
79
|
+
autoload :SpawnTeammate, 'rubyn_code/tools/spawn_teammate'
|
|
79
80
|
end
|
|
80
81
|
|
|
81
82
|
# Layer 3: Permissions
|
|
82
83
|
module Permissions
|
|
83
|
-
autoload :Tier,
|
|
84
|
-
autoload :Policy,
|
|
85
|
-
autoload :DenyList,
|
|
86
|
-
autoload :Prompter,
|
|
84
|
+
autoload :Tier, 'rubyn_code/permissions/tier'
|
|
85
|
+
autoload :Policy, 'rubyn_code/permissions/policy'
|
|
86
|
+
autoload :DenyList, 'rubyn_code/permissions/deny_list'
|
|
87
|
+
autoload :Prompter, 'rubyn_code/permissions/prompter'
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
# Layer 4: Context Management
|
|
90
91
|
module Context
|
|
91
|
-
autoload :Manager,
|
|
92
|
-
autoload :Compactor,
|
|
93
|
-
autoload :MicroCompact,
|
|
94
|
-
autoload :AutoCompact,
|
|
95
|
-
autoload :ManualCompact,
|
|
92
|
+
autoload :Manager, 'rubyn_code/context/manager'
|
|
93
|
+
autoload :Compactor, 'rubyn_code/context/compactor'
|
|
94
|
+
autoload :MicroCompact, 'rubyn_code/context/micro_compact'
|
|
95
|
+
autoload :AutoCompact, 'rubyn_code/context/auto_compact'
|
|
96
|
+
autoload :ManualCompact, 'rubyn_code/context/manual_compact'
|
|
97
|
+
autoload :ContextCollapse, 'rubyn_code/context/context_collapse'
|
|
96
98
|
end
|
|
97
99
|
|
|
98
100
|
# Layer 5: Skills
|
|
99
101
|
module Skills
|
|
100
|
-
autoload :Loader,
|
|
101
|
-
autoload :Catalog,
|
|
102
|
-
autoload :Document,
|
|
102
|
+
autoload :Loader, 'rubyn_code/skills/loader'
|
|
103
|
+
autoload :Catalog, 'rubyn_code/skills/catalog'
|
|
104
|
+
autoload :Document, 'rubyn_code/skills/document'
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
# Layer 6: Sub-Agents
|
|
106
108
|
module SubAgents
|
|
107
|
-
autoload :Runner,
|
|
108
|
-
autoload :Summarizer,
|
|
109
|
+
autoload :Runner, 'rubyn_code/sub_agents/runner'
|
|
110
|
+
autoload :Summarizer, 'rubyn_code/sub_agents/summarizer'
|
|
109
111
|
end
|
|
110
112
|
|
|
111
113
|
# Layer 7: Tasks
|
|
112
114
|
module Tasks
|
|
113
|
-
autoload :Manager,
|
|
114
|
-
autoload :DAG,
|
|
115
|
-
autoload :Models,
|
|
115
|
+
autoload :Manager, 'rubyn_code/tasks/manager'
|
|
116
|
+
autoload :DAG, 'rubyn_code/tasks/dag'
|
|
117
|
+
autoload :Models, 'rubyn_code/tasks/models'
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
# Layer 8: Background
|
|
119
121
|
module Background
|
|
120
|
-
autoload :Worker,
|
|
121
|
-
autoload :Job,
|
|
122
|
-
autoload :Notifier,
|
|
122
|
+
autoload :Worker, 'rubyn_code/background/worker'
|
|
123
|
+
autoload :Job, 'rubyn_code/background/job'
|
|
124
|
+
autoload :Notifier, 'rubyn_code/background/notifier'
|
|
123
125
|
end
|
|
124
126
|
|
|
125
127
|
# Layer 9: Teams
|
|
126
128
|
module Teams
|
|
127
|
-
autoload :Manager,
|
|
128
|
-
autoload :Mailbox,
|
|
129
|
-
autoload :Teammate,
|
|
129
|
+
autoload :Manager, 'rubyn_code/teams/manager'
|
|
130
|
+
autoload :Mailbox, 'rubyn_code/teams/mailbox'
|
|
131
|
+
autoload :Teammate, 'rubyn_code/teams/teammate'
|
|
130
132
|
end
|
|
131
133
|
|
|
132
134
|
# Layer 10: Protocols
|
|
133
135
|
module Protocols
|
|
134
|
-
autoload :ShutdownHandshake,
|
|
135
|
-
autoload :PlanApproval,
|
|
136
|
-
autoload :InterruptHandler,
|
|
136
|
+
autoload :ShutdownHandshake, 'rubyn_code/protocols/shutdown_handshake'
|
|
137
|
+
autoload :PlanApproval, 'rubyn_code/protocols/plan_approval'
|
|
138
|
+
autoload :InterruptHandler, 'rubyn_code/protocols/interrupt_handler'
|
|
137
139
|
end
|
|
138
140
|
|
|
139
141
|
# Layer 11: Autonomous
|
|
140
142
|
module Autonomous
|
|
141
|
-
autoload :Daemon,
|
|
142
|
-
autoload :IdlePoller,
|
|
143
|
-
autoload :TaskClaimer,
|
|
143
|
+
autoload :Daemon, 'rubyn_code/autonomous/daemon'
|
|
144
|
+
autoload :IdlePoller, 'rubyn_code/autonomous/idle_poller'
|
|
145
|
+
autoload :TaskClaimer, 'rubyn_code/autonomous/task_claimer'
|
|
144
146
|
end
|
|
145
147
|
|
|
146
148
|
# Layer 12: Memory
|
|
147
149
|
module Memory
|
|
148
|
-
autoload :Store,
|
|
149
|
-
autoload :Search,
|
|
150
|
-
autoload :SessionPersistence,
|
|
151
|
-
autoload :Models,
|
|
150
|
+
autoload :Store, 'rubyn_code/memory/store'
|
|
151
|
+
autoload :Search, 'rubyn_code/memory/search'
|
|
152
|
+
autoload :SessionPersistence, 'rubyn_code/memory/session_persistence'
|
|
153
|
+
autoload :Models, 'rubyn_code/memory/models'
|
|
152
154
|
end
|
|
153
155
|
|
|
154
156
|
# Layer 13: Observability
|
|
155
157
|
module Observability
|
|
156
|
-
autoload :TokenCounter,
|
|
157
|
-
autoload :CostCalculator,
|
|
158
|
-
autoload :BudgetEnforcer,
|
|
159
|
-
autoload :UsageReporter,
|
|
160
|
-
autoload :Models,
|
|
158
|
+
autoload :TokenCounter, 'rubyn_code/observability/token_counter'
|
|
159
|
+
autoload :CostCalculator, 'rubyn_code/observability/cost_calculator'
|
|
160
|
+
autoload :BudgetEnforcer, 'rubyn_code/observability/budget_enforcer'
|
|
161
|
+
autoload :UsageReporter, 'rubyn_code/observability/usage_reporter'
|
|
162
|
+
autoload :Models, 'rubyn_code/observability/models'
|
|
161
163
|
end
|
|
162
164
|
|
|
163
165
|
# Layer 14: Hooks
|
|
164
166
|
module Hooks
|
|
165
|
-
autoload :Registry,
|
|
166
|
-
autoload :Runner,
|
|
167
|
-
autoload :BuiltIn,
|
|
168
|
-
autoload :UserHooks,
|
|
167
|
+
autoload :Registry, 'rubyn_code/hooks/registry'
|
|
168
|
+
autoload :Runner, 'rubyn_code/hooks/runner'
|
|
169
|
+
autoload :BuiltIn, 'rubyn_code/hooks/built_in'
|
|
170
|
+
autoload :UserHooks, 'rubyn_code/hooks/user_hooks'
|
|
169
171
|
end
|
|
170
172
|
|
|
171
173
|
# Layer 15: MCP
|
|
172
174
|
module MCP
|
|
173
|
-
autoload :Client,
|
|
174
|
-
autoload :StdioTransport,
|
|
175
|
-
autoload :SSETransport,
|
|
176
|
-
autoload :ToolBridge,
|
|
177
|
-
autoload :Config,
|
|
175
|
+
autoload :Client, 'rubyn_code/mcp/client'
|
|
176
|
+
autoload :StdioTransport, 'rubyn_code/mcp/stdio_transport'
|
|
177
|
+
autoload :SSETransport, 'rubyn_code/mcp/sse_transport'
|
|
178
|
+
autoload :ToolBridge, 'rubyn_code/mcp/tool_bridge'
|
|
179
|
+
autoload :Config, 'rubyn_code/mcp/config'
|
|
178
180
|
end
|
|
179
181
|
|
|
180
182
|
# Layer 16: Learning
|
|
181
183
|
module Learning
|
|
182
|
-
autoload :Extractor,
|
|
183
|
-
autoload :Instinct,
|
|
184
|
-
autoload :InstinctMethods,
|
|
185
|
-
autoload :Injector,
|
|
184
|
+
autoload :Extractor, 'rubyn_code/learning/extractor'
|
|
185
|
+
autoload :Instinct, 'rubyn_code/learning/instinct'
|
|
186
|
+
autoload :InstinctMethods, 'rubyn_code/learning/instinct'
|
|
187
|
+
autoload :Injector, 'rubyn_code/learning/injector'
|
|
186
188
|
end
|
|
187
189
|
|
|
188
190
|
# CLI
|
|
189
191
|
module CLI
|
|
190
|
-
autoload :App,
|
|
191
|
-
autoload :REPL,
|
|
192
|
-
autoload :InputHandler,
|
|
193
|
-
autoload :Renderer,
|
|
194
|
-
autoload :Spinner,
|
|
195
|
-
autoload :StreamFormatter,
|
|
192
|
+
autoload :App, 'rubyn_code/cli/app'
|
|
193
|
+
autoload :REPL, 'rubyn_code/cli/repl'
|
|
194
|
+
autoload :InputHandler, 'rubyn_code/cli/input_handler'
|
|
195
|
+
autoload :Renderer, 'rubyn_code/cli/renderer'
|
|
196
|
+
autoload :Spinner, 'rubyn_code/cli/spinner'
|
|
197
|
+
autoload :StreamFormatter, 'rubyn_code/cli/stream_formatter'
|
|
198
|
+
autoload :Setup, 'rubyn_code/cli/setup'
|
|
199
|
+
autoload :DaemonRunner, 'rubyn_code/cli/daemon_runner'
|
|
200
|
+
autoload :VersionCheck, 'rubyn_code/cli/version_check'
|
|
201
|
+
|
|
202
|
+
# Slash Command System
|
|
203
|
+
module Commands
|
|
204
|
+
autoload :Base, 'rubyn_code/cli/commands/base'
|
|
205
|
+
autoload :Context, 'rubyn_code/cli/commands/context'
|
|
206
|
+
autoload :Registry, 'rubyn_code/cli/commands/registry'
|
|
207
|
+
autoload :Help, 'rubyn_code/cli/commands/help'
|
|
208
|
+
autoload :Quit, 'rubyn_code/cli/commands/quit'
|
|
209
|
+
autoload :Compact, 'rubyn_code/cli/commands/compact'
|
|
210
|
+
autoload :Cost, 'rubyn_code/cli/commands/cost'
|
|
211
|
+
autoload :Clear, 'rubyn_code/cli/commands/clear'
|
|
212
|
+
autoload :Undo, 'rubyn_code/cli/commands/undo'
|
|
213
|
+
autoload :Tasks, 'rubyn_code/cli/commands/tasks'
|
|
214
|
+
autoload :Budget, 'rubyn_code/cli/commands/budget'
|
|
215
|
+
autoload :Skill, 'rubyn_code/cli/commands/skill'
|
|
216
|
+
autoload :Version, 'rubyn_code/cli/commands/version'
|
|
217
|
+
autoload :Review, 'rubyn_code/cli/commands/review'
|
|
218
|
+
autoload :Resume, 'rubyn_code/cli/commands/resume'
|
|
219
|
+
autoload :Spawn, 'rubyn_code/cli/commands/spawn'
|
|
220
|
+
autoload :Doctor, 'rubyn_code/cli/commands/doctor'
|
|
221
|
+
autoload :Tokens, 'rubyn_code/cli/commands/tokens'
|
|
222
|
+
autoload :Plan, 'rubyn_code/cli/commands/plan'
|
|
223
|
+
autoload :ContextInfo, 'rubyn_code/cli/commands/context_info'
|
|
224
|
+
autoload :Diff, 'rubyn_code/cli/commands/diff'
|
|
225
|
+
autoload :Model, 'rubyn_code/cli/commands/model'
|
|
226
|
+
end
|
|
196
227
|
end
|
|
197
228
|
|
|
198
229
|
# Output
|
|
199
230
|
module Output
|
|
200
|
-
autoload :Formatter,
|
|
201
|
-
autoload :DiffRenderer,
|
|
231
|
+
autoload :Formatter, 'rubyn_code/output/formatter'
|
|
232
|
+
autoload :DiffRenderer, 'rubyn_code/output/diff_renderer'
|
|
202
233
|
end
|
|
203
234
|
end
|