rails-informant 0.6.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 905f71f9e86e6c982710d2c1dbd8471218798e1cfa80b8baca78124180a1fef3
4
- data.tar.gz: 9cc699035012351e2bfe4b0423c2b7fe0bffd7880f05250d2d54f758bf2d50ea
3
+ metadata.gz: 7f1d6f0b5274e2da8e271fdc47352ff3c35f181e6b799b64a8f5273853b07139
4
+ data.tar.gz: 165015e620935cca923dc3fbf89b049d587666d4047bb8fafc4b73049be50631
5
5
  SHA512:
6
- metadata.gz: b103c2f10d32404883a51e7d9ef82daf0dda368bd7ec50165d32f88b9b9d53924aeb6264af9c4e7f10468d6abe891228a62e7e09c2584a74a0d469a619cf9dd5
7
- data.tar.gz: fad95e73c07500480d703c2018e5eeeef77656f0cd16aced9b8e778d90c700a450b1f2963c54f093b76fc2b501a013148b2afb18bef81b8eeed399db1bd5d96c
6
+ metadata.gz: aa70bfe035cf0cb73d4aa8a9976c558ab5977ca858fdb526613e55e727f72261b0410143678a6eb523071fce99e4758f598f307727b2e51336adf4c8336a214e
7
+ data.tar.gz: a613e453aa984669d16c5c74ddbd8772faacbde476f341f2f94c405d6dea27db3b6a6bdc7115a2a54c38a74da26e33da74fe5412c8faf87cc294743e0c62c6db
data/README.md CHANGED
@@ -93,7 +93,7 @@ Every option can be set via an environment variable. The initializer takes prece
93
93
  | `capture_user_email` | _(none)_ | `false` | Capture email from detected user (PII -- opt-in) |
94
94
  | `ignored_exceptions` | `INFORMANT_IGNORED_EXCEPTIONS` | `[]` | Exception classes to skip (walks cause chain) |
95
95
  | `ignored_paths` | `INFORMANT_IGNORED_PATHS` | `[]` | Request paths to skip (exact or segment match) |
96
- | `job_attempt_threshold` | `INFORMANT_JOB_ATTEMPT_THRESHOLD` | `nil` | Suppress job errors until Nth retry |
96
+ | `job_attempt_threshold` | `INFORMANT_JOB_ATTEMPT_THRESHOLD` | `nil` | Suppress job failures until the Nth attempt (handled reports are always recorded) |
97
97
  | `retention_days` | `INFORMANT_RETENTION_DAYS` | `nil` | Auto-purge resolved errors after N days |
98
98
  | `slack_webhook_url` | `INFORMANT_SLACK_WEBHOOK_URL` | `nil` | Slack incoming webhook URL |
99
99
  | `spike_protection` | _(none)_ | `nil` | Rate-limit per error group: `{ threshold: 50, window: 1.minute }` |
@@ -199,6 +199,12 @@ The bundled `informant-mcp` executable connects Claude Code to your error data v
199
199
 
200
200
  The `rails_informant:skill` generator creates `.mcp.json` automatically. Set `INFORMANT_PRODUCTION_URL` and `INFORMANT_PRODUCTION_TOKEN` as environment variables (e.g., via `.envrc` + direnv).
201
201
 
202
+ `informant-mcp` reads these variables when it starts, so a Claude Code session started without them loaded crashes the server on boot. To load `.envrc` on every start, launch the server through direnv. The generator and `informant:doctor` both accept this entry:
203
+
204
+ ```json
205
+ "informant": { "command": "direnv", "args": ["exec", ".", "informant-mcp"] }
206
+ ```
207
+
202
208
  For multi-environment setups, add env vars for each environment:
203
209
 
204
210
  ```bash
@@ -25,7 +25,9 @@ module RailsInformant
25
25
  if File.exist?(mcp_path)
26
26
  existing = JSON.parse(File.read(mcp_path))
27
27
  existing["mcpServers"] ||= {}
28
- existing["mcpServers"]["informant"] = Content.mcp_entry
28
+ unless Content.accepted_mcp_entries.include?(existing["mcpServers"]["informant"])
29
+ existing["mcpServers"]["informant"] = Content.mcp_entry
30
+ end
29
31
  create_file ".mcp.json", JSON.pretty_generate(existing) + "\n", force: true
30
32
  else
31
33
  create_file ".mcp.json", JSON.pretty_generate(
@@ -65,6 +65,13 @@ module RailsInformant
65
65
  { "command" => "informant-mcp" }
66
66
  end
67
67
 
68
+ # Entries an app may keep in place of mcp_entry. The direnv form loads the
69
+ # app's .envrc first: informant-mcp reads its URL and token at startup, so a
70
+ # session started without the .envrc loaded crashes it on boot.
71
+ def accepted_mcp_entries
72
+ [ mcp_entry, { "command" => "direnv", "args" => [ "exec", ".", "informant-mcp" ] } ]
73
+ end
74
+
68
75
  # A single UserPromptSubmit hook registration for settings.json.
69
76
  def hook_registration
70
77
  {
@@ -113,7 +113,11 @@ module RailsInformant
113
113
  end
114
114
 
115
115
  def extract_job_class(context)
116
- context.dig(:job, :class) || context[:job_class]
116
+ case context[:job]
117
+ in ActiveJob::Base => job then job.class.name
118
+ in { class: String => job_class } then job_class
119
+ else context[:job_class]
120
+ end
117
121
  end
118
122
 
119
123
  def filtered_url(url)
@@ -11,11 +11,17 @@ module RailsInformant
11
11
  initializer "rails_informant.context_middleware" do
12
12
  next unless RailsInformant.capture_errors
13
13
 
14
- Rails.error.add_middleware ->(error, context) {
14
+ Rails.error.add_middleware ->(error, context:, **) {
15
15
  context.merge deploy_sha: RailsInformant.current_git_sha
16
16
  }
17
17
  end
18
18
 
19
+ initializer "rails_informant.job_execution_context" do
20
+ next unless RailsInformant.capture_errors
21
+
22
+ ActiveSupport.on_load(:active_job) { prepend RailsInformant::JobExecutionContext }
23
+ end
24
+
19
25
  initializer "rails_informant.middleware" do |app|
20
26
  next unless RailsInformant.capture_errors
21
27
 
@@ -7,7 +7,7 @@ module RailsInformant
7
7
  return if handled && severity == :info
8
8
  return if source && SKIP_SOURCES.match?(source)
9
9
  return if RailsInformant::Current.silenced
10
- return if below_job_attempt_threshold?(context)
10
+ return if !handled && below_job_attempt_threshold?(context)
11
11
  return if RailsInformant.ignored_exception?(error)
12
12
  return if RailsInformant.already_captured?(error)
13
13
 
@@ -25,6 +25,8 @@ module RailsInformant
25
25
  case context
26
26
  in job: { executions: Integer => executions }
27
27
  executions < threshold
28
+ in job: ActiveJob::Base => job
29
+ job.executions < threshold
28
30
  in executions: Integer => executions
29
31
  executions < threshold
30
32
  else
@@ -126,7 +126,7 @@ module RailsInformant
126
126
  "hook" => normalize_text(read_or_empty(hook_path)),
127
127
  "skill" => @hyperdrive_managed ? "" : normalize_text(read_or_empty(skill_path)),
128
128
  "settings" => canonical_json(live_settings_registrations || {}),
129
- "mcp" => canonical_json(live_mcp_entry || {})
129
+ "mcp" => canonical_json(Content.accepted_mcp_entries.include?(live_mcp_entry) ? Content.mcp_entry : live_mcp_entry || {})
130
130
  )
131
131
  end
132
132
 
@@ -0,0 +1,11 @@
1
+ module RailsInformant
2
+ # Rails leaves ExecutionContext[:job] set after perform_now returns, so a job
3
+ # performed inline would claim every later report in the same request or job.
4
+ # A failing job stays in place so the executor's report still names it.
5
+ module JobExecutionContext
6
+ def perform_now
7
+ previous = ActiveSupport::ExecutionContext.to_h[:job]
8
+ super.tap { ActiveSupport::ExecutionContext[:job] = previous }
9
+ end
10
+ end
11
+ end
@@ -35,6 +35,7 @@ module RailsInformant
35
35
  autoload :Event, "rails_informant/event"
36
36
  autoload :Fingerprint, "rails_informant/fingerprint"
37
37
  autoload :Integration, "rails_informant/integration"
38
+ autoload :JobExecutionContext, "rails_informant/job_execution_context"
38
39
  autoload :StructuredEventSubscriber, "rails_informant/structured_event_subscriber"
39
40
 
40
41
  module Middleware
@@ -173,7 +174,7 @@ module RailsInformant
173
174
  else
174
175
  head
175
176
  end
176
- rescue Errno::ENOENT, Errno::EACCES, ArgumentError
177
+ rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, ArgumentError
177
178
  nil
178
179
  end
179
180
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-informant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel López Prat
@@ -147,6 +147,7 @@ files:
147
147
  - lib/rails_informant/event.rb
148
148
  - lib/rails_informant/fingerprint.rb
149
149
  - lib/rails_informant/integration.rb
150
+ - lib/rails_informant/job_execution_context.rb
150
151
  - lib/rails_informant/mcp.rb
151
152
  - lib/rails_informant/mcp/base_tool.rb
152
153
  - lib/rails_informant/mcp/client.rb