uncaught 0.1.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.
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uncaught
4
+ # Severity levels mirroring syslog.
5
+ SEVERITY_LEVELS = %w[fatal error warning info debug].freeze
6
+
7
+ # Breadcrumb categories.
8
+ BREADCRUMB_TYPES = %w[click navigation api_call db_query auth console web_vital custom].freeze
9
+
10
+ # Issue statuses.
11
+ ISSUE_STATUSES = %w[open resolved ignored].freeze
12
+
13
+ # Transport modes.
14
+ TRANSPORT_MODES = %w[local console].freeze
15
+
16
+ # ---------------------------------------------------------------------------
17
+ # Struct definitions
18
+ # ---------------------------------------------------------------------------
19
+
20
+ # SDK metadata shipped with every event.
21
+ SdkInfo = Struct.new(:name, :version, keyword_init: true)
22
+
23
+ # Contextual HTTP request information attached to an event.
24
+ RequestInfo = Struct.new(:method, :url, :headers, :body, :query, keyword_init: true)
25
+
26
+ # Information about a failed external operation (DB, auth, API, etc.).
27
+ OperationInfo = Struct.new(:provider, :type, :method, :params, :error_code, :error_details, keyword_init: true)
28
+
29
+ # User context attached to events.
30
+ UserInfo = Struct.new(:id, :email, :username, :session_id, keyword_init: true)
31
+
32
+ # Structured representation of a captured error.
33
+ ErrorInfo = Struct.new(:message, :type, :stack, :resolved_stack, :component_stack, keyword_init: true)
34
+
35
+ # A single breadcrumb entry.
36
+ Breadcrumb = Struct.new(:type, :category, :message, :timestamp, :data, :level, keyword_init: true)
37
+
38
+ # Detected runtime / platform information.
39
+ EnvironmentInfo = Struct.new(
40
+ :framework, :framework_version, :runtime, :runtime_version,
41
+ :platform, :os, :browser, :browser_version, :device_type,
42
+ :locale, :timezone, :url, :deploy,
43
+ keyword_init: true
44
+ )
45
+
46
+ # The canonical event payload sent to transports.
47
+ UncaughtEvent = Struct.new(
48
+ :event_id, :timestamp, :project_key, :level, :fingerprint,
49
+ :release, :error, :breadcrumbs, :request, :operation,
50
+ :environment, :user, :user_feedback, :fix_prompt, :sdk,
51
+ keyword_init: true
52
+ )
53
+
54
+ # An entry in the issues.json index file.
55
+ IssueEntry = Struct.new(
56
+ :fingerprint, :title, :error_type, :count, :affected_users,
57
+ :first_seen, :last_seen, :status, :fix_prompt_file,
58
+ :latest_event_file, :release, :environment,
59
+ keyword_init: true
60
+ )
61
+
62
+ # Configuration object.
63
+ Configuration = Struct.new(
64
+ :project_key, :endpoint, :environment, :release, :debug,
65
+ :enabled, :max_breadcrumbs, :max_events_per_minute,
66
+ :before_send, :sanitize_keys, :ignore_errors,
67
+ :transport, :local_output_dir, :webhook_url,
68
+ :framework, :framework_version,
69
+ keyword_init: true
70
+ ) do
71
+ def initialize(**kwargs)
72
+ super(
73
+ enabled: true,
74
+ debug: false,
75
+ max_breadcrumbs: 20,
76
+ max_events_per_minute: 30,
77
+ transport: "local",
78
+ sanitize_keys: [],
79
+ ignore_errors: [],
80
+ **kwargs
81
+ )
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uncaught
4
+ VERSION = "0.1.0"
5
+ end
data/lib/uncaught.rb ADDED
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "json"
5
+ require "time"
6
+
7
+ require_relative "uncaught/version"
8
+ require_relative "uncaught/types"
9
+ require_relative "uncaught/fingerprint"
10
+ require_relative "uncaught/breadcrumbs"
11
+ require_relative "uncaught/rate_limiter"
12
+ require_relative "uncaught/sanitizer"
13
+ require_relative "uncaught/env_detector"
14
+ require_relative "uncaught/prompt_builder"
15
+ require_relative "uncaught/transport"
16
+ require_relative "uncaught/client"
17
+
18
+ module Uncaught
19
+ class Error < StandardError; end
20
+
21
+ # Module-level singleton client.
22
+ @client = nil
23
+ @config = nil
24
+ @mutex = Mutex.new
25
+
26
+ class << self
27
+ # Configure the Uncaught SDK.
28
+ #
29
+ # @yield [Configuration] Yields the configuration object for modification.
30
+ # @return [Client] The configured client instance.
31
+ #
32
+ # @example
33
+ # Uncaught.configure do |config|
34
+ # config.project_key = "my-project"
35
+ # config.environment = "production"
36
+ # config.release = "1.0.0"
37
+ # end
38
+ def configure
39
+ @mutex.synchronize do
40
+ @config ||= Configuration.new
41
+ yield @config if block_given?
42
+ @client = Client.new(@config)
43
+ end
44
+ @client
45
+ end
46
+
47
+ # Return the current singleton client, or nil if not configured.
48
+ #
49
+ # @return [Client, nil]
50
+ def client
51
+ @client
52
+ end
53
+
54
+ # Return the current configuration, or nil if not configured.
55
+ #
56
+ # @return [Configuration, nil]
57
+ def configuration
58
+ @config
59
+ end
60
+
61
+ # Convenience: capture an error on the singleton client.
62
+ #
63
+ # @param error [Exception, String, Hash]
64
+ # @param kwargs [Hash] Additional context (request:, operation:, level:, etc.)
65
+ # @return [String, nil] The event ID.
66
+ def capture_error(error, **kwargs)
67
+ return nil unless @client
68
+
69
+ @client.capture_error(error, **kwargs)
70
+ end
71
+
72
+ # Convenience: capture a message on the singleton client.
73
+ #
74
+ # @param message [String]
75
+ # @param level [String]
76
+ # @return [String, nil]
77
+ def capture_message(message, level: "info")
78
+ return nil unless @client
79
+
80
+ @client.capture_message(message, level: level)
81
+ end
82
+
83
+ # Convenience: add a breadcrumb on the singleton client.
84
+ def add_breadcrumb(**kwargs)
85
+ return unless @client
86
+
87
+ @client.add_breadcrumb(**kwargs)
88
+ end
89
+
90
+ # Convenience: set user on the singleton client.
91
+ def set_user(user)
92
+ return unless @client
93
+
94
+ @client.set_user(user)
95
+ end
96
+
97
+ # Convenience: flush on the singleton client.
98
+ def flush
99
+ return unless @client
100
+
101
+ @client.flush
102
+ end
103
+
104
+ # Install global exception handler for at_exit.
105
+ #
106
+ # @example
107
+ # Uncaught.install_at_exit_handler!
108
+ def install_at_exit_handler!
109
+ at_exit do
110
+ if $! && !$!.is_a?(SystemExit)
111
+ Uncaught.capture_error($!)
112
+ Uncaught.flush
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ # Auto-load Rails integration if Rails is present.
120
+ if defined?(::Rails::Railtie)
121
+ require_relative "uncaught/integrations/rails"
122
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uncaught
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Uncaught Dev
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-03-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Catch bugs locally, get AI-powered fixes. Works with Rails and Sinatra.
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/uncaught.rb
20
+ - lib/uncaught/breadcrumbs.rb
21
+ - lib/uncaught/client.rb
22
+ - lib/uncaught/env_detector.rb
23
+ - lib/uncaught/fingerprint.rb
24
+ - lib/uncaught/integrations/rails.rb
25
+ - lib/uncaught/integrations/sinatra.rb
26
+ - lib/uncaught/prompt_builder.rb
27
+ - lib/uncaught/rate_limiter.rb
28
+ - lib/uncaught/sanitizer.rb
29
+ - lib/uncaught/transport.rb
30
+ - lib/uncaught/types.rb
31
+ - lib/uncaught/version.rb
32
+ homepage: https://github.com/ajeeshworkspace/uncaught
33
+ licenses:
34
+ - MIT
35
+ metadata: {}
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.7.0
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubygems_version: 3.0.3.1
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Local-first, AI-ready error monitoring for Ruby
55
+ test_files: []