rails_ai 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/.rspec_status +96 -0
- data/AGENT_GUIDE.md +513 -0
- data/Appraisals +49 -0
- data/COMMERCIAL_LICENSE_TEMPLATE.md +92 -0
- data/FEATURES.md +204 -0
- data/LEGAL_PROTECTION_GUIDE.md +222 -0
- data/LICENSE +62 -0
- data/LICENSE_SUMMARY.md +74 -0
- data/MIT-LICENSE +62 -0
- data/PERFORMANCE.md +300 -0
- data/PROVIDERS.md +495 -0
- data/README.md +454 -0
- data/Rakefile +11 -0
- data/SPEED_OPTIMIZATIONS.md +217 -0
- data/STRUCTURE.md +139 -0
- data/USAGE_GUIDE.md +288 -0
- data/app/channels/ai_stream_channel.rb +33 -0
- data/app/components/ai/prompt_component.rb +25 -0
- data/app/controllers/concerns/ai/context_aware.rb +77 -0
- data/app/controllers/concerns/ai/streaming.rb +41 -0
- data/app/helpers/ai_helper.rb +164 -0
- data/app/jobs/ai/generate_embedding_job.rb +25 -0
- data/app/jobs/ai/generate_summary_job.rb +25 -0
- data/app/models/concerns/ai/embeddable.rb +38 -0
- data/app/views/rails_ai/dashboard/index.html.erb +51 -0
- data/config/routes.rb +19 -0
- data/lib/generators/rails_ai/install/install_generator.rb +38 -0
- data/lib/rails_ai/agents/agent_manager.rb +258 -0
- data/lib/rails_ai/agents/agent_team.rb +243 -0
- data/lib/rails_ai/agents/base_agent.rb +331 -0
- data/lib/rails_ai/agents/collaboration.rb +238 -0
- data/lib/rails_ai/agents/memory.rb +116 -0
- data/lib/rails_ai/agents/message_bus.rb +95 -0
- data/lib/rails_ai/agents/specialized_agents.rb +391 -0
- data/lib/rails_ai/agents/task_queue.rb +111 -0
- data/lib/rails_ai/cache.rb +14 -0
- data/lib/rails_ai/config.rb +40 -0
- data/lib/rails_ai/context.rb +7 -0
- data/lib/rails_ai/context_analyzer.rb +86 -0
- data/lib/rails_ai/engine.rb +48 -0
- data/lib/rails_ai/events.rb +9 -0
- data/lib/rails_ai/image_context.rb +110 -0
- data/lib/rails_ai/performance.rb +231 -0
- data/lib/rails_ai/provider.rb +8 -0
- data/lib/rails_ai/providers/anthropic_adapter.rb +256 -0
- data/lib/rails_ai/providers/base.rb +60 -0
- data/lib/rails_ai/providers/dummy_adapter.rb +29 -0
- data/lib/rails_ai/providers/gemini_adapter.rb +509 -0
- data/lib/rails_ai/providers/openai_adapter.rb +535 -0
- data/lib/rails_ai/providers/secure_anthropic_adapter.rb +206 -0
- data/lib/rails_ai/providers/secure_openai_adapter.rb +284 -0
- data/lib/rails_ai/railtie.rb +48 -0
- data/lib/rails_ai/redactor.rb +12 -0
- data/lib/rails_ai/security/api_key_manager.rb +82 -0
- data/lib/rails_ai/security/audit_logger.rb +46 -0
- data/lib/rails_ai/security/error_handler.rb +62 -0
- data/lib/rails_ai/security/input_validator.rb +176 -0
- data/lib/rails_ai/security/secure_file_handler.rb +45 -0
- data/lib/rails_ai/security/secure_http_client.rb +177 -0
- data/lib/rails_ai/security.rb +0 -0
- data/lib/rails_ai/version.rb +5 -0
- data/lib/rails_ai/window_context.rb +103 -0
- data/lib/rails_ai.rb +502 -0
- data/monitoring/ci_setup_guide.md +214 -0
- data/monitoring/enhanced_monitoring_script.rb +237 -0
- data/monitoring/google_alerts_setup.md +42 -0
- data/monitoring_log_20250921.txt +0 -0
- data/monitoring_script.rb +161 -0
- data/rails_ai.gemspec +54 -0
- data/scripts/security_scanner.rb +353 -0
- data/setup_monitoring.sh +163 -0
- data/wiki/API-Documentation.md +734 -0
- data/wiki/Architecture-Overview.md +672 -0
- data/wiki/Contributing-Guide.md +407 -0
- data/wiki/Development-Setup.md +532 -0
- data/wiki/Home.md +278 -0
- data/wiki/Installation-Guide.md +527 -0
- data/wiki/Quick-Start.md +186 -0
- data/wiki/README.md +135 -0
- data/wiki/Release-Process.md +467 -0
- metadata +385 -0
@@ -0,0 +1,353 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'yaml'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
class SecurityScanner
|
10
|
+
VULNERABILITY_DB = {
|
11
|
+
'sql_injection' => {
|
12
|
+
patterns: [
|
13
|
+
/SELECT.*FROM/i,
|
14
|
+
/INSERT.*INTO/i,
|
15
|
+
/UPDATE.*SET/i,
|
16
|
+
/DELETE.*FROM/i,
|
17
|
+
/UNION.*SELECT/i,
|
18
|
+
/DROP.*TABLE/i
|
19
|
+
],
|
20
|
+
severity: 'HIGH',
|
21
|
+
description: 'Potential SQL injection vulnerability'
|
22
|
+
},
|
23
|
+
'xss' => {
|
24
|
+
patterns: [
|
25
|
+
/<script[^>]*>.*?<\/script>/mi,
|
26
|
+
/javascript:/i,
|
27
|
+
/vbscript:/i,
|
28
|
+
/on\w+\s*=/i,
|
29
|
+
/<iframe[^>]*>.*?<\/iframe>/mi
|
30
|
+
],
|
31
|
+
severity: 'HIGH',
|
32
|
+
description: 'Potential XSS vulnerability'
|
33
|
+
},
|
34
|
+
'path_traversal' => {
|
35
|
+
patterns: [
|
36
|
+
/\.\.\//,
|
37
|
+
/\.\.\\/,
|
38
|
+
/\.\.%2f/i,
|
39
|
+
/\.\.%5c/i,
|
40
|
+
/\.\.%252f/i,
|
41
|
+
/\.\.%255c/i
|
42
|
+
],
|
43
|
+
severity: 'HIGH',
|
44
|
+
description: 'Potential directory traversal vulnerability'
|
45
|
+
},
|
46
|
+
'command_injection' => {
|
47
|
+
patterns: [
|
48
|
+
/system\s*\(/,
|
49
|
+
/exec\s*\(/,
|
50
|
+
/`[^`]*`/,
|
51
|
+
/%x\[/,
|
52
|
+
/IO\.popen/,
|
53
|
+
/Kernel\.system/
|
54
|
+
],
|
55
|
+
severity: 'CRITICAL',
|
56
|
+
description: 'Potential command injection vulnerability'
|
57
|
+
},
|
58
|
+
'hardcoded_secrets' => {
|
59
|
+
patterns: [
|
60
|
+
/password\s*=\s*['"][^'"]+['"]/i,
|
61
|
+
/api[_-]?key\s*=\s*['"][^'"]+['"]/i,
|
62
|
+
/secret\s*=\s*['"][^'"]+['"]/i,
|
63
|
+
/token\s*=\s*['"][^'"]+['"]/i,
|
64
|
+
/private[_-]?key\s*=\s*['"][^'"]+['"]/i
|
65
|
+
],
|
66
|
+
severity: 'CRITICAL',
|
67
|
+
description: 'Hardcoded secret detected'
|
68
|
+
},
|
69
|
+
'insecure_random' => {
|
70
|
+
patterns: [
|
71
|
+
/rand\s*\(/,
|
72
|
+
/Random\.rand/,
|
73
|
+
/SecureRandom\.random_bytes\s*\(\s*1\s*\)/,
|
74
|
+
/Random\.new/
|
75
|
+
],
|
76
|
+
severity: 'MEDIUM',
|
77
|
+
description: 'Insecure random number generation'
|
78
|
+
},
|
79
|
+
'mass_assignment' => {
|
80
|
+
patterns: [
|
81
|
+
/params\[:.*\]\.permit!/,
|
82
|
+
/params\[:.*\]\.permit\s*\(\s*\)/,
|
83
|
+
/update_attributes\s*\(\s*params/,
|
84
|
+
/assign_attributes\s*\(\s*params/
|
85
|
+
],
|
86
|
+
severity: 'HIGH',
|
87
|
+
description: 'Potential mass assignment vulnerability'
|
88
|
+
},
|
89
|
+
'unsafe_deserialization' => {
|
90
|
+
patterns: [
|
91
|
+
/Marshal\.load/,
|
92
|
+
/YAML\.load/,
|
93
|
+
/JSON\.parse\s*\(\s*.*\s*,\s*.*\s*\)/,
|
94
|
+
/eval\s*\(/
|
95
|
+
],
|
96
|
+
severity: 'CRITICAL',
|
97
|
+
description: 'Unsafe deserialization detected'
|
98
|
+
},
|
99
|
+
'cors_misconfiguration' => {
|
100
|
+
patterns: [
|
101
|
+
/Access-Control-Allow-Origin\s*:\s*\*/,
|
102
|
+
/Access-Control-Allow-Credentials\s*:\s*true.*Access-Control-Allow-Origin\s*:\s*\*/
|
103
|
+
],
|
104
|
+
severity: 'MEDIUM',
|
105
|
+
description: 'Potential CORS misconfiguration'
|
106
|
+
},
|
107
|
+
'insecure_redirect' => {
|
108
|
+
patterns: [
|
109
|
+
/redirect_to\s*\(\s*params/,
|
110
|
+
/redirect_to\s*\(\s*request\.referer/,
|
111
|
+
/redirect_to\s*\(\s*request\.url/
|
112
|
+
],
|
113
|
+
severity: 'HIGH',
|
114
|
+
description: 'Potential open redirect vulnerability'
|
115
|
+
}
|
116
|
+
}.freeze
|
117
|
+
|
118
|
+
def initialize
|
119
|
+
@results = []
|
120
|
+
@scan_time = Time.now
|
121
|
+
end
|
122
|
+
|
123
|
+
def scan
|
124
|
+
puts "🔍 Starting security scan..."
|
125
|
+
puts "📅 Scan time: #{@scan_time}"
|
126
|
+
puts "=" * 50
|
127
|
+
|
128
|
+
scan_ruby_files
|
129
|
+
scan_config_files
|
130
|
+
scan_gemfile
|
131
|
+
scan_github_workflows
|
132
|
+
scan_documentation
|
133
|
+
|
134
|
+
generate_report
|
135
|
+
puts "✅ Security scan completed!"
|
136
|
+
puts "📊 Results saved to: security_scan_report.json"
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def scan_ruby_files
|
142
|
+
puts "🔍 Scanning Ruby files..."
|
143
|
+
|
144
|
+
ruby_files = Dir.glob('lib/**/*.rb') + Dir.glob('spec/**/*.rb')
|
145
|
+
|
146
|
+
ruby_files.each do |file|
|
147
|
+
next unless File.file?(file)
|
148
|
+
|
149
|
+
content = File.read(file)
|
150
|
+
scan_file_content(file, content)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def scan_config_files
|
155
|
+
puts "🔍 Scanning configuration files..."
|
156
|
+
|
157
|
+
config_files = [
|
158
|
+
'config/application.rb',
|
159
|
+
'config/environments/production.rb',
|
160
|
+
'config/database.yml',
|
161
|
+
'config/secrets.yml',
|
162
|
+
'config/credentials.yml.enc'
|
163
|
+
]
|
164
|
+
|
165
|
+
config_files.each do |file|
|
166
|
+
next unless File.exist?(file)
|
167
|
+
|
168
|
+
content = File.read(file)
|
169
|
+
scan_file_content(file, content)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def scan_gemfile
|
174
|
+
puts "🔍 Scanning Gemfile..."
|
175
|
+
|
176
|
+
return unless File.exist?('Gemfile')
|
177
|
+
|
178
|
+
content = File.read('Gemfile')
|
179
|
+
scan_file_content('Gemfile', content)
|
180
|
+
|
181
|
+
# Check for known vulnerable gems
|
182
|
+
check_vulnerable_gems(content)
|
183
|
+
end
|
184
|
+
|
185
|
+
def scan_github_workflows
|
186
|
+
puts "🔍 Scanning GitHub workflows..."
|
187
|
+
|
188
|
+
workflow_files = Dir.glob('.github/workflows/*.yml') + Dir.glob('.github/workflows/*.yaml')
|
189
|
+
|
190
|
+
workflow_files.each do |file|
|
191
|
+
next unless File.file?(file)
|
192
|
+
|
193
|
+
content = File.read(file)
|
194
|
+
scan_file_content(file, content)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def scan_documentation
|
199
|
+
puts "🔍 Scanning documentation files..."
|
200
|
+
|
201
|
+
doc_files = Dir.glob('*.md') + Dir.glob('docs/**/*.md')
|
202
|
+
|
203
|
+
doc_files.each do |file|
|
204
|
+
next unless File.file?(file)
|
205
|
+
|
206
|
+
content = File.read(file)
|
207
|
+
scan_file_content(file, content)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def scan_file_content(file_path, content)
|
212
|
+
VULNERABILITY_DB.each do |vuln_type, config|
|
213
|
+
config[:patterns].each do |pattern|
|
214
|
+
matches = content.scan(pattern)
|
215
|
+
|
216
|
+
next if matches.empty?
|
217
|
+
|
218
|
+
matches.each_with_index do |match, index|
|
219
|
+
line_number = find_line_number(content, match)
|
220
|
+
|
221
|
+
@results << {
|
222
|
+
file: file_path,
|
223
|
+
line: line_number,
|
224
|
+
vulnerability: vuln_type,
|
225
|
+
severity: config[:severity],
|
226
|
+
description: config[:description],
|
227
|
+
match: match.to_s,
|
228
|
+
context: get_context(content, line_number)
|
229
|
+
}
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def check_vulnerable_gems(gemfile_content)
|
236
|
+
vulnerable_gems = {
|
237
|
+
'rails' => { min_version: '6.0.0', reason: 'Security updates required' },
|
238
|
+
'rack' => { min_version: '2.0.0', reason: 'Security vulnerabilities in older versions' },
|
239
|
+
'nokogiri' => { min_version: '1.10.0', reason: 'XML parsing vulnerabilities' },
|
240
|
+
'json' => { min_version: '2.0.0', reason: 'JSON parsing vulnerabilities' }
|
241
|
+
}
|
242
|
+
|
243
|
+
gemfile_content.scan(/gem\s+['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]+)['"])?/) do |gem_name, version|
|
244
|
+
if vulnerable_gems.key?(gem_name)
|
245
|
+
gem_info = vulnerable_gems[gem_name]
|
246
|
+
|
247
|
+
@results << {
|
248
|
+
file: 'Gemfile',
|
249
|
+
line: 0,
|
250
|
+
vulnerability: 'vulnerable_gem',
|
251
|
+
severity: 'MEDIUM',
|
252
|
+
description: "Potentially vulnerable gem: #{gem_name}",
|
253
|
+
match: "gem '#{gem_name}'",
|
254
|
+
context: "Consider updating to version #{gem_info[:min_version]} or later",
|
255
|
+
recommendation: gem_info[:reason]
|
256
|
+
}
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def find_line_number(content, match)
|
262
|
+
lines = content.split("\n")
|
263
|
+
lines.each_with_index do |line, index|
|
264
|
+
return index + 1 if line.include?(match.to_s)
|
265
|
+
end
|
266
|
+
0
|
267
|
+
end
|
268
|
+
|
269
|
+
def get_context(content, line_number)
|
270
|
+
lines = content.split("\n")
|
271
|
+
start_line = [line_number - 3, 0].max
|
272
|
+
end_line = [line_number + 2, lines.length - 1].min
|
273
|
+
|
274
|
+
lines[start_line..end_line].join("\n")
|
275
|
+
end
|
276
|
+
|
277
|
+
def generate_report
|
278
|
+
report = {
|
279
|
+
scan_time: @scan_time.iso8601,
|
280
|
+
total_vulnerabilities: @results.length,
|
281
|
+
severity_counts: count_by_severity,
|
282
|
+
vulnerabilities: @results,
|
283
|
+
summary: generate_summary
|
284
|
+
}
|
285
|
+
|
286
|
+
File.write('security_scan_report.json', JSON.pretty_generate(report))
|
287
|
+
|
288
|
+
# Generate markdown report
|
289
|
+
generate_markdown_report(report)
|
290
|
+
end
|
291
|
+
|
292
|
+
def count_by_severity
|
293
|
+
@results.group_by { |r| r[:severity] }.transform_values(&:count)
|
294
|
+
end
|
295
|
+
|
296
|
+
def generate_summary
|
297
|
+
{
|
298
|
+
critical: @results.count { |r| r[:severity] == 'CRITICAL' },
|
299
|
+
high: @results.count { |r| r[:severity] == 'HIGH' },
|
300
|
+
medium: @results.count { |r| r[:severity] == 'MEDIUM' },
|
301
|
+
low: @results.count { |r| r[:severity] == 'LOW' }
|
302
|
+
}
|
303
|
+
end
|
304
|
+
|
305
|
+
def generate_markdown_report(report)
|
306
|
+
markdown = <<~MARKDOWN
|
307
|
+
# Security Scan Report
|
308
|
+
|
309
|
+
**Scan Time:** #{report[:scan_time]}
|
310
|
+
**Total Vulnerabilities:** #{report[:total_vulnerabilities]}
|
311
|
+
|
312
|
+
## Summary
|
313
|
+
|
314
|
+
| Severity | Count |
|
315
|
+
|----------|-------|
|
316
|
+
| Critical | #{report[:summary][:critical]} |
|
317
|
+
| High | #{report[:summary][:high]} |
|
318
|
+
| Medium | #{report[:summary][:medium]} |
|
319
|
+
| Low | #{report[:summary][:low]} |
|
320
|
+
|
321
|
+
## Vulnerabilities
|
322
|
+
|
323
|
+
MARKDOWN
|
324
|
+
|
325
|
+
@results.group_by { |r| r[:severity] }.each do |severity, vulns|
|
326
|
+
markdown += "\n### #{severity.upcase} (#{vulns.count})\n\n"
|
327
|
+
|
328
|
+
vulns.each do |vuln|
|
329
|
+
markdown += <<~VULN
|
330
|
+
**File:** `#{vuln[:file]}:#{vuln[:line]}`
|
331
|
+
**Type:** #{vuln[:vulnerability]}
|
332
|
+
**Description:** #{vuln[:description]}
|
333
|
+
**Match:** `#{vuln[:match]}`
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
#{vuln[:context]}
|
337
|
+
```
|
338
|
+
|
339
|
+
---
|
340
|
+
|
341
|
+
VULN
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
File.write('security_scan_report.md', markdown)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
# Run the scanner
|
350
|
+
if __FILE__ == $0
|
351
|
+
scanner = SecurityScanner.new
|
352
|
+
scanner.scan
|
353
|
+
end
|
data/setup_monitoring.sh
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
echo "🛡️ Setting up Rails AI Monitoring System"
|
4
|
+
echo "========================================"
|
5
|
+
|
6
|
+
# Create monitoring directory
|
7
|
+
mkdir -p monitoring
|
8
|
+
cd monitoring
|
9
|
+
|
10
|
+
# Create Google Alerts setup guide
|
11
|
+
cat > google_alerts_setup.md << 'GUIDE'
|
12
|
+
# Google Alerts Setup for Rails AI
|
13
|
+
|
14
|
+
## Step 1: Go to Google Alerts
|
15
|
+
Visit: https://www.google.com/alerts
|
16
|
+
|
17
|
+
## Step 2: Create Alerts for These Terms:
|
18
|
+
- "Rails AI" commercial
|
19
|
+
- "rails_ai" business
|
20
|
+
- "Rails AI" enterprise
|
21
|
+
- "rails_ai" license
|
22
|
+
- "Rails AI" gem
|
23
|
+
- "rails_ai" ruby
|
24
|
+
|
25
|
+
## Step 3: Configure Each Alert:
|
26
|
+
- Frequency: As-it-happens
|
27
|
+
- Sources: Everything
|
28
|
+
- Language: English
|
29
|
+
- Region: Any region
|
30
|
+
- Delivery: Your email
|
31
|
+
|
32
|
+
## Step 4: Test Alerts
|
33
|
+
Search for your terms manually to ensure alerts work.
|
34
|
+
GUIDE
|
35
|
+
|
36
|
+
# Create GitHub monitoring guide
|
37
|
+
cat > github_monitoring.md << 'GITHUB'
|
38
|
+
# GitHub Monitoring for Rails AI
|
39
|
+
|
40
|
+
## Manual Searches (Run Weekly):
|
41
|
+
1. Go to https://github.com/search
|
42
|
+
2. Search for: "rails_ai" language:ruby
|
43
|
+
3. Search for: "Rails AI" language:ruby
|
44
|
+
4. Search for: "rails-ai" language:ruby
|
45
|
+
5. Search for: "railsai" language:ruby
|
46
|
+
|
47
|
+
## GitHub Notifications Setup:
|
48
|
+
1. Go to GitHub.com → Settings → Notifications
|
49
|
+
2. Enable email notifications for mentions
|
50
|
+
3. Watch relevant repositories
|
51
|
+
4. Set up keyword notifications
|
52
|
+
|
53
|
+
## What to Look For:
|
54
|
+
- Repositories using your gem
|
55
|
+
- Forks of your code
|
56
|
+
- Similar project names
|
57
|
+
- Commercial usage indicators
|
58
|
+
GITHUB
|
59
|
+
|
60
|
+
# Create RubyGems monitoring guide
|
61
|
+
cat > rubygems_monitoring.md << 'RUBYGEMS'
|
62
|
+
# RubyGems Monitoring for Rails AI
|
63
|
+
|
64
|
+
## Manual Checks (Run Weekly):
|
65
|
+
1. Go to https://rubygems.org
|
66
|
+
2. Search for: "rails_ai"
|
67
|
+
3. Search for: "rails-ai"
|
68
|
+
4. Search for: "railsai"
|
69
|
+
5. Check download statistics
|
70
|
+
|
71
|
+
## What to Look For:
|
72
|
+
- Similar gem names
|
73
|
+
- High download numbers
|
74
|
+
- Commercial usage in descriptions
|
75
|
+
- Forked or copied code
|
76
|
+
|
77
|
+
## API Access (Optional):
|
78
|
+
- Get RubyGems API key for automated monitoring
|
79
|
+
- Use the monitoring script with API access
|
80
|
+
RUBYGEMS
|
81
|
+
|
82
|
+
# Create social media monitoring guide
|
83
|
+
cat > social_media_monitoring.md << 'SOCIAL'
|
84
|
+
# Social Media Monitoring for Rails AI
|
85
|
+
|
86
|
+
## Twitter/X:
|
87
|
+
1. Search for: "Rails AI"
|
88
|
+
2. Search for: "rails_ai"
|
89
|
+
3. Set up keyword notifications
|
90
|
+
4. Monitor relevant hashtags
|
91
|
+
|
92
|
+
## LinkedIn:
|
93
|
+
1. Search for: "Rails AI"
|
94
|
+
2. Search for: "rails_ai"
|
95
|
+
3. Look for company mentions
|
96
|
+
4. Check job postings
|
97
|
+
|
98
|
+
## Reddit:
|
99
|
+
1. Search r/ruby for "Rails AI"
|
100
|
+
2. Search r/rails for "rails_ai"
|
101
|
+
3. Search r/programming for mentions
|
102
|
+
4. Monitor for commercial usage
|
103
|
+
|
104
|
+
## Stack Overflow:
|
105
|
+
1. Search for: "rails_ai"
|
106
|
+
2. Search for: "Rails AI"
|
107
|
+
3. Look for commercial usage questions
|
108
|
+
4. Monitor for licensing discussions
|
109
|
+
SOCIAL
|
110
|
+
|
111
|
+
# Create monitoring checklist
|
112
|
+
cat > monitoring_checklist.md << 'CHECKLIST'
|
113
|
+
# Rails AI Monitoring Checklist
|
114
|
+
|
115
|
+
## Daily Tasks:
|
116
|
+
- [ ] Check Google Alerts email
|
117
|
+
- [ ] Check GitHub notifications
|
118
|
+
- [ ] Check social media mentions
|
119
|
+
|
120
|
+
## Weekly Tasks:
|
121
|
+
- [ ] Run GitHub searches
|
122
|
+
- [ ] Check RubyGems.org
|
123
|
+
- [ ] Search social media platforms
|
124
|
+
- [ ] Check business directories
|
125
|
+
|
126
|
+
## Monthly Tasks:
|
127
|
+
- [ ] Legal database searches
|
128
|
+
- [ ] Patent database checks
|
129
|
+
- [ ] Industry publication reviews
|
130
|
+
- [ ] Update monitoring terms
|
131
|
+
|
132
|
+
## When You Find Infringement:
|
133
|
+
- [ ] Document everything (screenshots)
|
134
|
+
- [ ] Save evidence to multiple locations
|
135
|
+
- [ ] Send cease and desist letter
|
136
|
+
- [ ] File DMCA takedowns if applicable
|
137
|
+
- [ ] Consult with IP lawyer
|
138
|
+
|
139
|
+
## Emergency Contacts:
|
140
|
+
- IP Lawyer: [Add your lawyer's contact]
|
141
|
+
- CIPO: 1-866-997-1936
|
142
|
+
- Copyright Board: 613-952-8621
|
143
|
+
CHECKLIST
|
144
|
+
|
145
|
+
# Make the monitoring script executable
|
146
|
+
chmod +x ../monitoring_script.rb
|
147
|
+
|
148
|
+
echo "✅ Monitoring setup complete!"
|
149
|
+
echo ""
|
150
|
+
echo "📁 Created monitoring directory with guides:"
|
151
|
+
echo " - google_alerts_setup.md"
|
152
|
+
echo " - github_monitoring.md"
|
153
|
+
echo " - rubygems_monitoring.md"
|
154
|
+
echo " - social_media_monitoring.md"
|
155
|
+
echo " - monitoring_checklist.md"
|
156
|
+
echo ""
|
157
|
+
echo "🚀 Next steps:"
|
158
|
+
echo "1. Set up Google Alerts (see google_alerts_setup.md)"
|
159
|
+
echo "2. Configure GitHub notifications (see github_monitoring.md)"
|
160
|
+
echo "3. Run weekly manual checks (see monitoring_checklist.md)"
|
161
|
+
echo "4. Run the monitoring script: ruby monitoring_script.rb"
|
162
|
+
echo ""
|
163
|
+
echo "🛡️ Your Rails AI is now protected with monitoring!"
|