pwn 0.5.752 → 0.5.754
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/Gemfile +2 -2
- data/lib/pwn/ai/anthropic.rb +73 -1
- data/lib/pwn/plugins/repl/ai_console.rb +3 -3
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/ai/anthropic_spec.rb +48 -0
- data/spec/lib/pwn/plugins/repl/ai_console_spec.rb +12 -8
- data/third_party/pwn_rdoc.jsonl +4 -0
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e01b8e88574a241d780acc3e2c4d70a7e5c07fb1e9e17fa709363a4bfcbc7898
|
|
4
|
+
data.tar.gz: f50a1f5f35d25f300c396678edb5daa8119f4fca9e1567d71652c7f45bcc1dcb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c34deaa7b6835b37cacb76a2863cb0759b4dc727301692014702468aa3d4a04ddc1c76fda3893005f58071b9060768ade05401dbbae1cac2fc3dbfc99bcfa9f0
|
|
7
|
+
data.tar.gz: de481a34a2b3776fa8003094618af168f6a33341fd236e14daa3247694e8e703e0eddb15ea74556e9bd4814a14a3187d48f51c18be90094f1bd4c83ddcd364b8
|
data/Gemfile
CHANGED
|
@@ -20,7 +20,7 @@ gem 'base32', '0.3.4'
|
|
|
20
20
|
gem 'bitcoin-ruby', '0.0.20'
|
|
21
21
|
gem 'brakeman', '8.0.6'
|
|
22
22
|
gem 'bson', '5.2.0'
|
|
23
|
-
gem 'bundler', '>=4.0.
|
|
23
|
+
gem 'bundler', '>=4.0.22'
|
|
24
24
|
gem 'bundler-audit', '>=0.9.3'
|
|
25
25
|
gem 'bunny', '3.4.0'
|
|
26
26
|
gem 'colorize', '1.1.0'
|
|
@@ -57,7 +57,7 @@ gem 'msfrpc-client', '1.1.2'
|
|
|
57
57
|
gem 'netaddr', '2.0.6'
|
|
58
58
|
gem 'net-ldap', '0.20.0'
|
|
59
59
|
gem 'net-openvpn', '0.8.7'
|
|
60
|
-
gem 'net-smtp', '0.5.
|
|
60
|
+
gem 'net-smtp', '0.5.2'
|
|
61
61
|
gem 'nexpose', '7.3.0'
|
|
62
62
|
gem 'nokogiri', '1.19.4'
|
|
63
63
|
gem 'nokogiri-diff', '0.3.0'
|
data/lib/pwn/ai/anthropic.rb
CHANGED
|
@@ -575,7 +575,7 @@ module PWN
|
|
|
575
575
|
{
|
|
576
576
|
name: fn[:name] || fn['name'],
|
|
577
577
|
description: fn[:description] || fn['description'],
|
|
578
|
-
input_schema: fn[:parameters] || fn['parameters']
|
|
578
|
+
input_schema: anthropic_input_schema(schema: fn[:parameters] || fn['parameters'])
|
|
579
579
|
}
|
|
580
580
|
end
|
|
581
581
|
http_body[:tool_choice] = anth_tool_choice(choice: opts[:tool_choice]) if opts[:tool_choice]
|
|
@@ -598,6 +598,78 @@ module PWN
|
|
|
598
598
|
raise e
|
|
599
599
|
end
|
|
600
600
|
|
|
601
|
+
# Anthropic rejects oneOf, allOf, and anyOf at the root of input_schema.
|
|
602
|
+
# Return a deep copy with those root keys removed and branch properties merged.
|
|
603
|
+
# Nested combinators and the caller's schema stay unchanged.
|
|
604
|
+
private_class_method def self.anthropic_input_schema(opts = {})
|
|
605
|
+
schema = opts[:schema]
|
|
606
|
+
return { type: 'object', properties: {} } unless schema.is_a?(Hash)
|
|
607
|
+
|
|
608
|
+
copy = json_copy(value: schema)
|
|
609
|
+
notes = []
|
|
610
|
+
%w[anyOf oneOf allOf].each do |name|
|
|
611
|
+
key = anthropic_schema_key(schema: copy, name: name)
|
|
612
|
+
next unless key
|
|
613
|
+
|
|
614
|
+
Array(copy.delete(key)).each do |branch|
|
|
615
|
+
next unless branch.is_a?(Hash)
|
|
616
|
+
|
|
617
|
+
anthropic_schema_notes(branch: branch, notes: notes)
|
|
618
|
+
props = branch[:properties] || branch['properties']
|
|
619
|
+
next unless props.is_a?(Hash)
|
|
620
|
+
|
|
621
|
+
dest = copy.key?('properties') ? 'properties' : :properties
|
|
622
|
+
copy[dest] = {} unless copy[dest].is_a?(Hash)
|
|
623
|
+
props.each { |prop, spec| copy[dest][prop] = spec unless copy[dest].key?(prop) }
|
|
624
|
+
end
|
|
625
|
+
end
|
|
626
|
+
copy[:type] = 'object' unless copy.key?(:type) || copy.key?('type')
|
|
627
|
+
copy[:properties] = {} unless copy.key?(:properties) || copy.key?('properties')
|
|
628
|
+
unless notes.empty?
|
|
629
|
+
note = "One of these field sets is required: #{notes.uniq.join('; ')}."
|
|
630
|
+
copy[:description] = [copy[:description] || copy['description'], note].compact.reject { |part| part.to_s.empty? }.join(' ')
|
|
631
|
+
copy.delete('description')
|
|
632
|
+
end
|
|
633
|
+
copy
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
private_class_method def self.anthropic_schema_notes(opts = {})
|
|
637
|
+
branch = opts[:branch]
|
|
638
|
+
notes = opts[:notes]
|
|
639
|
+
return notes unless branch.is_a?(Hash) && notes.is_a?(Array)
|
|
640
|
+
|
|
641
|
+
required = branch[:required] || branch['required']
|
|
642
|
+
notes << required.join('+') if required.is_a?(Array) && required.any?
|
|
643
|
+
%w[anyOf oneOf allOf].each do |name|
|
|
644
|
+
key = anthropic_schema_key(schema: branch, name: name)
|
|
645
|
+
next unless key
|
|
646
|
+
|
|
647
|
+
Array(branch[key]).each { |child| anthropic_schema_notes(branch: child, notes: notes) }
|
|
648
|
+
end
|
|
649
|
+
notes
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
private_class_method def self.anthropic_schema_key(opts = {})
|
|
653
|
+
schema = opts[:schema]
|
|
654
|
+
name = opts[:name]
|
|
655
|
+
return name if schema.is_a?(Hash) && schema.key?(name)
|
|
656
|
+
return name.to_sym if schema.is_a?(Hash) && schema.key?(name.to_sym)
|
|
657
|
+
|
|
658
|
+
nil
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
private_class_method def self.json_copy(opts = {})
|
|
662
|
+
value = opts[:value]
|
|
663
|
+
case value
|
|
664
|
+
when Hash
|
|
665
|
+
value.each_with_object({}) { |(key, item), out| out[key] = json_copy(value: item) }
|
|
666
|
+
when Array
|
|
667
|
+
value.map { |item| json_copy(value: item) }
|
|
668
|
+
else
|
|
669
|
+
value.is_a?(String) ? value.dup : value
|
|
670
|
+
end
|
|
671
|
+
end
|
|
672
|
+
|
|
601
673
|
# OpenAI messages[] -> [system_string, anthropic messages[]]
|
|
602
674
|
private_class_method def self.oa_messages_to_anthropic(opts = {})
|
|
603
675
|
messages = opts[:messages] ||= []
|
|
@@ -1070,10 +1070,10 @@ module PWN
|
|
|
1070
1070
|
role = cfg[:system_role_content].to_s.gsub(/\s+/, ' ').strip
|
|
1071
1071
|
parts = []
|
|
1072
1072
|
parts << "SYSTEM ROLE CONTENT: #{role}" unless role.empty?
|
|
1073
|
-
parts << "\
|
|
1074
|
-
parts << " MAX TOKENS: #{cfg[:max_tokens]}" unless cfg[:max_tokens].nil?
|
|
1073
|
+
parts << "\nMAX TOKENS: #{cfg[:max_tokens]}" unless cfg[:max_tokens].nil?
|
|
1075
1074
|
parts << " MAX PROMPT LENGTH: #{cfg[:max_prompt_length]}" unless cfg[:max_prompt_length].nil?
|
|
1076
|
-
parts << "
|
|
1075
|
+
parts << " REASONING EFFORT: #{cfg[:reasoning_effort]}" unless cfg[:reasoning_effort].to_s.empty?
|
|
1076
|
+
parts << " TEMP: #{cfg[:temp]}" unless cfg[:temp].nil?
|
|
1077
1077
|
parts.join(' · ')
|
|
1078
1078
|
rescue StandardError
|
|
1079
1079
|
''
|
data/lib/pwn/version.rb
CHANGED
|
@@ -58,4 +58,52 @@ describe PWN::AI::Anthropic do
|
|
|
58
58
|
expect(src).to include('PromptCache.enabled?')
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
+
|
|
62
|
+
it 'drops root combinators from Anthropic input_schema without mutating registry schemas' do
|
|
63
|
+
allow(PWN::Env).to receive(:[]).with(:ai).and_return(
|
|
64
|
+
anthropic: { key: 'test-key', model: 'claude-test', temp: 1, max_tokens: 100 }
|
|
65
|
+
)
|
|
66
|
+
allow(PWN::AI::Agent::PromptCache).to receive(:enabled?).and_return(false) if defined?(PWN::AI::Agent::PromptCache)
|
|
67
|
+
tools = PWN::AI::Agent::Registry.definitions(core_only: true)
|
|
68
|
+
artifact = tools.find { |tool| tool.dig(:function, :name) == 'artifact_read' }
|
|
69
|
+
original = artifact[:function][:parameters]
|
|
70
|
+
nested = {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {
|
|
73
|
+
item: { anyOf: [{ type: 'string' }, { type: 'object', properties: { handle: { type: 'string' } } }] }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
union = {
|
|
77
|
+
'anyOf' => [
|
|
78
|
+
{ 'type' => 'object', 'properties' => { 'handle' => { 'type' => 'string' } }, 'required' => ['handle'] },
|
|
79
|
+
{ 'type' => 'object', 'properties' => { 'path' => { 'type' => 'string' } }, 'required' => ['path'] }
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
sent = tools + [
|
|
83
|
+
{ type: 'function', function: { name: 'nested_union', description: 'keep nested', parameters: nested } },
|
|
84
|
+
{ type: 'function', function: { name: 'root_union', description: 'flatten', parameters: union } }
|
|
85
|
+
]
|
|
86
|
+
captured = nil
|
|
87
|
+
allow(described_class).to receive(:anthropic_rest_call) do |opts|
|
|
88
|
+
captured = opts[:http_body]
|
|
89
|
+
'{"id":"msg_schema","type":"message","role":"assistant","content":[{"type":"text","text":"ok"}],"stop_reason":"end_turn"}'
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
described_class.chat_with_tools(messages: [{ role: 'user', content: 'hello' }], tools: sent, model: 'claude-test')
|
|
93
|
+
|
|
94
|
+
expect(original).to have_key(:anyOf)
|
|
95
|
+
wire = captured[:tools]
|
|
96
|
+
expect(wire.map { |tool| tool[:name] }[10]).to eq('artifact_read')
|
|
97
|
+
wire.each do |tool|
|
|
98
|
+
schema = tool[:input_schema]
|
|
99
|
+
expect(schema.keys.map(&:to_s)).not_to include('anyOf', 'oneOf', 'allOf')
|
|
100
|
+
end
|
|
101
|
+
read_schema = wire[10][:input_schema]
|
|
102
|
+
expect(read_schema[:properties].keys.map(&:to_s)).to include('handle', 'path', 'ref')
|
|
103
|
+
expect(read_schema[:description]).to include('handle', 'path', 'ref')
|
|
104
|
+
expect(wire.find { |tool| tool[:name] == 'nested_union' }[:input_schema][:properties][:item]).to have_key(:anyOf)
|
|
105
|
+
flat = wire.find { |tool| tool[:name] == 'root_union' }[:input_schema]
|
|
106
|
+
expect(flat[:properties].keys.map(&:to_s)).to include('handle', 'path')
|
|
107
|
+
expect(flat[:description]).to include('handle', 'path')
|
|
108
|
+
end
|
|
61
109
|
end
|
|
@@ -535,10 +535,10 @@ describe 'pwn-ai curses launch' do # rubocop:disable Metrics/BlockLength -- publ
|
|
|
535
535
|
expect(console.instance_variable_get(:@header_text_column)).to eq(2)
|
|
536
536
|
end
|
|
537
537
|
allow(curses).to receive_messages(cols: 120, lines: 26)
|
|
538
|
-
PWN::Env[:ai][:ollama][:system_role_content] = 'operator ' *
|
|
538
|
+
PWN::Env[:ai][:ollama][:system_role_content] = 'operator ' * 200
|
|
539
539
|
console.draw
|
|
540
540
|
expect(console.instance_variable_get(:@header_text_column)).to eq(2)
|
|
541
|
-
expect(console.header_lines('ollama', 'fixture', 115).length).to be
|
|
541
|
+
expect(console.header_lines('ollama', 'fixture', 115).length).to be > 16
|
|
542
542
|
expect(PWN::Banner).to have_received(:mini_cells).once
|
|
543
543
|
expect([console.instance_variable_get(:@editor).text, console.instance_variable_get(:@editor).cursor]).to eq(['retained draft', 4])
|
|
544
544
|
end
|
|
@@ -719,13 +719,15 @@ describe 'pwn-ai curses launch' do # rubocop:disable Metrics/BlockLength -- publ
|
|
|
719
719
|
expect(actual).to eq(lines)
|
|
720
720
|
expect(header.select { |entry| entry[3] == console.tone(:category) }.map { |entry| entry[2] }.join).to include('SYSTEM ROLE CONTENT:', 'MAX PROMPT LENGTH:', 'REASONING EFFORT:')
|
|
721
721
|
expect(header.select { |entry| entry[3] == console.tone(:header) }.map { |entry| entry[2] }.join).to include('operator', '1024', 'high')
|
|
722
|
-
if columns == 48
|
|
723
|
-
labels = header.select { |entry| entry[3] == console.tone(:category) }.map { |entry| entry[2] }
|
|
724
|
-
expect(labels.join).to include('MAX PROMPT LENGTH:')
|
|
725
|
-
expect(labels).not_to include(a_string_including('MAX PROMPT LENGTH:'))
|
|
726
|
-
end
|
|
727
722
|
expect(console.instance_variable_get(:@page_size)).to be >= 1
|
|
728
723
|
end
|
|
724
|
+
console.header_lines('ollama', 'fixture', 35)
|
|
725
|
+
labels = []
|
|
726
|
+
console.instance_variable_get(:@header_spans).each do |row|
|
|
727
|
+
row.each { |role, text| labels << text if role == :category }
|
|
728
|
+
end
|
|
729
|
+
expect(labels.join).to include('MAX PROMPT LENGTH:')
|
|
730
|
+
expect(labels).not_to include(a_string_including('MAX PROMPT LENGTH:'))
|
|
729
731
|
console.handle("\u000f")
|
|
730
732
|
console.draw
|
|
731
733
|
console.handle(:end)
|
|
@@ -1238,7 +1240,9 @@ describe 'pwn-ai curses launch' do # rubocop:disable Metrics/BlockLength -- publ
|
|
|
1238
1240
|
if rendered_header.include?('worker-effort')
|
|
1239
1241
|
expect(rendered_header).to include('worker settings role', '0.42', '4321', '8765')
|
|
1240
1242
|
expect(painted).to include([a_kind_of(Integer), a_kind_of(Integer), 'MODEL:', 7])
|
|
1241
|
-
|
|
1243
|
+
value = painted.find { |_y, _x, text, color| color == 6 && text.to_s.include?('worker-effort') }
|
|
1244
|
+
expect(value).not_to be_nil
|
|
1245
|
+
expect(value[2]).not_to include('REASONING EFFORT:')
|
|
1242
1246
|
"\u0004"
|
|
1243
1247
|
else
|
|
1244
1248
|
Thread.pass
|
data/third_party/pwn_rdoc.jsonl
CHANGED
|
@@ -1058,13 +1058,17 @@
|
|
|
1058
1058
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::VulnGen.authors Usage"},{"role":"assistant","content":"`PWN::AI::Agent::VulnGen.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
|
1059
1059
|
{"messages":[{"role":"user","content":"PWN::AI::Agent::VulnGen.help Usage"},{"role":"assistant","content":"`PWN::AI::Agent::VulnGen.help`: "}]}
|
|
1060
1060
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.anth_tool_choice Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.anth_tool_choice`: "}]}
|
|
1061
|
+
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.anthropic_input_schema Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.anthropic_input_schema`: "}]}
|
|
1061
1062
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.anthropic_resp_to_oa Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.anthropic_resp_to_oa`: "}]}
|
|
1062
1063
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.anthropic_rest_call Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.anthropic_rest_call`: Supported Method Parameters\n\nanthropic_rest_call(\n\ntoken: 'required - anthropic api key',\nhttp_method: 'optional HTTP method (defaults to GET)',\nbase_uri: 'optional base anthropic api URI (defaults to https://api.anthropic.com/v1)',\nrest_call: 'required rest call to make per the schema',\nparams: 'optional params passed in the URI or HTTP Headers',\nhttp_body: 'optional HTTP body sent in HTTP methods that support it e.g. POST',\ntimeout: 'optional timeout in seconds (defaults to 900)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
|
|
1064
|
+
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.anthropic_schema_key Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.anthropic_schema_key`: "}]}
|
|
1065
|
+
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.anthropic_schema_notes Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.anthropic_schema_notes`: "}]}
|
|
1063
1066
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.authors Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
|
|
1064
1067
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.chat Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.chat`: Supported Method Parameters\n\nresponse = PWN::AI::Anthropic.chat(\n\nrequest: 'required - message to Anthropic',\nmodel: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:anthropic][:model])',\ntemp: 'optional - creative response float (defaults to PWN::Env[:ai][:anthropic][:temp])',\nsystem_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:anthropic][:system_role_content])',\nresponse_history: 'optional - pass response back in to have a conversation',\nspeak_answer: 'optional speak answer using PWN::Plugins::Voice.text_to_speech (Default: nil)',\ntimeout: 'optional timeout in seconds (defaults to 900)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
|
|
1065
1068
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.chat_with_tools Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.chat_with_tools`: Supported Method Parameters\n\nresponse = PWN::AI::Anthropic.chat_with_tools(\n\nmessages: 'required - OpenAI-format messages array (system/user/assistant/tool)',\ntools: 'optional - OpenAI tools array [{type:\"function\", function:{...}}]',\ntool_choice: 'optional - \"auto\" | \"none\" | \"required\" | {type:\"function\", function:{name:..}}',\nmodel: 'optional - overrides PWN::Env[:ai][:anthropic][:model]',\ntemp: 'optional - temperature (defaults to PWN::Env[:ai][:anthropic][:temp] || 1)',\nmax_tokens: 'optional - defaults to PWN::Env[:ai][:anthropic][:max_tokens] || 128_000',\ntimeout: 'optional - seconds (default 900)',\nspinner: 'optional - display spinner (default false)'\n\n)\n"}]}
|
|
1066
1069
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.get_models Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.get_models`: Supported Method Parameters\n\nmodels = PWN::AI::Anthropic.get_models\n"}]}
|
|
1067
1070
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.help Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.help`: "}]}
|
|
1071
|
+
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.json_copy Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.json_copy`: "}]}
|
|
1068
1072
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.jwt_exp Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.jwt_exp`: "}]}
|
|
1069
1073
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.oa_messages_to_anthropic Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.oa_messages_to_anthropic`: "}]}
|
|
1070
1074
|
{"messages":[{"role":"user","content":"PWN::AI::Anthropic.oauth_token_expiring? Usage"},{"role":"assistant","content":"`PWN::AI::Anthropic.oauth_token_expiring?`: "}]}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pwn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.754
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
@@ -141,14 +141,14 @@ dependencies:
|
|
|
141
141
|
requirements:
|
|
142
142
|
- - ">="
|
|
143
143
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: 4.0.
|
|
144
|
+
version: 4.0.22
|
|
145
145
|
type: :development
|
|
146
146
|
prerelease: false
|
|
147
147
|
version_requirements: !ruby/object:Gem::Requirement
|
|
148
148
|
requirements:
|
|
149
149
|
- - ">="
|
|
150
150
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: 4.0.
|
|
151
|
+
version: 4.0.22
|
|
152
152
|
- !ruby/object:Gem::Dependency
|
|
153
153
|
name: bundler-audit
|
|
154
154
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -617,14 +617,14 @@ dependencies:
|
|
|
617
617
|
requirements:
|
|
618
618
|
- - '='
|
|
619
619
|
- !ruby/object:Gem::Version
|
|
620
|
-
version: 0.5.
|
|
620
|
+
version: 0.5.2
|
|
621
621
|
type: :runtime
|
|
622
622
|
prerelease: false
|
|
623
623
|
version_requirements: !ruby/object:Gem::Requirement
|
|
624
624
|
requirements:
|
|
625
625
|
- - '='
|
|
626
626
|
- !ruby/object:Gem::Version
|
|
627
|
-
version: 0.5.
|
|
627
|
+
version: 0.5.2
|
|
628
628
|
- !ruby/object:Gem::Dependency
|
|
629
629
|
name: nexpose
|
|
630
630
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -7228,7 +7228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
7228
7228
|
- !ruby/object:Gem::Version
|
|
7229
7229
|
version: '0'
|
|
7230
7230
|
requirements: []
|
|
7231
|
-
rubygems_version: 4.0.
|
|
7231
|
+
rubygems_version: 4.0.22
|
|
7232
7232
|
specification_version: 4
|
|
7233
7233
|
summary: Automated Security Testing for CI/CD Pipelines & Beyond
|
|
7234
7234
|
test_files: []
|