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
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Crucible
|
|
4
|
+
module Tools
|
|
5
|
+
# MCP tools for stealth mode management
|
|
6
|
+
module Stealth
|
|
7
|
+
extend Helpers
|
|
8
|
+
|
|
9
|
+
VALID_PROFILES = %w[minimal moderate maximum].freeze
|
|
10
|
+
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
# Returns all stealth tools
|
|
14
|
+
# @param sessions [SessionManager]
|
|
15
|
+
# @param config [Configuration]
|
|
16
|
+
# @return [Array<MCP::Tool>]
|
|
17
|
+
def tools(sessions, config)
|
|
18
|
+
[
|
|
19
|
+
enable_stealth_tool(sessions, config),
|
|
20
|
+
disable_stealth_tool(sessions),
|
|
21
|
+
get_stealth_status_tool(sessions),
|
|
22
|
+
set_stealth_profile_tool(sessions, config)
|
|
23
|
+
]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Tool: Enable stealth mode for a session
|
|
27
|
+
def enable_stealth_tool(sessions, _config)
|
|
28
|
+
MCP::Tool.new(
|
|
29
|
+
name: 'enable_stealth',
|
|
30
|
+
description: 'Enable stealth mode for a browser session. Stealth mode applies various ' \
|
|
31
|
+
'evasion techniques to make the browser appear as a regular user browser ' \
|
|
32
|
+
'to bot detection systems.',
|
|
33
|
+
input_schema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
session: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'Session name',
|
|
39
|
+
default: 'default'
|
|
40
|
+
},
|
|
41
|
+
profile: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
enum: VALID_PROFILES,
|
|
44
|
+
description: 'Stealth profile: minimal (basic evasions), moderate (common evasions), ' \
|
|
45
|
+
'or maximum (all evasions for strictest detection)'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
required: []
|
|
49
|
+
}
|
|
50
|
+
) do |args|
|
|
51
|
+
session = args['session'] || 'default'
|
|
52
|
+
profile = args['profile']&.to_sym
|
|
53
|
+
|
|
54
|
+
sessions.enable_stealth(session, profile: profile)
|
|
55
|
+
|
|
56
|
+
info = sessions.stealth_info(session)
|
|
57
|
+
build_result("Stealth mode enabled for session '#{session}' with profile: #{info[:profile]}")
|
|
58
|
+
rescue Crucible::SessionNotFoundError => e
|
|
59
|
+
build_error(e.message)
|
|
60
|
+
rescue Crucible::Error => e
|
|
61
|
+
build_error(e.message)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Tool: Disable stealth mode for a session
|
|
66
|
+
def disable_stealth_tool(sessions)
|
|
67
|
+
MCP::Tool.new(
|
|
68
|
+
name: 'disable_stealth',
|
|
69
|
+
description: 'Disable stealth mode for a browser session. Note: Already-applied evasions ' \
|
|
70
|
+
'cannot be removed, but this prevents new evasions from being applied.',
|
|
71
|
+
input_schema: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
properties: {
|
|
74
|
+
session: {
|
|
75
|
+
type: 'string',
|
|
76
|
+
description: 'Session name',
|
|
77
|
+
default: 'default'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
required: []
|
|
81
|
+
}
|
|
82
|
+
) do |args|
|
|
83
|
+
session = args['session'] || 'default'
|
|
84
|
+
|
|
85
|
+
sessions.disable_stealth(session)
|
|
86
|
+
|
|
87
|
+
build_result("Stealth mode disabled for session '#{session}'")
|
|
88
|
+
rescue Crucible::SessionNotFoundError => e
|
|
89
|
+
build_error(e.message)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Tool: Get stealth status for a session
|
|
94
|
+
def get_stealth_status_tool(sessions)
|
|
95
|
+
MCP::Tool.new(
|
|
96
|
+
name: 'get_stealth_status',
|
|
97
|
+
description: 'Get the current stealth mode status for a browser session.',
|
|
98
|
+
input_schema: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {
|
|
101
|
+
session: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: 'Session name',
|
|
104
|
+
default: 'default'
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
required: []
|
|
108
|
+
}
|
|
109
|
+
) do |args|
|
|
110
|
+
session = args['session'] || 'default'
|
|
111
|
+
|
|
112
|
+
info = sessions.stealth_info(session)
|
|
113
|
+
|
|
114
|
+
status = {
|
|
115
|
+
session: session,
|
|
116
|
+
stealth_enabled: info[:enabled],
|
|
117
|
+
profile: info[:profile]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
build_result(JSON.pretty_generate(status))
|
|
121
|
+
rescue Crucible::SessionNotFoundError => e
|
|
122
|
+
build_error(e.message)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Tool: Set stealth profile (change profile for existing session)
|
|
127
|
+
def set_stealth_profile_tool(sessions, _config)
|
|
128
|
+
MCP::Tool.new(
|
|
129
|
+
name: 'set_stealth_profile',
|
|
130
|
+
description: 'Change the stealth profile for a session. This enables stealth mode with ' \
|
|
131
|
+
'the new profile if not already enabled.',
|
|
132
|
+
input_schema: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
properties: {
|
|
135
|
+
session: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
description: 'Session name',
|
|
138
|
+
default: 'default'
|
|
139
|
+
},
|
|
140
|
+
profile: {
|
|
141
|
+
type: 'string',
|
|
142
|
+
enum: VALID_PROFILES,
|
|
143
|
+
description: 'Stealth profile: minimal, moderate, or maximum'
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
required: ['profile']
|
|
147
|
+
}
|
|
148
|
+
) do |args|
|
|
149
|
+
session = args['session'] || 'default'
|
|
150
|
+
profile = args['profile']&.to_sym
|
|
151
|
+
|
|
152
|
+
unless VALID_PROFILES.include?(args['profile'])
|
|
153
|
+
raise Crucible::Error, "Invalid profile: #{args['profile']}. Must be one of: #{VALID_PROFILES.join(', ')}"
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
sessions.enable_stealth(session, profile: profile)
|
|
157
|
+
|
|
158
|
+
build_result("Stealth profile set to '#{profile}' for session '#{session}'")
|
|
159
|
+
rescue Crucible::SessionNotFoundError => e
|
|
160
|
+
build_error(e.message)
|
|
161
|
+
rescue Crucible::Error => e
|
|
162
|
+
build_error(e.message)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Crucible
|
|
4
|
+
# Tool registry and loader for MCP browser automation tools
|
|
5
|
+
#
|
|
6
|
+
# Tools are organized by domain:
|
|
7
|
+
# - Navigation: navigate, wait_for, back, forward, refresh
|
|
8
|
+
# - Interaction: click, type, fill_form, select_option, scroll, hover
|
|
9
|
+
# - Extraction: screenshot, get_content, pdf, evaluate, get_url, get_title
|
|
10
|
+
# - Cookies: get_cookies, set_cookies, clear_cookies
|
|
11
|
+
# - Sessions: list_sessions, close_session
|
|
12
|
+
# - Downloads: set_download_path, list_downloads, wait_for_download, clear_downloads
|
|
13
|
+
#
|
|
14
|
+
module Tools
|
|
15
|
+
autoload :Helpers, 'crucible/tools/helpers'
|
|
16
|
+
autoload :Navigation, 'crucible/tools/navigation'
|
|
17
|
+
autoload :Interaction, 'crucible/tools/interaction'
|
|
18
|
+
autoload :Extraction, 'crucible/tools/extraction'
|
|
19
|
+
autoload :Cookies, 'crucible/tools/cookies'
|
|
20
|
+
autoload :Sessions, 'crucible/tools/sessions'
|
|
21
|
+
autoload :Downloads, 'crucible/tools/downloads'
|
|
22
|
+
autoload :Stealth, 'crucible/tools/stealth'
|
|
23
|
+
|
|
24
|
+
class << self
|
|
25
|
+
# Returns all tool definitions for the MCP server
|
|
26
|
+
# @param session_manager [SessionManager] the session manager instance
|
|
27
|
+
# @param config [Configuration] the server configuration
|
|
28
|
+
# @return [Array] array of MCP tool definitions
|
|
29
|
+
def all(session_manager, config)
|
|
30
|
+
[
|
|
31
|
+
*Navigation.tools(session_manager, config),
|
|
32
|
+
*Interaction.tools(session_manager, config),
|
|
33
|
+
*Extraction.tools(session_manager, config),
|
|
34
|
+
*Cookies.tools(session_manager, config),
|
|
35
|
+
*Sessions.tools(session_manager, config),
|
|
36
|
+
*Downloads.tools(session_manager, config),
|
|
37
|
+
*Stealth.tools(session_manager, config)
|
|
38
|
+
]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/crucible.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'crucible/version'
|
|
4
|
+
|
|
5
|
+
# Crucible: MCP server for browser automation using Ferrum/Chrome
|
|
6
|
+
#
|
|
7
|
+
# Provides browser automation tools for AI agents via the Model Context Protocol.
|
|
8
|
+
# Supports multiple named sessions, navigation, screenshots, form interaction,
|
|
9
|
+
# JavaScript evaluation, cookie management, and PDF generation.
|
|
10
|
+
#
|
|
11
|
+
# @example Basic usage
|
|
12
|
+
# Crucible.configure do |config|
|
|
13
|
+
# config.headless = true
|
|
14
|
+
# config.timeout = 30
|
|
15
|
+
# end
|
|
16
|
+
# Crucible.run
|
|
17
|
+
#
|
|
18
|
+
module Crucible
|
|
19
|
+
class Error < StandardError; end
|
|
20
|
+
class SessionNotFoundError < Error; end
|
|
21
|
+
class ElementNotFoundError < Error; end
|
|
22
|
+
class TimeoutError < Error; end
|
|
23
|
+
class BrowserError < Error; end
|
|
24
|
+
|
|
25
|
+
autoload :Configuration, 'crucible/configuration'
|
|
26
|
+
autoload :Server, 'crucible/server'
|
|
27
|
+
autoload :SessionManager, 'crucible/session_manager'
|
|
28
|
+
autoload :Stealth, 'crucible/stealth'
|
|
29
|
+
autoload :Tools, 'crucible/tools'
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
attr_writer :configuration
|
|
33
|
+
|
|
34
|
+
# Returns the current configuration, initializing with defaults if needed
|
|
35
|
+
# @return [Configuration]
|
|
36
|
+
def configuration
|
|
37
|
+
@configuration ||= Configuration.new
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Yields the configuration for modification
|
|
41
|
+
# @yield [Configuration] the configuration instance
|
|
42
|
+
# @return [Configuration]
|
|
43
|
+
def configure
|
|
44
|
+
yield(configuration) if block_given?
|
|
45
|
+
configuration
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Starts the MCP server with the given options
|
|
49
|
+
# @param options [Hash] configuration overrides
|
|
50
|
+
def run(**options)
|
|
51
|
+
config = options.empty? ? configuration : configuration.merge(options)
|
|
52
|
+
Server.new(config).run
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Resets configuration to defaults (mainly for testing)
|
|
56
|
+
def reset!
|
|
57
|
+
@configuration = nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: crucible
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Josh Frye
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ferrum
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mcp
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rake
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: rspec
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rubocop
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rubocop-rake
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rubocop-rspec
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: simplecov
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - ">="
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - ">="
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0'
|
|
124
|
+
description: |
|
|
125
|
+
An MCP (Model Context Protocol) server that provides browser automation tools
|
|
126
|
+
for AI agents using Ferrum and headless Chrome. Features 25 tools covering
|
|
127
|
+
navigation, screenshots, form interaction, JavaScript evaluation, cookies,
|
|
128
|
+
file downloads, and multi-session management.
|
|
129
|
+
email:
|
|
130
|
+
- me@joshfrye.dev
|
|
131
|
+
executables:
|
|
132
|
+
- crucible
|
|
133
|
+
extensions: []
|
|
134
|
+
extra_rdoc_files: []
|
|
135
|
+
files:
|
|
136
|
+
- ".rspec"
|
|
137
|
+
- ".rubocop.yml"
|
|
138
|
+
- Gemfile
|
|
139
|
+
- LICENSE
|
|
140
|
+
- README.md
|
|
141
|
+
- Rakefile
|
|
142
|
+
- TESTING.md
|
|
143
|
+
- config.sample.yml
|
|
144
|
+
- crucible.gemspec
|
|
145
|
+
- exe/crucible
|
|
146
|
+
- lib/crucible.rb
|
|
147
|
+
- lib/crucible/configuration.rb
|
|
148
|
+
- lib/crucible/server.rb
|
|
149
|
+
- lib/crucible/session_manager.rb
|
|
150
|
+
- lib/crucible/stealth.rb
|
|
151
|
+
- lib/crucible/stealth/evasions/chrome_app.js
|
|
152
|
+
- lib/crucible/stealth/evasions/chrome_csi.js
|
|
153
|
+
- lib/crucible/stealth/evasions/chrome_load_times.js
|
|
154
|
+
- lib/crucible/stealth/evasions/chrome_runtime.js
|
|
155
|
+
- lib/crucible/stealth/evasions/iframe_content_window.js
|
|
156
|
+
- lib/crucible/stealth/evasions/media_codecs.js
|
|
157
|
+
- lib/crucible/stealth/evasions/navigator_hardware_concurrency.js
|
|
158
|
+
- lib/crucible/stealth/evasions/navigator_languages.js
|
|
159
|
+
- lib/crucible/stealth/evasions/navigator_permissions.js
|
|
160
|
+
- lib/crucible/stealth/evasions/navigator_plugins.js
|
|
161
|
+
- lib/crucible/stealth/evasions/navigator_vendor.js
|
|
162
|
+
- lib/crucible/stealth/evasions/navigator_webdriver.js
|
|
163
|
+
- lib/crucible/stealth/evasions/webgl_vendor.js
|
|
164
|
+
- lib/crucible/stealth/evasions/window_outerdimensions.js
|
|
165
|
+
- lib/crucible/stealth/utils.js
|
|
166
|
+
- lib/crucible/tools.rb
|
|
167
|
+
- lib/crucible/tools/cookies.rb
|
|
168
|
+
- lib/crucible/tools/downloads.rb
|
|
169
|
+
- lib/crucible/tools/extraction.rb
|
|
170
|
+
- lib/crucible/tools/helpers.rb
|
|
171
|
+
- lib/crucible/tools/interaction.rb
|
|
172
|
+
- lib/crucible/tools/navigation.rb
|
|
173
|
+
- lib/crucible/tools/sessions.rb
|
|
174
|
+
- lib/crucible/tools/stealth.rb
|
|
175
|
+
- lib/crucible/version.rb
|
|
176
|
+
homepage: https://github.com/joshfng/crucible
|
|
177
|
+
licenses:
|
|
178
|
+
- MIT
|
|
179
|
+
metadata:
|
|
180
|
+
homepage_uri: https://github.com/joshfng/crucible
|
|
181
|
+
source_code_uri: https://github.com/joshfng/crucible
|
|
182
|
+
changelog_uri: https://github.com/joshfng/crucible/blob/main/CHANGELOG.md
|
|
183
|
+
rubygems_mfa_required: 'true'
|
|
184
|
+
rdoc_options: []
|
|
185
|
+
require_paths:
|
|
186
|
+
- lib
|
|
187
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
188
|
+
requirements:
|
|
189
|
+
- - ">="
|
|
190
|
+
- !ruby/object:Gem::Version
|
|
191
|
+
version: 3.2.0
|
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
|
+
requirements:
|
|
194
|
+
- - ">="
|
|
195
|
+
- !ruby/object:Gem::Version
|
|
196
|
+
version: '0'
|
|
197
|
+
requirements: []
|
|
198
|
+
rubygems_version: 4.0.3
|
|
199
|
+
specification_version: 4
|
|
200
|
+
summary: MCP server for browser automation using Ferrum/Chrome
|
|
201
|
+
test_files: []
|