spyglasses 1.0.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 +3 -0
- data/.rspec_status +54 -0
- data/CHANGELOG.md +41 -0
- data/DEVELOPMENT.md +215 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +143 -0
- data/LICENSE +21 -0
- data/README.md +335 -0
- data/Rakefile +37 -0
- data/lib/spyglasses/client.rb +491 -0
- data/lib/spyglasses/configuration.rb +79 -0
- data/lib/spyglasses/middleware.rb +197 -0
- data/lib/spyglasses/types.rb +210 -0
- data/lib/spyglasses/version.rb +5 -0
- data/lib/spyglasses.rb +28 -0
- metadata +203 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 500f84bd8f684ffc7b0bc15d28743dcf50e5c883191efb166de087ecc001496c
|
4
|
+
data.tar.gz: 4dd3be43d678475d4f16d1988f51ebcdab33a941add56040aed2c714ab725121
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c1e7d7d73fc2a1551987c96eafada4e9e893fa9735adeb0174b13bf7f8da99740313c8135ed90ca40ef41a4db694939f8d8359d97a9632744c79691ec0ad531e
|
7
|
+
data.tar.gz: b383b31150503a03161f3fcf2915d5049177d947c44187f5180623cb7205c368be298d719aa6061dd1478617c6042aa2cc151e4b41bc94f60a96a5abb4e3cae6
|
data/.rspec
ADDED
data/.rspec_status
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
example_id | status | run_time |
|
2
|
+
---------------------------------------------- | ------ | --------------- |
|
3
|
+
./spec/spyglasses/client_spec.rb[1:1:1] | passed | 0.00252 seconds |
|
4
|
+
./spec/spyglasses/client_spec.rb[1:1:2] | passed | 0.00096 seconds |
|
5
|
+
./spec/spyglasses/client_spec.rb[1:2:1:1] | passed | 0.02254 seconds |
|
6
|
+
./spec/spyglasses/client_spec.rb[1:2:2:1] | passed | 0.00235 seconds |
|
7
|
+
./spec/spyglasses/client_spec.rb[1:2:3:1] | passed | 0.00059 seconds |
|
8
|
+
./spec/spyglasses/client_spec.rb[1:3:1] | passed | 0.00084 seconds |
|
9
|
+
./spec/spyglasses/client_spec.rb[1:3:2] | passed | 0.00029 seconds |
|
10
|
+
./spec/spyglasses/client_spec.rb[1:3:3] | passed | 0.0002 seconds |
|
11
|
+
./spec/spyglasses/client_spec.rb[1:4:1] | passed | 0.00034 seconds |
|
12
|
+
./spec/spyglasses/client_spec.rb[1:4:2] | passed | 0.00022 seconds |
|
13
|
+
./spec/spyglasses/client_spec.rb[1:4:3] | passed | 0.00023 seconds |
|
14
|
+
./spec/spyglasses/client_spec.rb[1:5:1] | passed | 0.00029 seconds |
|
15
|
+
./spec/spyglasses/client_spec.rb[1:5:2] | passed | 0.0003 seconds |
|
16
|
+
./spec/spyglasses/client_spec.rb[1:5:3] | passed | 0.00018 seconds |
|
17
|
+
./spec/spyglasses/client_spec.rb[1:6:1] | passed | 0.10244 seconds |
|
18
|
+
./spec/spyglasses/client_spec.rb[1:6:2] | passed | 0.10159 seconds |
|
19
|
+
./spec/spyglasses/client_spec.rb[1:6:3] | passed | 0.10182 seconds |
|
20
|
+
./spec/spyglasses/configuration_spec.rb[1:1:1] | passed | 0.00037 seconds |
|
21
|
+
./spec/spyglasses/configuration_spec.rb[1:1:2] | passed | 0.00022 seconds |
|
22
|
+
./spec/spyglasses/configuration_spec.rb[1:2:1] | passed | 0.00013 seconds |
|
23
|
+
./spec/spyglasses/configuration_spec.rb[1:2:2] | passed | 0.00008 seconds |
|
24
|
+
./spec/spyglasses/configuration_spec.rb[1:2:3] | passed | 0.00009 seconds |
|
25
|
+
./spec/spyglasses/configuration_spec.rb[1:3:1] | passed | 0.00047 seconds |
|
26
|
+
./spec/spyglasses/configuration_spec.rb[1:4:1] | passed | 0.00012 seconds |
|
27
|
+
./spec/spyglasses/configuration_spec.rb[1:5:1] | passed | 0.00328 seconds |
|
28
|
+
./spec/spyglasses/configuration_spec.rb[1:5:2] | passed | 0.00024 seconds |
|
29
|
+
./spec/spyglasses/configuration_spec.rb[1:5:3] | passed | 0.00016 seconds |
|
30
|
+
./spec/spyglasses/configuration_spec.rb[1:5:4] | passed | 0.00016 seconds |
|
31
|
+
./spec/spyglasses/configuration_spec.rb[1:5:5] | passed | 0.0001 seconds |
|
32
|
+
./spec/spyglasses/configuration_spec.rb[1:6:1] | passed | 0.0001 seconds |
|
33
|
+
./spec/spyglasses/configuration_spec.rb[1:6:2] | passed | 0.00007 seconds |
|
34
|
+
./spec/spyglasses/middleware_spec.rb[1:1:1] | passed | 0.00018 seconds |
|
35
|
+
./spec/spyglasses/middleware_spec.rb[1:2:1:1] | passed | 0.00041 seconds |
|
36
|
+
./spec/spyglasses/middleware_spec.rb[1:2:1:2] | passed | 0.00024 seconds |
|
37
|
+
./spec/spyglasses/middleware_spec.rb[1:2:1:3] | passed | 0.00019 seconds |
|
38
|
+
./spec/spyglasses/middleware_spec.rb[1:2:1:4] | passed | 0.00301 seconds |
|
39
|
+
./spec/spyglasses/middleware_spec.rb[1:2:1:5] | passed | 0.00038 seconds |
|
40
|
+
./spec/spyglasses/middleware_spec.rb[1:2:2:1] | passed | 0.00033 seconds |
|
41
|
+
./spec/spyglasses/middleware_spec.rb[1:2:2:2] | passed | 0.10132 seconds |
|
42
|
+
./spec/spyglasses/middleware_spec.rb[1:2:2:3] | passed | 0.10237 seconds |
|
43
|
+
./spec/spyglasses/middleware_spec.rb[1:2:3:1] | passed | 0.1138 seconds |
|
44
|
+
./spec/spyglasses/middleware_spec.rb[1:2:4:1] | passed | 0.10115 seconds |
|
45
|
+
./spec/spyglasses/middleware_spec.rb[1:2:5:1] | passed | 0.10181 seconds |
|
46
|
+
./spec/spyglasses/middleware_spec.rb[1:3:1] | passed | 0.00046 seconds |
|
47
|
+
./spec/spyglasses/middleware_spec.rb[1:3:2] | passed | 0.00054 seconds |
|
48
|
+
./spec/spyglasses/middleware_spec.rb[1:3:3] | passed | 0.00013 seconds |
|
49
|
+
./spec/spyglasses_spec.rb[1:1] | passed | 0.00008 seconds |
|
50
|
+
./spec/spyglasses_spec.rb[1:2:1] | passed | 0.00181 seconds |
|
51
|
+
./spec/spyglasses_spec.rb[1:2:2] | passed | 0.00035 seconds |
|
52
|
+
./spec/spyglasses_spec.rb[1:3:1] | passed | 0.00008 seconds |
|
53
|
+
./spec/spyglasses_spec.rb[1:3:2] | passed | 0.00006 seconds |
|
54
|
+
./spec/spyglasses_spec.rb[1:4:1] | passed | 0.00007 seconds |
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [1.0.0] - 2024-01-XX
|
11
|
+
|
12
|
+
### Added
|
13
|
+
- Initial release of Spyglasses Ruby gem
|
14
|
+
- Core AI agent detection functionality
|
15
|
+
- Bot pattern matching with regex support
|
16
|
+
- AI referrer detection for platforms like ChatGPT, Claude, Perplexity
|
17
|
+
- Flexible blocking system based on patterns and property settings
|
18
|
+
- Rack middleware for easy integration with Ruby web frameworks
|
19
|
+
- Rails, Sinatra, and generic Rack application support
|
20
|
+
- Non-blocking request logging to Spyglasses collector API
|
21
|
+
- Thread-safe pattern caching and background processing
|
22
|
+
- Comprehensive test suite with >95% code coverage
|
23
|
+
- Environment variable configuration support
|
24
|
+
- Default patterns for common AI agents and crawlers
|
25
|
+
- Pattern synchronization from Spyglasses API
|
26
|
+
- Debug logging capabilities
|
27
|
+
- Comprehensive documentation and examples
|
28
|
+
|
29
|
+
### Security
|
30
|
+
- Thread-safe operations for concurrent Ruby applications
|
31
|
+
- Secure API key handling with masked logging
|
32
|
+
- Input validation and error handling
|
33
|
+
|
34
|
+
### Performance
|
35
|
+
- Compiled regex pattern caching
|
36
|
+
- Background thread processing for API calls
|
37
|
+
- Smart path exclusions for static assets
|
38
|
+
- Minimal request overhead (<1ms typical)
|
39
|
+
|
40
|
+
[Unreleased]: https://github.com/spyglasses/spyglasses-ruby/compare/v1.0.0...HEAD
|
41
|
+
[1.0.0]: https://github.com/spyglasses/spyglasses-ruby/releases/tag/v1.0.0
|
data/DEVELOPMENT.md
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
# Development Guide
|
2
|
+
|
3
|
+
This guide provides information for developers working on the Spyglasses Ruby gem.
|
4
|
+
|
5
|
+
## Architecture Overview
|
6
|
+
|
7
|
+
The gem is structured into several key components:
|
8
|
+
|
9
|
+
### Core Components
|
10
|
+
|
11
|
+
1. **`Spyglasses::Configuration`** - Handles configuration management and environment variables
|
12
|
+
2. **`Spyglasses::Client`** - Core detection logic and API communication
|
13
|
+
3. **`Spyglasses::Middleware`** - Rack middleware for web framework integration
|
14
|
+
4. **`Spyglasses::Types`** - Data structures and type definitions
|
15
|
+
|
16
|
+
### Key Features
|
17
|
+
|
18
|
+
- **Pattern Management**: Loads default patterns and syncs from API
|
19
|
+
- **Detection Logic**: Bot and AI referrer detection with regex matching
|
20
|
+
- **Blocking System**: Configurable blocking based on property settings
|
21
|
+
- **Request Logging**: Non-blocking background logging to collector API
|
22
|
+
- **Thread Safety**: Mutex-protected pattern updates and caching
|
23
|
+
|
24
|
+
## Development Setup
|
25
|
+
|
26
|
+
```bash
|
27
|
+
git clone https://github.com/spyglasses/spyglasses-ruby.git
|
28
|
+
cd spyglasses-ruby
|
29
|
+
bin/setup
|
30
|
+
```
|
31
|
+
|
32
|
+
## Running Tests
|
33
|
+
|
34
|
+
```bash
|
35
|
+
# Run all tests
|
36
|
+
bundle exec rspec
|
37
|
+
|
38
|
+
# Run with coverage
|
39
|
+
rake coverage
|
40
|
+
|
41
|
+
# Run specific test file
|
42
|
+
bundle exec rspec spec/spyglasses/client_spec.rb
|
43
|
+
|
44
|
+
# Run specific test
|
45
|
+
bundle exec rspec spec/spyglasses/client_spec.rb:42
|
46
|
+
```
|
47
|
+
|
48
|
+
## Code Quality
|
49
|
+
|
50
|
+
```bash
|
51
|
+
# Run RuboCop
|
52
|
+
bundle exec rubocop
|
53
|
+
|
54
|
+
# Auto-fix RuboCop issues
|
55
|
+
bundle exec rubocop -a
|
56
|
+
|
57
|
+
# Run all checks
|
58
|
+
rake check
|
59
|
+
```
|
60
|
+
|
61
|
+
## Building and Testing the Gem
|
62
|
+
|
63
|
+
```bash
|
64
|
+
# Build the gem
|
65
|
+
rake build
|
66
|
+
|
67
|
+
# Install locally for testing
|
68
|
+
rake install_local
|
69
|
+
|
70
|
+
# Test in an app
|
71
|
+
gem 'spyglasses', path: '/path/to/spyglasses-ruby'
|
72
|
+
```
|
73
|
+
|
74
|
+
## Testing with Real API
|
75
|
+
|
76
|
+
To test with the real Spyglasses API:
|
77
|
+
|
78
|
+
```bash
|
79
|
+
export SPYGLASSES_API_KEY=your_real_api_key
|
80
|
+
export SPYGLASSES_DEBUG=true
|
81
|
+
|
82
|
+
# Create a test script
|
83
|
+
cat > test_api.rb << 'EOF'
|
84
|
+
require 'spyglasses'
|
85
|
+
|
86
|
+
client = Spyglasses::Client.new
|
87
|
+
result = client.sync_patterns
|
88
|
+
puts "Sync result: #{result.class}"
|
89
|
+
puts "Patterns loaded: #{client.patterns.length}"
|
90
|
+
|
91
|
+
detection = client.detect('GPTBot/1.0')
|
92
|
+
puts "Detection result: #{detection.to_h}"
|
93
|
+
EOF
|
94
|
+
|
95
|
+
ruby test_api.rb
|
96
|
+
```
|
97
|
+
|
98
|
+
## Performance Testing
|
99
|
+
|
100
|
+
```bash
|
101
|
+
# Simple benchmark
|
102
|
+
cat > benchmark.rb << 'EOF'
|
103
|
+
require 'benchmark'
|
104
|
+
require 'spyglasses'
|
105
|
+
|
106
|
+
client = Spyglasses::Client.new(
|
107
|
+
Spyglasses::Configuration.new.tap { |c| c.auto_sync = false }
|
108
|
+
)
|
109
|
+
|
110
|
+
user_agents = [
|
111
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
112
|
+
'GPTBot/1.0',
|
113
|
+
'ClaudeBot/1.0',
|
114
|
+
'ChatGPT-User/1.0'
|
115
|
+
]
|
116
|
+
|
117
|
+
Benchmark.bm do |x|
|
118
|
+
x.report("1000 detections") do
|
119
|
+
1000.times do
|
120
|
+
user_agents.each { |ua| client.detect(ua) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
EOF
|
125
|
+
|
126
|
+
ruby benchmark.rb
|
127
|
+
```
|
128
|
+
|
129
|
+
## Release Process
|
130
|
+
|
131
|
+
1. Update version in `lib/spyglasses/version.rb`
|
132
|
+
2. Update `CHANGELOG.md` with changes
|
133
|
+
3. Ensure all tests pass: `rake check`
|
134
|
+
4. Build and test the gem: `rake build && rake install_local`
|
135
|
+
5. Commit changes: `git commit -am "Release v1.x.x"`
|
136
|
+
6. Tag the release: `git tag v1.x.x`
|
137
|
+
7. Push: `git push && git push --tags`
|
138
|
+
8. Publish: `gem push pkg/spyglasses-1.x.x.gem`
|
139
|
+
|
140
|
+
## Contributing Guidelines
|
141
|
+
|
142
|
+
### Code Style
|
143
|
+
|
144
|
+
- Follow Ruby community standards
|
145
|
+
- Use RuboCop for linting
|
146
|
+
- Write descriptive commit messages
|
147
|
+
- Include tests for new functionality
|
148
|
+
|
149
|
+
### Testing Requirements
|
150
|
+
|
151
|
+
- Maintain >90% test coverage
|
152
|
+
- Include unit tests for all public methods
|
153
|
+
- Test error conditions and edge cases
|
154
|
+
- Use WebMock to stub HTTP requests
|
155
|
+
|
156
|
+
### Documentation
|
157
|
+
|
158
|
+
- Update README.md for user-facing changes
|
159
|
+
- Add inline documentation for complex methods
|
160
|
+
- Include usage examples in docstrings
|
161
|
+
- Update CHANGELOG.md for all changes
|
162
|
+
|
163
|
+
## Debugging
|
164
|
+
|
165
|
+
### Enable Debug Mode
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
# In code
|
169
|
+
Spyglasses.configure do |config|
|
170
|
+
config.debug = true
|
171
|
+
end
|
172
|
+
|
173
|
+
# Via environment
|
174
|
+
export SPYGLASSES_DEBUG=true
|
175
|
+
```
|
176
|
+
|
177
|
+
### Common Issues
|
178
|
+
|
179
|
+
1. **Pattern loading fails**: Check API key and network connectivity
|
180
|
+
2. **Tests fail with real HTTP**: Ensure WebMock stubs are in place
|
181
|
+
3. **Middleware not detecting**: Check user agent patterns and exclusions
|
182
|
+
4. **Performance issues**: Profile pattern matching and API calls
|
183
|
+
|
184
|
+
### Debugging API Issues
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
# Test API connectivity
|
188
|
+
require 'net/http'
|
189
|
+
require 'json'
|
190
|
+
|
191
|
+
uri = URI('https://www.spyglasses.io/api/patterns')
|
192
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
193
|
+
http.use_ssl = true
|
194
|
+
|
195
|
+
request = Net::HTTP::Get.new(uri)
|
196
|
+
request['x-api-key'] = 'your-api-key'
|
197
|
+
|
198
|
+
response = http.request(request)
|
199
|
+
puts "Status: #{response.code}"
|
200
|
+
puts "Body: #{response.body[0..200]}..."
|
201
|
+
```
|
202
|
+
|
203
|
+
## Compatibility
|
204
|
+
|
205
|
+
- **Ruby**: 2.7+ (tested on 2.7, 3.0, 3.1, 3.2, 3.3)
|
206
|
+
- **Rails**: 6.0+ (all versions with Rack 2.0+)
|
207
|
+
- **Rack**: 2.0+
|
208
|
+
- **Other frameworks**: Sinatra, Hanami, Roda, etc.
|
209
|
+
|
210
|
+
## Security Considerations
|
211
|
+
|
212
|
+
- API keys are masked in logs and debug output
|
213
|
+
- No sensitive data is stored in memory longer than necessary
|
214
|
+
- HTTP requests use TLS/SSL for API communication
|
215
|
+
- Input validation prevents regex injection attacks
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in spyglasses.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
gem 'pry', '~> 0.14.0'
|
9
|
+
gem 'pry-byebug', '~> 3.10.0'
|
10
|
+
|
11
|
+
group :development do
|
12
|
+
gem 'guard', '~> 2.18.0'
|
13
|
+
gem 'guard-rspec', '~> 4.7.0'
|
14
|
+
gem 'listen', '~> 3.8.0'
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
spyglasses (1.0.0)
|
5
|
+
json (>= 2.0)
|
6
|
+
rack (>= 2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
addressable (2.8.7)
|
12
|
+
public_suffix (>= 2.0.2, < 7.0)
|
13
|
+
ast (2.4.3)
|
14
|
+
bigdecimal (3.2.2)
|
15
|
+
byebug (11.1.3)
|
16
|
+
coderay (1.1.3)
|
17
|
+
crack (1.0.0)
|
18
|
+
bigdecimal
|
19
|
+
rexml
|
20
|
+
diff-lcs (1.6.2)
|
21
|
+
docile (1.4.1)
|
22
|
+
ffi (1.17.2)
|
23
|
+
ffi (1.17.2-arm64-darwin)
|
24
|
+
ffi (1.17.2-x86_64-darwin)
|
25
|
+
formatador (1.1.0)
|
26
|
+
guard (2.18.1)
|
27
|
+
formatador (>= 0.2.4)
|
28
|
+
listen (>= 2.7, < 4.0)
|
29
|
+
lumberjack (>= 1.0.12, < 2.0)
|
30
|
+
nenv (~> 0.1)
|
31
|
+
notiffany (~> 0.0)
|
32
|
+
pry (>= 0.13.0)
|
33
|
+
shellany (~> 0.0)
|
34
|
+
thor (>= 0.18.1)
|
35
|
+
guard-compat (1.2.1)
|
36
|
+
guard-rspec (4.7.3)
|
37
|
+
guard (~> 2.1)
|
38
|
+
guard-compat (~> 1.1)
|
39
|
+
rspec (>= 2.99.0, < 4.0)
|
40
|
+
hashdiff (1.2.0)
|
41
|
+
json (2.12.2)
|
42
|
+
language_server-protocol (3.17.0.5)
|
43
|
+
lint_roller (1.1.0)
|
44
|
+
listen (3.8.0)
|
45
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
46
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
47
|
+
lumberjack (1.2.10)
|
48
|
+
method_source (1.1.0)
|
49
|
+
nenv (0.3.0)
|
50
|
+
notiffany (0.1.3)
|
51
|
+
nenv (~> 0.1)
|
52
|
+
shellany (~> 0.0)
|
53
|
+
parallel (1.27.0)
|
54
|
+
parser (3.3.8.0)
|
55
|
+
ast (~> 2.4.1)
|
56
|
+
racc
|
57
|
+
prism (1.4.0)
|
58
|
+
pry (0.14.2)
|
59
|
+
coderay (~> 1.1)
|
60
|
+
method_source (~> 1.0)
|
61
|
+
pry-byebug (3.10.1)
|
62
|
+
byebug (~> 11.0)
|
63
|
+
pry (>= 0.13, < 0.15)
|
64
|
+
public_suffix (6.0.2)
|
65
|
+
racc (1.8.1)
|
66
|
+
rack (3.1.16)
|
67
|
+
rack-test (2.2.0)
|
68
|
+
rack (>= 1.3)
|
69
|
+
rainbow (3.1.1)
|
70
|
+
rake (13.3.0)
|
71
|
+
rb-fsevent (0.11.2)
|
72
|
+
rb-inotify (0.11.1)
|
73
|
+
ffi (~> 1.0)
|
74
|
+
regexp_parser (2.10.0)
|
75
|
+
rexml (3.4.1)
|
76
|
+
rspec (3.13.1)
|
77
|
+
rspec-core (~> 3.13.0)
|
78
|
+
rspec-expectations (~> 3.13.0)
|
79
|
+
rspec-mocks (~> 3.13.0)
|
80
|
+
rspec-core (3.13.4)
|
81
|
+
rspec-support (~> 3.13.0)
|
82
|
+
rspec-expectations (3.13.5)
|
83
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
84
|
+
rspec-support (~> 3.13.0)
|
85
|
+
rspec-mocks (3.13.5)
|
86
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
87
|
+
rspec-support (~> 3.13.0)
|
88
|
+
rspec-support (3.13.4)
|
89
|
+
rubocop (1.77.0)
|
90
|
+
json (~> 2.3)
|
91
|
+
language_server-protocol (~> 3.17.0.2)
|
92
|
+
lint_roller (~> 1.1.0)
|
93
|
+
parallel (~> 1.10)
|
94
|
+
parser (>= 3.3.0.2)
|
95
|
+
rainbow (>= 2.2.2, < 4.0)
|
96
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
97
|
+
rubocop-ast (>= 1.45.1, < 2.0)
|
98
|
+
ruby-progressbar (~> 1.7)
|
99
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
100
|
+
rubocop-ast (1.45.1)
|
101
|
+
parser (>= 3.3.7.2)
|
102
|
+
prism (~> 1.4)
|
103
|
+
ruby-progressbar (1.13.0)
|
104
|
+
shellany (0.0.1)
|
105
|
+
simplecov (0.22.0)
|
106
|
+
docile (~> 1.1)
|
107
|
+
simplecov-html (~> 0.11)
|
108
|
+
simplecov_json_formatter (~> 0.1)
|
109
|
+
simplecov-html (0.13.1)
|
110
|
+
simplecov_json_formatter (0.1.4)
|
111
|
+
thor (1.3.2)
|
112
|
+
unicode-display_width (3.1.4)
|
113
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
114
|
+
unicode-emoji (4.0.4)
|
115
|
+
webmock (3.25.1)
|
116
|
+
addressable (>= 2.8.0)
|
117
|
+
crack (>= 0.3.2)
|
118
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
119
|
+
yard (0.9.37)
|
120
|
+
|
121
|
+
PLATFORMS
|
122
|
+
arm64-darwin
|
123
|
+
ruby
|
124
|
+
x86_64-darwin
|
125
|
+
|
126
|
+
DEPENDENCIES
|
127
|
+
bundler (>= 2.0)
|
128
|
+
guard (~> 2.18.0)
|
129
|
+
guard-rspec (~> 4.7.0)
|
130
|
+
listen (~> 3.8.0)
|
131
|
+
pry (~> 0.14.0)
|
132
|
+
pry-byebug (~> 3.10.0)
|
133
|
+
rack-test (~> 2.0)
|
134
|
+
rake (>= 13.0)
|
135
|
+
rspec (~> 3.0)
|
136
|
+
rubocop (~> 1.0)
|
137
|
+
simplecov (~> 0.21)
|
138
|
+
spyglasses!
|
139
|
+
webmock (~> 3.0)
|
140
|
+
yard (~> 0.9)
|
141
|
+
|
142
|
+
BUNDLED WITH
|
143
|
+
2.6.6
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Orchestra AI
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|