crucible 0.1.2
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/.rubocop.yml +102 -0
- data/Gemfile +10 -0
- data/LICENSE +21 -0
- data/README.md +366 -0
- data/Rakefile +23 -0
- data/TESTING.md +319 -0
- data/config.sample.yml +48 -0
- data/crucible.gemspec +48 -0
- data/exe/crucible +122 -0
- data/lib/crucible/configuration.rb +212 -0
- data/lib/crucible/server.rb +123 -0
- data/lib/crucible/session_manager.rb +209 -0
- data/lib/crucible/stealth/evasions/chrome_app.js +75 -0
- data/lib/crucible/stealth/evasions/chrome_csi.js +33 -0
- data/lib/crucible/stealth/evasions/chrome_load_times.js +44 -0
- data/lib/crucible/stealth/evasions/chrome_runtime.js +190 -0
- data/lib/crucible/stealth/evasions/iframe_content_window.js +101 -0
- data/lib/crucible/stealth/evasions/media_codecs.js +65 -0
- data/lib/crucible/stealth/evasions/navigator_hardware_concurrency.js +18 -0
- data/lib/crucible/stealth/evasions/navigator_languages.js +18 -0
- data/lib/crucible/stealth/evasions/navigator_permissions.js +53 -0
- data/lib/crucible/stealth/evasions/navigator_plugins.js +261 -0
- data/lib/crucible/stealth/evasions/navigator_vendor.js +18 -0
- data/lib/crucible/stealth/evasions/navigator_webdriver.js +16 -0
- data/lib/crucible/stealth/evasions/webgl_vendor.js +43 -0
- data/lib/crucible/stealth/evasions/window_outerdimensions.js +18 -0
- data/lib/crucible/stealth/utils.js +266 -0
- data/lib/crucible/stealth.rb +213 -0
- data/lib/crucible/tools/cookies.rb +206 -0
- data/lib/crucible/tools/downloads.rb +273 -0
- data/lib/crucible/tools/extraction.rb +335 -0
- data/lib/crucible/tools/helpers.rb +46 -0
- data/lib/crucible/tools/interaction.rb +355 -0
- data/lib/crucible/tools/navigation.rb +181 -0
- data/lib/crucible/tools/sessions.rb +85 -0
- data/lib/crucible/tools/stealth.rb +167 -0
- data/lib/crucible/tools.rb +42 -0
- data/lib/crucible/version.rb +5 -0
- data/lib/crucible.rb +60 -0
- metadata +201 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e2c04da14bee7961c1ced708e2328f25a0b35073f5328738eb18b7837a743ce3
|
|
4
|
+
data.tar.gz: ad94610d74d10ae74132690247b6b7801a622323d5b45c256aefd380b03328c2
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 84058ca5a1bdec6bb411eff6c36335a254dcabc10055ae707d686a7dd2f179e9c165dd49a4c80c2ce22d0d2c18f38d6e8484d446e22f3b8b0fb84bb55cdd19b5
|
|
7
|
+
data.tar.gz: 9f5fcc4f0d4fd50b343cd3fc1be9be2e523620fb92324c11c29675bc4986b8fe039318c69109862ff754ce475cc13de3cb37a711d4a1a41c3388df793f33b5fe
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# RuboCop configuration for Crucible
|
|
2
|
+
|
|
3
|
+
plugins:
|
|
4
|
+
- rubocop-rake
|
|
5
|
+
- rubocop-rspec
|
|
6
|
+
|
|
7
|
+
AllCops:
|
|
8
|
+
NewCops: enable
|
|
9
|
+
TargetRubyVersion: 3.2
|
|
10
|
+
Exclude:
|
|
11
|
+
- 'vendor/**/*'
|
|
12
|
+
- 'tmp/**/*'
|
|
13
|
+
|
|
14
|
+
# Gemspec - development dependencies in gemspec is acceptable
|
|
15
|
+
Gemspec/DevelopmentDependencies:
|
|
16
|
+
Enabled: false
|
|
17
|
+
|
|
18
|
+
# Metrics - tool methods are inherently verbose due to MCP schema definitions
|
|
19
|
+
Metrics/BlockLength:
|
|
20
|
+
Exclude:
|
|
21
|
+
- 'spec/**/*'
|
|
22
|
+
- '*.gemspec'
|
|
23
|
+
- 'exe/*'
|
|
24
|
+
- 'lib/crucible/tools/**/*'
|
|
25
|
+
Max: 50
|
|
26
|
+
|
|
27
|
+
Metrics/ClassLength:
|
|
28
|
+
Max: 200
|
|
29
|
+
Exclude:
|
|
30
|
+
- 'lib/crucible/tools/**/*'
|
|
31
|
+
|
|
32
|
+
Metrics/ModuleLength:
|
|
33
|
+
Max: 200
|
|
34
|
+
Exclude:
|
|
35
|
+
- 'lib/crucible/tools/**/*'
|
|
36
|
+
|
|
37
|
+
Metrics/MethodLength:
|
|
38
|
+
Max: 25
|
|
39
|
+
Exclude:
|
|
40
|
+
- 'lib/crucible/tools/**/*'
|
|
41
|
+
|
|
42
|
+
Metrics/AbcSize:
|
|
43
|
+
Max: 35
|
|
44
|
+
Exclude:
|
|
45
|
+
- 'lib/crucible/tools/**/*'
|
|
46
|
+
- 'lib/crucible/configuration.rb'
|
|
47
|
+
|
|
48
|
+
Metrics/CyclomaticComplexity:
|
|
49
|
+
Max: 15
|
|
50
|
+
Exclude:
|
|
51
|
+
- 'lib/crucible/configuration.rb'
|
|
52
|
+
- 'lib/crucible/tools/**/*'
|
|
53
|
+
|
|
54
|
+
Metrics/PerceivedComplexity:
|
|
55
|
+
Max: 15
|
|
56
|
+
Exclude:
|
|
57
|
+
- 'lib/crucible/configuration.rb'
|
|
58
|
+
- 'lib/crucible/tools/**/*'
|
|
59
|
+
|
|
60
|
+
Metrics/ParameterLists:
|
|
61
|
+
Max: 8
|
|
62
|
+
|
|
63
|
+
# Naming - these aren't predicate methods or accessor methods
|
|
64
|
+
Naming/PredicateMethod:
|
|
65
|
+
Exclude:
|
|
66
|
+
- 'lib/crucible/configuration.rb'
|
|
67
|
+
- 'lib/crucible/session_manager.rb'
|
|
68
|
+
|
|
69
|
+
Naming/AccessorMethodName:
|
|
70
|
+
Exclude:
|
|
71
|
+
- 'lib/crucible/tools/**/*'
|
|
72
|
+
|
|
73
|
+
# Lint - duplicate rescue branches are intentional for different error types
|
|
74
|
+
Lint/DuplicateBranch:
|
|
75
|
+
Exclude:
|
|
76
|
+
- 'lib/crucible/tools/**/*'
|
|
77
|
+
|
|
78
|
+
# RSpec - tests need flexibility
|
|
79
|
+
RSpec/MultipleExpectations:
|
|
80
|
+
Max: 10
|
|
81
|
+
|
|
82
|
+
RSpec/ExampleLength:
|
|
83
|
+
Max: 70
|
|
84
|
+
Exclude:
|
|
85
|
+
- 'spec/e2e/**/*'
|
|
86
|
+
|
|
87
|
+
RSpec/NestedGroups:
|
|
88
|
+
Max: 4
|
|
89
|
+
|
|
90
|
+
RSpec/VerifiedDoubles:
|
|
91
|
+
Enabled: false
|
|
92
|
+
|
|
93
|
+
RSpec/SpecFilePathFormat:
|
|
94
|
+
Enabled: false
|
|
95
|
+
|
|
96
|
+
RSpec/DescribeClass:
|
|
97
|
+
Exclude:
|
|
98
|
+
- 'spec/e2e/**/*'
|
|
99
|
+
|
|
100
|
+
RSpec/BeforeAfterAll:
|
|
101
|
+
Exclude:
|
|
102
|
+
- 'spec/e2e/**/*'
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Josh Frye
|
|
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.
|
data/README.md
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Crucible
|
|
2
|
+
|
|
3
|
+
A Ruby MCP (Model Context Protocol) server for browser automation using [Ferrum](https://github.com/rubycdp/ferrum) and headless Chrome. Provides 29 tools that AI agents can use to control browsers, with built-in stealth mode to evade bot detection.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/joshfng/crucible.git
|
|
9
|
+
cd crucible
|
|
10
|
+
bundle install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Running the Server
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Run with defaults (headless, 1280x720 viewport, 30s timeout)
|
|
19
|
+
./exe/crucible
|
|
20
|
+
|
|
21
|
+
# Run with visible browser
|
|
22
|
+
./exe/crucible --no-headless
|
|
23
|
+
|
|
24
|
+
# Full options
|
|
25
|
+
./exe/crucible \
|
|
26
|
+
--no-headless \
|
|
27
|
+
--width 1920 \
|
|
28
|
+
--height 1080 \
|
|
29
|
+
--timeout 60 \
|
|
30
|
+
--chrome /usr/bin/chromium \
|
|
31
|
+
--error-level debug
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### CLI Options
|
|
35
|
+
|
|
36
|
+
| Option | Description | Default |
|
|
37
|
+
| --------------------------- | ------------------------------------------- | ----------- |
|
|
38
|
+
| `-c, --config FILE` | Path to YAML configuration file | auto-detect |
|
|
39
|
+
| `--[no-]headless` | Run browser in headless mode | `true` |
|
|
40
|
+
| `-w, --width WIDTH` | Viewport width in pixels | `1280` |
|
|
41
|
+
| `-h, --height HEIGHT` | Viewport height in pixels | `720` |
|
|
42
|
+
| `--chrome PATH` | Path to Chrome/Chromium executable | auto-detect |
|
|
43
|
+
| `-t, --timeout SECONDS` | Default timeout in seconds | `30` |
|
|
44
|
+
| `--error-level LEVEL` | Logging level (debug/info/warn/error) | `warn` |
|
|
45
|
+
| `--screenshot-format FMT` | Default screenshot format (png/jpeg/base64) | `png` |
|
|
46
|
+
| `--content-format FMT` | Default content format (html/text) | `html` |
|
|
47
|
+
| `--[no-]stealth` | Enable/disable stealth mode | `true` |
|
|
48
|
+
| `--stealth-profile PROFILE` | Stealth profile (minimal/moderate/maximum) | `moderate` |
|
|
49
|
+
| `--stealth-locale LOCALE` | Browser locale for stealth mode | `en-US,en` |
|
|
50
|
+
|
|
51
|
+
### Claude Code Integration
|
|
52
|
+
|
|
53
|
+
Add to your Claude Code MCP settings (`~/.claude/settings.json`):
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"crucible": {
|
|
59
|
+
"command": "ruby",
|
|
60
|
+
"args": [
|
|
61
|
+
"-I",
|
|
62
|
+
"/path/to/crucible/lib",
|
|
63
|
+
"/path/to/crucible/exe/crucible"
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Tools
|
|
71
|
+
|
|
72
|
+
### Navigation
|
|
73
|
+
|
|
74
|
+
| Tool | Description |
|
|
75
|
+
| ---------- | ----------------------------- |
|
|
76
|
+
| `navigate` | Navigate browser to a URL |
|
|
77
|
+
| `wait_for` | Wait for an element to appear |
|
|
78
|
+
| `back` | Navigate back in history |
|
|
79
|
+
| `forward` | Navigate forward in history |
|
|
80
|
+
| `refresh` | Refresh the current page |
|
|
81
|
+
|
|
82
|
+
### Interaction
|
|
83
|
+
|
|
84
|
+
| Tool | Description |
|
|
85
|
+
| --------------- | ----------------------------------------------------- |
|
|
86
|
+
| `click` | Click an element (supports double-click, right-click) |
|
|
87
|
+
| `type` | Type text into an input (with optional clear/submit) |
|
|
88
|
+
| `fill_form` | Fill multiple form fields at once |
|
|
89
|
+
| `select_option` | Select option from dropdown |
|
|
90
|
+
| `scroll` | Scroll page or element into view |
|
|
91
|
+
| `hover` | Hover over an element |
|
|
92
|
+
|
|
93
|
+
### Extraction
|
|
94
|
+
|
|
95
|
+
| Tool | Description |
|
|
96
|
+
| ------------- | -------------------------------------------------------------------------------- |
|
|
97
|
+
| `screenshot` | Take screenshot (viewport, full page, or element); save to file or return base64 |
|
|
98
|
+
| `get_content` | Get page content (HTML or text) |
|
|
99
|
+
| `pdf` | Generate PDF of the page; save to file or return base64 |
|
|
100
|
+
| `evaluate` | Execute JavaScript and return result |
|
|
101
|
+
| `get_url` | Get current page URL |
|
|
102
|
+
| `get_title` | Get current page title |
|
|
103
|
+
|
|
104
|
+
### Cookies
|
|
105
|
+
|
|
106
|
+
| Tool | Description |
|
|
107
|
+
| --------------- | ---------------------------------- |
|
|
108
|
+
| `get_cookies` | Get all cookies or specific cookie |
|
|
109
|
+
| `set_cookies` | Set one or more cookies |
|
|
110
|
+
| `clear_cookies` | Clear all or specific cookies |
|
|
111
|
+
|
|
112
|
+
### Sessions
|
|
113
|
+
|
|
114
|
+
| Tool | Description |
|
|
115
|
+
| --------------- | -------------------------------- |
|
|
116
|
+
| `list_sessions` | List all active browser sessions |
|
|
117
|
+
| `close_session` | Close a session or all sessions |
|
|
118
|
+
|
|
119
|
+
### Downloads
|
|
120
|
+
|
|
121
|
+
| Tool | Description |
|
|
122
|
+
| ------------------- | ------------------------------------------------- |
|
|
123
|
+
| `set_download_path` | Set the directory for downloads |
|
|
124
|
+
| `wait_for_download` | Wait for a download to complete |
|
|
125
|
+
| `list_downloads` | List all tracked downloads |
|
|
126
|
+
| `clear_downloads` | Clear tracked downloads (optionally delete files) |
|
|
127
|
+
|
|
128
|
+
### Stealth
|
|
129
|
+
|
|
130
|
+
| Tool | Description |
|
|
131
|
+
| --------------------- | ----------------------------------------------------- |
|
|
132
|
+
| `enable_stealth` | Enable stealth mode for a session |
|
|
133
|
+
| `disable_stealth` | Disable stealth mode for a session |
|
|
134
|
+
| `get_stealth_status` | Get stealth mode status for a session |
|
|
135
|
+
| `set_stealth_profile` | Change the stealth profile (minimal/moderate/maximum) |
|
|
136
|
+
|
|
137
|
+
## Sessions
|
|
138
|
+
|
|
139
|
+
All tools accept an optional `session` parameter to manage multiple independent browser instances:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
# These run in separate browsers
|
|
143
|
+
navigate(session: "login-flow", url: "https://example.com/login")
|
|
144
|
+
navigate(session: "signup-flow", url: "https://example.com/signup")
|
|
145
|
+
|
|
146
|
+
# List active sessions
|
|
147
|
+
list_sessions()
|
|
148
|
+
# => { "count": 2, "sessions": ["login-flow", "signup-flow"] }
|
|
149
|
+
|
|
150
|
+
# Close a specific session
|
|
151
|
+
close_session(session: "login-flow")
|
|
152
|
+
|
|
153
|
+
# Close all sessions
|
|
154
|
+
close_session(all: true)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Sessions are created automatically on first use and persist until explicitly closed.
|
|
158
|
+
|
|
159
|
+
## Example Workflows
|
|
160
|
+
|
|
161
|
+
### Basic Navigation
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
navigate(url: "https://example.com")
|
|
165
|
+
wait_for(selector: ".content")
|
|
166
|
+
get_content(format: "text")
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Form Submission
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
navigate(url: "https://example.com/login")
|
|
173
|
+
type(selector: "#email", text: "user@example.com")
|
|
174
|
+
type(selector: "#password", text: "secret123")
|
|
175
|
+
click(selector: "button[type=submit]")
|
|
176
|
+
wait_for(selector: ".dashboard")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Screenshots & PDFs
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
# Viewport screenshot (returns base64)
|
|
183
|
+
screenshot()
|
|
184
|
+
|
|
185
|
+
# Full page screenshot
|
|
186
|
+
screenshot(full_page: true)
|
|
187
|
+
|
|
188
|
+
# Element screenshot
|
|
189
|
+
screenshot(selector: ".hero-image")
|
|
190
|
+
|
|
191
|
+
# Save to file
|
|
192
|
+
screenshot(path: "/tmp/page.png")
|
|
193
|
+
screenshot(format: "jpeg", quality: 90, path: "/tmp/page.jpg")
|
|
194
|
+
|
|
195
|
+
# PDF generation
|
|
196
|
+
pdf() # Returns base64
|
|
197
|
+
pdf(path: "/tmp/page.pdf") # Save to file
|
|
198
|
+
pdf(format: "Letter", landscape: true) # Custom format
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### JavaScript Execution
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
# Get page dimensions
|
|
205
|
+
evaluate(expression: "[window.innerWidth, window.innerHeight]")
|
|
206
|
+
|
|
207
|
+
# Scroll to top
|
|
208
|
+
evaluate(expression: "window.scrollTo(0, 0)")
|
|
209
|
+
|
|
210
|
+
# Get element count
|
|
211
|
+
evaluate(expression: "document.querySelectorAll('a').length")
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### File Downloads
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
# Set download directory
|
|
218
|
+
set_download_path(path: "/tmp/downloads")
|
|
219
|
+
|
|
220
|
+
# Click download link and wait
|
|
221
|
+
click(selector: "a.download-btn")
|
|
222
|
+
wait_for_download(timeout: 30)
|
|
223
|
+
|
|
224
|
+
# List tracked downloads (persists across navigation)
|
|
225
|
+
list_downloads()
|
|
226
|
+
|
|
227
|
+
# Clear tracking and delete files
|
|
228
|
+
clear_downloads(delete_files: true)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Stealth Mode
|
|
232
|
+
|
|
233
|
+
Stealth mode applies various evasion techniques to make headless Chrome appear as a regular browser to bot detection systems. It is enabled by default with the "moderate" profile.
|
|
234
|
+
|
|
235
|
+
### Stealth Profiles
|
|
236
|
+
|
|
237
|
+
| Profile | Description |
|
|
238
|
+
| ---------- | ------------------------------------------------------- |
|
|
239
|
+
| `minimal` | Basic evasions (navigator.webdriver, window dimensions) |
|
|
240
|
+
| `moderate` | Common evasions for most use cases (default) |
|
|
241
|
+
| `maximum` | All evasions for strictest bot detection |
|
|
242
|
+
|
|
243
|
+
### Evasions Applied
|
|
244
|
+
|
|
245
|
+
The stealth module includes evasions ported from [puppeteer-extra](https://github.com/berstend/puppeteer-extra):
|
|
246
|
+
|
|
247
|
+
- `navigator.webdriver` - Remove the webdriver flag
|
|
248
|
+
- `chrome.app` - Mock the chrome.app object
|
|
249
|
+
- `chrome.csi` - Mock the chrome.csi function
|
|
250
|
+
- `chrome.loadTimes` - Mock chrome.loadTimes
|
|
251
|
+
- `chrome.runtime` - Mock chrome.runtime for extensions
|
|
252
|
+
- `navigator.vendor` - Override navigator.vendor
|
|
253
|
+
- `navigator.languages` - Match Accept-Language header
|
|
254
|
+
- `navigator.plugins` - Mock plugins and mimeTypes
|
|
255
|
+
- `navigator.permissions` - Fix Notification.permission
|
|
256
|
+
- `navigator.hardwareConcurrency` - Set realistic core count
|
|
257
|
+
- `webgl.vendor` - Fix WebGL vendor/renderer
|
|
258
|
+
- `media.codecs` - Report support for proprietary codecs
|
|
259
|
+
- `iframe.contentWindow` - Fix iframe detection
|
|
260
|
+
- `window.outerdimensions` - Fix outerWidth/outerHeight
|
|
261
|
+
- User-Agent override - Strip "Headless" and fix platform
|
|
262
|
+
|
|
263
|
+
### Runtime Control
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
# Check stealth status
|
|
267
|
+
get_stealth_status(session: "default")
|
|
268
|
+
|
|
269
|
+
# Enable with maximum protection
|
|
270
|
+
enable_stealth(session: "default", profile: "maximum")
|
|
271
|
+
|
|
272
|
+
# Disable stealth (already-applied evasions remain)
|
|
273
|
+
disable_stealth(session: "default")
|
|
274
|
+
|
|
275
|
+
# Change profile
|
|
276
|
+
set_stealth_profile(session: "default", profile: "minimal")
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Configuration File
|
|
280
|
+
|
|
281
|
+
Create `~/.config/crucible/config.yml`:
|
|
282
|
+
|
|
283
|
+
```yaml
|
|
284
|
+
browser:
|
|
285
|
+
headless: true
|
|
286
|
+
window_size: [1280, 720]
|
|
287
|
+
|
|
288
|
+
stealth:
|
|
289
|
+
enabled: true
|
|
290
|
+
profile: moderate
|
|
291
|
+
locale: "en-US,en"
|
|
292
|
+
|
|
293
|
+
server:
|
|
294
|
+
log_level: info
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Project Structure
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
crucible/
|
|
301
|
+
├── exe/crucible # CLI executable
|
|
302
|
+
├── crucible.gemspec # Gem specification
|
|
303
|
+
├── Gemfile # Dependencies
|
|
304
|
+
├── Rakefile # Build tasks
|
|
305
|
+
├── lib/
|
|
306
|
+
│ ├── crucible.rb # Main module
|
|
307
|
+
│ └── crucible/
|
|
308
|
+
│ ├── version.rb # Version constant
|
|
309
|
+
│ ├── configuration.rb # Config with YAML support
|
|
310
|
+
│ ├── session_manager.rb # Multi-session management
|
|
311
|
+
│ ├── server.rb # MCP server setup
|
|
312
|
+
│ ├── stealth.rb # Stealth mode module
|
|
313
|
+
│ ├── stealth/
|
|
314
|
+
│ │ ├── utils.js # Stealth utilities
|
|
315
|
+
│ │ └── evasions/ # Individual evasion scripts
|
|
316
|
+
│ └── tools/
|
|
317
|
+
│ ├── helpers.rb # Shared utilities
|
|
318
|
+
│ ├── navigation.rb # Navigation tools
|
|
319
|
+
│ ├── interaction.rb # Interaction tools
|
|
320
|
+
│ ├── extraction.rb # Extraction tools
|
|
321
|
+
│ ├── cookies.rb # Cookie tools
|
|
322
|
+
│ ├── sessions.rb # Session tools
|
|
323
|
+
│ ├── downloads.rb # Download tools
|
|
324
|
+
│ └── stealth.rb # Stealth control tools
|
|
325
|
+
└── spec/ # RSpec tests
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Development
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Run tests
|
|
332
|
+
bundle exec rspec
|
|
333
|
+
|
|
334
|
+
# Run linter
|
|
335
|
+
bundle exec rubocop
|
|
336
|
+
|
|
337
|
+
# Interactive console
|
|
338
|
+
bundle exec rake console
|
|
339
|
+
|
|
340
|
+
# Run server in development
|
|
341
|
+
bundle exec rake server
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Releasing
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
bin/release 0.2.0
|
|
348
|
+
git push origin main --tags
|
|
349
|
+
gh release create v0.2.0 --generate-notes
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
The release workflow automatically publishes to RubyGems.
|
|
353
|
+
|
|
354
|
+
**Setup**: Add `RUBYGEMS_API_KEY` to repository secrets.
|
|
355
|
+
|
|
356
|
+
## Requirements
|
|
357
|
+
|
|
358
|
+
- Ruby >= 3.2.0
|
|
359
|
+
- Chrome or Chromium browser
|
|
360
|
+
- Dependencies:
|
|
361
|
+
- `ferrum` ~> 0.15
|
|
362
|
+
- `mcp` ~> 0.4
|
|
363
|
+
|
|
364
|
+
## License
|
|
365
|
+
|
|
366
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
require 'rubocop/rake_task'
|
|
6
|
+
|
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
8
|
+
RuboCop::RakeTask.new
|
|
9
|
+
|
|
10
|
+
task default: %i[spec rubocop]
|
|
11
|
+
|
|
12
|
+
desc 'Run the MCP server'
|
|
13
|
+
task :server do
|
|
14
|
+
exec 'ruby', '-I', 'lib', 'exe/crucible'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc 'Open an interactive console'
|
|
18
|
+
task :console do
|
|
19
|
+
require 'irb'
|
|
20
|
+
require_relative 'lib/crucible'
|
|
21
|
+
ARGV.clear
|
|
22
|
+
IRB.start(__FILE__)
|
|
23
|
+
end
|