antigravity-sdk 0.1.1 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ade58fad8a0ce76edf2cb631fa0ff4e8c21efc86bfa2ae48d5489372145a6756
4
- data.tar.gz: f06feea8e5aaae71a0b1a24167b8da5f89cead824e5ea4f858aac409b9431574
3
+ metadata.gz: 449edf2b1bf5f2aaa389a0e79b74c6ed93bc5b7623a957068b2bd704b292347b
4
+ data.tar.gz: c876958eb74ccac96717634b5a0c1d7314e837f2a3695a557d1d19eee4b6d853
5
5
  SHA512:
6
- metadata.gz: 72b602c3732ca8e6a24f9684b8e595492381509afeae41493b75a05de9107e605cfffae134b48f58bed7414725a24a73a5fdd42514bbda19a220fb0831543e94
7
- data.tar.gz: f8b3367309f54ae8e667eff77fb9e33da87943a279d5edebe2275c4ba1f2a7183db3a7da61c300efe771a64f8d9dee8299e99cd7d337f14d1a6221e9c5966b3e
6
+ metadata.gz: 6ccc779048181412d94425b9a9c4901339acfb957e4646b047ce4fe1b96e4d2b4f4b6096c560178920f68b22733a6d424b3d010769e17b592f90bc77d2004220
7
+ data.tar.gz: e170353f68f1fdbe47ab3c487136be397636a8855223204e72b4d216bd37c7d04592f935d22b207314d9ecd35c95b7ef3741397204005b89eaccdb7564578427
@@ -15,19 +15,9 @@ module Antigravity
15
15
  @hooks = Hooks.new
16
16
  @client = Client.new
17
17
 
18
- # Auto-attach default safety guardrails
19
- use_safety_defaults!
20
-
21
18
  yield(self) if block_given?
22
19
  end
23
20
 
24
- def use_safety_defaults!
25
- # Pre-tool guard against editing protected files (.env, Gemfile, etc.)
26
- before_tool_call(&Safety::ProtectedFilesGuard.new)
27
- # Post-tool secret masking
28
- after_tool_call(&Safety::SecretMasker.new)
29
- end
30
-
31
21
  def register_tool(tool_or_name = nil, description: "", &block)
32
22
  if block_given? && tool_or_name
33
23
  tool = Tool::Dynamic.new(tool_or_name, description: description, &block)
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Antigravity
4
+ module Guards
5
+ # Configurable opt-in file protection guard
6
+ class FileProtection
7
+ DEFAULT_FILES = [
8
+ /\.env(\..*)?$/i,
9
+ /Gemfile(\.lock)?$/i,
10
+ /config\/secrets\.yml$/i,
11
+ /config\/database\.yml$/i
12
+ ].freeze
13
+
14
+ attr_reader :protected_files
15
+
16
+ def initialize(files: nil, add: [], remove: [])
17
+ initial_patterns = files ? Array(files) : DEFAULT_FILES
18
+ patterns = initial_patterns.map { |f| f.is_a?(Regexp) ? f : /#{Regexp.escape(f.to_s)}$/i }
19
+ patterns += Array(add).map { |f| f.is_a?(Regexp) ? f : /#{Regexp.escape(f.to_s)}$/i }
20
+ patterns -= Array(remove).map { |f| f.is_a?(Regexp) ? f : /#{Regexp.escape(f.to_s)}$/i }
21
+ @protected_files = patterns.freeze
22
+ end
23
+
24
+ def call(_tool_name, params)
25
+ path = extract_path(params)
26
+ return :allow unless path
27
+
28
+ if protected_path?(path)
29
+ { status: :deny, reason: "FileProtection Guard: Modifications to '#{path}' are restricted." }
30
+ else
31
+ :allow
32
+ end
33
+ end
34
+
35
+ def to_proc
36
+ method(:call).to_proc
37
+ end
38
+
39
+ private
40
+
41
+ def extract_path(params)
42
+ return nil unless params.is_a?(Hash)
43
+ params[:path] || params["path"] || params[:file] || params["file"] || params[:target]
44
+ end
45
+
46
+ def protected_path?(path)
47
+ filename = File.basename(path)
48
+ @protected_files.any? { |pattern| path =~ pattern || filename =~ pattern }
49
+ end
50
+ end
51
+
52
+ # Configurable opt-in secret masking filter
53
+ class SecretMasker
54
+ DEFAULT_PATTERNS = [
55
+ /(AIzaSy[A-Za-z0-9_-]{25,45})/, # Google API Keys
56
+ /(sk-[A-Za-z0-9]{25,50})/, # OpenAI API Keys
57
+ /(ghp_[A-Za-z0-9]{25,45})/, # GitHub Tokens
58
+ /(bearer\s+[A-Za-z0-9\._-]{20,})/i # Bearer Tokens
59
+ ].freeze
60
+
61
+ attr_reader :patterns, :replacement
62
+
63
+ def initialize(patterns: nil, replacement: "[REDACTED_SECRET]")
64
+ @patterns = (patterns ? Array(patterns) : DEFAULT_PATTERNS).freeze
65
+ @replacement = replacement
66
+ end
67
+
68
+ def call(_tool_name, _params, result)
69
+ return result unless result.is_a?(String)
70
+
71
+ sanitized = result.dup
72
+ @patterns.each do |pattern|
73
+ sanitized.gsub!(pattern, @replacement)
74
+ end
75
+ sanitized
76
+ end
77
+
78
+ def to_proc
79
+ method(:call).to_proc
80
+ end
81
+ end
82
+ end
83
+ end
data/lib/antigravity.rb CHANGED
@@ -5,7 +5,7 @@ require_relative "antigravity/config"
5
5
  require_relative "antigravity/message"
6
6
  require_relative "antigravity/harness"
7
7
  require_relative "antigravity/hooks"
8
- require_relative "antigravity/safety"
8
+ require_relative "antigravity/guards"
9
9
  require_relative "antigravity/sidecar"
10
10
  require_relative "antigravity/tool"
11
11
  require_relative "antigravity/skill"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: antigravity-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Riccardo Carlesso
@@ -49,10 +49,10 @@ files:
49
49
  - lib/antigravity/agent.rb
50
50
  - lib/antigravity/client.rb
51
51
  - lib/antigravity/config.rb
52
+ - lib/antigravity/guards.rb
52
53
  - lib/antigravity/harness.rb
53
54
  - lib/antigravity/hooks.rb
54
55
  - lib/antigravity/message.rb
55
- - lib/antigravity/safety.rb
56
56
  - lib/antigravity/sidecar.rb
57
57
  - lib/antigravity/skill.rb
58
58
  - lib/antigravity/tool.rb
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Antigravity
4
- module Safety
5
- # Pre-hook guardrail to prevent dangerous file edits or destructive operations
6
- class ProtectedFilesGuard
7
- PROTECTED_PATTERNS = [
8
- /\.env(\..*)?$/i,
9
- /Gemfile(\.lock)?$/i,
10
- /config\/secrets\.yml$/i,
11
- /config\/database\.yml$/i,
12
- /\.git\//i,
13
- /\/etc\//i
14
- ].freeze
15
-
16
- attr_reader :blocked_patterns
17
-
18
- def initialize(additional_patterns: [])
19
- @blocked_patterns = PROTECTED_PATTERNS + additional_patterns
20
- end
21
-
22
- def call(tool_name, params)
23
- path = extract_path(params)
24
- return :allow unless path
25
-
26
- if protected_file?(path)
27
- { status: :deny, reason: "Security Policy Violation: Modifications to '#{path}' are restricted and require explicit approval." }
28
- else
29
- :allow
30
- end
31
- end
32
-
33
- def to_proc
34
- method(:call).to_proc
35
- end
36
-
37
- private
38
-
39
- def extract_path(params)
40
- return nil unless params.is_a?(Hash)
41
- params[:path] || params["path"] || params[:file] || params["file"] || params[:target]
42
- end
43
-
44
- def protected_file?(path)
45
- filename = File.basename(path)
46
- @blocked_patterns.any? { |pattern| path =~ pattern || filename =~ pattern }
47
- end
48
- end
49
-
50
- # Post-hook sanitizer to redact sensitive API keys and tokens from tool outputs
51
- class SecretMasker
52
- SECRET_PATTERNS = [
53
- /(AIzaSy[A-Za-z0-9_-]{25,45})/, # Google API Keys
54
- /(sk-[A-Za-z0-9]{25,50})/, # OpenAI API Keys
55
- /(ghp_[A-Za-z0-9]{25,45})/, # GitHub Tokens
56
- /(bearer\s+[A-Za-z0-9\._-]{20,})/i # Bearer Tokens
57
- ].freeze
58
-
59
- def call(_tool_name, _params, result)
60
- return result unless result.is_a?(String)
61
-
62
- sanitized = result.dup
63
- SECRET_PATTERNS.each do |pattern|
64
- sanitized.gsub!(pattern, "[REDACTED_SECRET]")
65
- end
66
- sanitized
67
- end
68
-
69
- def to_proc
70
- method(:call).to_proc
71
- end
72
- end
73
- end
74
- end