bugsage 0.2.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.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/ARCHITECTURE.md +442 -0
  3. data/CHANGELOG.md +28 -0
  4. data/CODE_OF_CONDUCT.md +10 -0
  5. data/CONTRIBUTING.md +301 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +344 -0
  8. data/ROADMAP.md +217 -0
  9. data/SECURITY.md +83 -0
  10. data/docs/AI.md +167 -0
  11. data/docs/Configuration.md +168 -0
  12. data/docs/GettingStarted.md +146 -0
  13. data/docs/RELEASE_CHECKLIST.md +346 -0
  14. data/docs/Troubleshooting.md +181 -0
  15. data/docs/images/BadRequest.png +0 -0
  16. data/docs/images/BadRequest2.png +0 -0
  17. data/docs/images/BugSage_Logo.png +0 -0
  18. data/docs/images/BugSage_Social_Preview.png +0 -0
  19. data/docs/images/NoMethodError.png +0 -0
  20. data/docs/images/NoMethodError2.png +0 -0
  21. data/docs/images/README.md +38 -0
  22. data/docs/releases/README.md +21 -0
  23. data/docs/releases/v0.2.0.md +40 -0
  24. data/exe/bugsage +7 -0
  25. data/lib/bugsage/ai_analyzer.rb +145 -0
  26. data/lib/bugsage/ai_chat.rb +388 -0
  27. data/lib/bugsage/ai_context.rb +69 -0
  28. data/lib/bugsage/ai_panel.rb +708 -0
  29. data/lib/bugsage/ai_support.rb +36 -0
  30. data/lib/bugsage/auto_configurator.rb +97 -0
  31. data/lib/bugsage/cli.rb +59 -0
  32. data/lib/bugsage/code_context.rb +81 -0
  33. data/lib/bugsage/code_patch.rb +147 -0
  34. data/lib/bugsage/configuration.rb +149 -0
  35. data/lib/bugsage/console_context.rb +51 -0
  36. data/lib/bugsage/cursor_client.rb +165 -0
  37. data/lib/bugsage/dashboard.rb +627 -0
  38. data/lib/bugsage/editor_links.rb +34 -0
  39. data/lib/bugsage/error_page.rb +298 -0
  40. data/lib/bugsage/exception_handler.rb +66 -0
  41. data/lib/bugsage/exception_support.rb +95 -0
  42. data/lib/bugsage/exceptions_app.rb +31 -0
  43. data/lib/bugsage/fix_applicator.rb +107 -0
  44. data/lib/bugsage/formatter.rb +37 -0
  45. data/lib/bugsage/http_error_capture.rb +104 -0
  46. data/lib/bugsage/http_response_error.rb +14 -0
  47. data/lib/bugsage/inline_console.rb +226 -0
  48. data/lib/bugsage/installation.rb +94 -0
  49. data/lib/bugsage/installer.rb +66 -0
  50. data/lib/bugsage/json_endpoint.rb +34 -0
  51. data/lib/bugsage/locales/en.yml +439 -0
  52. data/lib/bugsage/middleware.rb +152 -0
  53. data/lib/bugsage/openai_client.rb +103 -0
  54. data/lib/bugsage/page_actions.rb +255 -0
  55. data/lib/bugsage/railtie.rb +49 -0
  56. data/lib/bugsage/request_context.rb +56 -0
  57. data/lib/bugsage/rule.rb +271 -0
  58. data/lib/bugsage/session_clear.rb +35 -0
  59. data/lib/bugsage/store.rb +60 -0
  60. data/lib/bugsage/suggestion.rb +58 -0
  61. data/lib/bugsage/trace_cleaner.rb +24 -0
  62. data/lib/bugsage/translations.rb +85 -0
  63. data/lib/bugsage/version.rb +5 -0
  64. data/lib/bugsage.rb +65 -0
  65. data/lib/generators/bugsage/install/install_generator.rb +21 -0
  66. data/lib/generators/bugsage/install/templates/bugsage.rb +22 -0
  67. data/scripts/publish-github-release.sh +38 -0
  68. data/sig/bugsage.rbs +4 -0
  69. metadata +157 -0
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,301 @@
1
+ # Contributing to BugSage
2
+
3
+ Thank you for your interest in contributing to BugSage. This guide covers how to set up the project, run checks, and submit changes that are easy to review and merge.
4
+
5
+ Bug reports, documentation improvements, bug fixes, and new features are all welcome. By participating, you agree to follow our [Code of Conduct](CODE_OF_CONDUCT.md).
6
+
7
+ ## Table of contents
8
+
9
+ - [Development setup](#development-setup)
10
+ - [Running tests](#running-tests)
11
+ - [Coding standards](#coding-standards)
12
+ - [Project layout](#project-layout)
13
+ - [Branch naming](#branch-naming)
14
+ - [Commit message conventions](#commit-message-conventions)
15
+ - [Pull request guidelines](#pull-request-guidelines)
16
+ - [Reporting bugs](#reporting-bugs)
17
+ - [Suggesting features](#suggesting-features)
18
+ - [Release notes](#release-notes)
19
+
20
+ ## Development setup
21
+
22
+ ### Requirements
23
+
24
+ - **Ruby** `>= 3.2.0` (CI currently runs on Ruby 3.4)
25
+ - **Bundler**
26
+ - Git
27
+
28
+ ### Clone and install
29
+
30
+ ```bash
31
+ git clone https://github.com/MONARCHKOLI/bugsage.git
32
+ cd bugsage
33
+ bundle install
34
+ ```
35
+
36
+ ### Verify the setup
37
+
38
+ ```bash
39
+ bundle exec rake
40
+ ```
41
+
42
+ This runs the full default suite: RSpec and RuboCop. Both must pass before you open a pull request.
43
+
44
+ ### Optional: local Rails app
45
+
46
+ To manually exercise middleware, the error page, or the `/bugsage` dashboard, add this gem to a Rails app via path or Git:
47
+
48
+ ```ruby
49
+ # In the host app Gemfile
50
+ gem "bugsage", path: "/absolute/path/to/bugsage"
51
+ # or
52
+ gem "bugsage", github: "MONARCHKOLI/bugsage", branch: "your-branch"
53
+ ```
54
+
55
+ Then run `bundle install` and restart the Rails server.
56
+
57
+ ## Running tests
58
+
59
+ BugSage uses [RSpec](https://rspec.info/). Specs live under `spec/`.
60
+
61
+ ### Full suite
62
+
63
+ ```bash
64
+ bundle exec rake spec
65
+ # or
66
+ bundle exec rspec
67
+ ```
68
+
69
+ ### Focused examples
70
+
71
+ ```bash
72
+ bundle exec rspec spec/bugsage_spec.rb
73
+ bundle exec rspec spec/bugsage_spec.rb -e "captures API bad request"
74
+ ```
75
+
76
+ ### Default Rake task
77
+
78
+ ```bash
79
+ bundle exec rake
80
+ ```
81
+
82
+ Runs **specs** and **RuboCop**. Prefer this before pushing.
83
+
84
+ ### What to cover
85
+
86
+ When you change behavior, add or update specs that cover:
87
+
88
+ - happy path and important edge cases
89
+ - Rails-like response bodies (for example enumerable Rack bodies that do not implement `map`)
90
+ - configuration flags that alter capture or rendering
91
+ - i18n keys if you introduce or rename user-facing strings
92
+
93
+ Avoid committing secrets (API keys, credentials) in specs or fixtures.
94
+
95
+ ## Coding standards
96
+
97
+ ### Style and linting
98
+
99
+ - Style is enforced by [RuboCop](https://rubocop.org/) using `.rubocop.yml`
100
+ - Target Ruby version is **3.2**
101
+ - Prefer **double-quoted** strings (enforced by RuboCop)
102
+
103
+ ```bash
104
+ bundle exec rubocop
105
+ # or via Rake (uses .rubocop.yml and --force-exclusion)
106
+ bundle exec rake rubocop
107
+ ```
108
+
109
+ Auto-correct safe offenses when appropriate:
110
+
111
+ ```bash
112
+ bundle exec rubocop -A
113
+ ```
114
+
115
+ Do not weaken RuboCop rules or add broad excludes unless there is a clear, documented reason.
116
+
117
+ ### Ruby practices
118
+
119
+ - Keep `# frozen_string_literal: true` at the top of Ruby files
120
+ - Prefer small, focused modules under `lib/bugsage/`
121
+ - Match existing naming, error handling, and middleware patterns
122
+ - Prefer deterministic rules first; AI-related code should degrade gracefully when keys or providers are unavailable
123
+
124
+ ### User-facing strings
125
+
126
+ User-visible copy should go through `Bugsage.t` and live in `lib/bugsage/locales/en.yml` (or additional locale files). Avoid new hard-coded UI strings in Ruby or embedded HTML helpers unless they are truly non-user-facing (for example internal AI system prompts).
127
+
128
+ ### Security and safety
129
+
130
+ - Do not commit API keys, tokens, or credentials
131
+ - Apply-fix / filesystem write paths must remain limited to development and test
132
+ - Prefer fixes that preserve API response bodies when capturing HTTP errors (do not replace successful or intentional JSON/XML responses with BugSage HTML unless that is the intended error-page path)
133
+
134
+ ## Project layout
135
+
136
+ | Path | Purpose |
137
+ |------|---------|
138
+ | `lib/bugsage/` | Gem implementation |
139
+ | `lib/bugsage/locales/` | I18n strings |
140
+ | `lib/bugsage/railtie.rb` | Rails integration |
141
+ | `spec/` | RSpec suite |
142
+ | `exe/` | CLI entrypoints |
143
+ | `.rubocop.yml` | Lint configuration |
144
+ | `Rakefile` | `spec`, `rubocop`, and default task |
145
+ | `.github/workflows/` | CI |
146
+
147
+ ## Branch naming
148
+
149
+ Create a branch from the latest `master`:
150
+
151
+ ```bash
152
+ git checkout master
153
+ git pull origin master
154
+ git checkout -b <type>/<short-description>
155
+ ```
156
+
157
+ ### Recommended prefixes
158
+
159
+ | Prefix | Use for |
160
+ |--------|---------|
161
+ | `fix/` | Bug fixes |
162
+ | `feat/` | New features |
163
+ | `docs/` | Documentation only |
164
+ | `chore/` | Tooling, deps, CI, housekeeping |
165
+ | `refactor/` | Internal restructuring without behavior change |
166
+ | `test/` | Spec-only improvements |
167
+ | `perf/` | Performance improvements |
168
+
169
+ ### Examples
170
+
171
+ ```text
172
+ fix/rack-body-extract
173
+ feat/http-error-capture
174
+ docs/contributing-guide
175
+ chore/bump-rubocop
176
+ ```
177
+
178
+ Keep names lowercase, hyphen-separated, and short.
179
+
180
+ ## Commit message conventions
181
+
182
+ Write commits that explain **why** the change exists. Prefer one logical change per commit.
183
+
184
+ ### Format
185
+
186
+ ```text
187
+ <Imperative summary in sentence case>
188
+
189
+ Optional body explaining motivation, trade-offs, or follow-ups.
190
+ ```
191
+
192
+ ### Summary line
193
+
194
+ - Use the imperative mood: “Add…”, “Fix…”, “Capture…”, not “Added” or “Fixes”
195
+ - Keep the first line around **72 characters or fewer**
196
+ - Do not end the summary with a period
197
+ - Scope one concern per commit when practical
198
+
199
+ ### Optional conventional prefixes
200
+
201
+ These prefixes appear in the history and are welcome when they clarify intent:
202
+
203
+ | Prefix | Meaning |
204
+ |--------|---------|
205
+ | `feat:` | New user-facing capability |
206
+ | `fix:` | Bug fix |
207
+ | `docs:` | Documentation |
208
+ | `chore:` | Maintenance |
209
+ | `refactor:` | Code change without behavior change |
210
+ | `test:` | Tests only |
211
+
212
+ ### Good examples
213
+
214
+ ```text
215
+ Fix Rack body extraction for ActionDispatch::Response::RackBody
216
+
217
+ Rails API responses implement each but not map. Iterating with each
218
+ avoids NoMethodError when capturing HTTP error bodies.
219
+ ```
220
+
221
+ ```text
222
+ feat: add HTTP 4xx/5xx capture for API responses
223
+ ```
224
+
225
+ ```text
226
+ docs: add CONTRIBUTING.md with setup and PR guidelines
227
+ ```
228
+
229
+ ### Avoid
230
+
231
+ - Vague messages: `update`, `fix stuff`, `wip`
232
+ - Mixing unrelated refactors with feature work in the same commit
233
+ - Committing generated noise (for example local `.rspec_status`) unless intentionally required
234
+
235
+ ## Pull request guidelines
236
+
237
+ ### Before you open a PR
238
+
239
+ 1. Rebase or merge the latest `master` into your branch
240
+ 2. Run `bundle exec rake` locally and ensure it passes
241
+ 3. Add or update specs for behavior changes
242
+ 4. Update docs (`README.md`, `CHANGELOG.md` under `[Unreleased]`) when user-facing behavior changes
243
+ 5. Keep the diff focused; split large work into smaller PRs when possible
244
+
245
+ ### PR title
246
+
247
+ Use the same style as commit summaries, for example:
248
+
249
+ ```text
250
+ Fix Rack body extraction for Rails API responses
251
+ ```
252
+
253
+ ### PR description
254
+
255
+ Include:
256
+
257
+ - **Summary** — what changed and why
258
+ - **Test plan** — commands you ran and any manual steps (Postman, dummy Rails app, dashboard checks)
259
+ - **Screenshots** — for UI changes (error page, dashboard, AI panel)
260
+ - **Breaking changes** — call them out clearly, or state “None”
261
+
262
+ ### Review expectations
263
+
264
+ - CI must pass (`.github/workflows/ci.yml`: RSpec, RuboCop, bundle-audit, gem build/validate)
265
+ - Prefer small, reviewable PRs
266
+ - Respond to review feedback with follow-up commits rather than force-pushing rewritten history unless asked
267
+ - Do not include unrelated formatting sweeps
268
+
269
+ ### Merging
270
+
271
+ Maintainers typically merge after approval and green CI. Squash or merge strategy is up to maintainers; keep your branch history clean enough that either option works.
272
+
273
+ ## Reporting bugs
274
+
275
+ Open an issue on GitHub with:
276
+
277
+ - BugSage version (or Git commit SHA if using the gem from Git)
278
+ - Ruby and Rails versions
279
+ - Minimal reproduction steps
280
+ - Expected vs actual behavior
281
+ - Relevant logs or stack traces (redact secrets)
282
+ - Whether AI features or HTTP error capture were enabled
283
+
284
+ ## Suggesting features
285
+
286
+ Open an issue describing:
287
+
288
+ - the problem you want to solve
289
+ - proposed behavior
290
+ - alternatives considered
291
+ - whether it affects the default zero-config Rails experience
292
+
293
+ Features that change default middleware behavior (for example capturing non-exception HTTP responses) should document opt-out configuration when appropriate.
294
+
295
+ ## Release notes
296
+
297
+ User-facing changes should be noted under `[Unreleased]` in `CHANGELOG.md` using Keep a Changelog–style sections (`Added`, `Changed`, `Fixed`, `Removed`). Maintainers handle version bumps and gem releases using [docs/RELEASE_CHECKLIST.md](docs/RELEASE_CHECKLIST.md).
298
+
299
+ ## Questions
300
+
301
+ If something in this guide is unclear, open a GitHub issue or start a discussion on the related pull request. Thanks for helping improve BugSage.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,344 @@
1
+ <p align="center">
2
+ <img src="docs/images/BugSage_Logo.png" alt="BugSage — AI-powered debugging assistant for Ruby on Rails" width="420">
3
+ </p>
4
+
5
+ # BugSage
6
+
7
+ [![CI](https://github.com/MONARCHKOLI/bugsage/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/MONARCHKOLI/bugsage/actions/workflows/ci.yml)
8
+
9
+ BugSage is a Ruby gem for Ruby on Rails applications that helps developers understand exceptions faster. Instead of showing only a raw stack trace, BugSage classifies the error, explains the likely root cause, and suggests actionable fixes.
10
+
11
+ It uses deterministic rules first, with optional AI-powered refinement when enabled.
12
+
13
+ ## What BugSage does
14
+
15
+ - Catches common Rails and Ruby exceptions
16
+ - Classifies them into likely issue categories
17
+ - Surfaces the root cause in a simple report
18
+ - Suggests practical next steps
19
+ - Optionally refines suggestions with OpenAI or Cursor when configured
20
+ - Displays Rails request context such as path, method, controller, action, and parameters
21
+ - Provides a session dashboard at `/bugsage` in development
22
+ - Lets you chat with AI about a fix and apply refined code patches directly to your codebase
23
+
24
+ ## Screenshots
25
+
26
+ ![Exception page — NoMethodError on /boom](docs/images/NoMethodError2.png)
27
+
28
+ ![Dashboard — NoMethodError session detail](docs/images/NoMethodError.png)
29
+
30
+ ![Dashboard — HTTP 400 Response](docs/images/BadRequest.png)
31
+
32
+ ![API JSON response still returned for /bad_request](docs/images/BadRequest2.png)
33
+
34
+ ## Installation
35
+
36
+ ### Quick start (zero-config)
37
+
38
+ **1. Add the gem to your Gemfile**
39
+
40
+ ```ruby
41
+ gem "bugsage"
42
+ ```
43
+
44
+ **2. Install dependencies**
45
+
46
+ ```bash
47
+ bundle install
48
+ ```
49
+
50
+ **3. Start your Rails server**
51
+
52
+ ```bash
53
+ bin/rails server
54
+ ```
55
+
56
+ **4. Trigger an error in development**
57
+
58
+ Visit any route that raises an exception. You should see the BugSage error page.
59
+
60
+ **5. Open the session dashboard**
61
+
62
+ ```text
63
+ http://localhost:3000/bugsage
64
+ ```
65
+
66
+ No `routes.rb` changes, no middleware setup, and no `application.rb` edits are required. BugSage auto-wires everything through its Rails Railtie.
67
+
68
+ ### What gets auto-wired on boot
69
+
70
+ - Exception capture middleware
71
+ - BugSage HTML error pages in development
72
+ - Session dashboard at `/bugsage`
73
+ - Inline Rails console at `/bugsage/console`
74
+ - On-demand AI panel with Quick Fix, loading animation, and follow-up chat
75
+ - Surgical code patches (`delete_lines`, `replace_lines`, `insert_before`) with duplicate detection
76
+ - Dashboard fix actions (apply patch, open in editor, copy prompt, clear session)
77
+ - Routing error capture via `exceptions_app`
78
+ - AI provider auto-detection when API keys are present
79
+
80
+ ### Optional steps
81
+
82
+ **Generate a commented initializer** (only if you want custom overrides):
83
+
84
+ ```bash
85
+ bundle exec rails generate bugsage:install
86
+ ```
87
+
88
+ Or print the install guide and create the initializer:
89
+
90
+ ```bash
91
+ bundle exec bugsage install
92
+ ```
93
+
94
+ Print the guide without writing files:
95
+
96
+ ```bash
97
+ bundle exec bugsage install --guide-only
98
+ ```
99
+
100
+ **Enable AI-enhanced suggestions** (optional):
101
+
102
+ ```bash
103
+ export OPENAI_API_KEY=sk-your-openai-key-here
104
+ # or
105
+ export CURSOR_API_KEY=crsr_your-cursor-key-here
106
+ bin/rails server
107
+ ```
108
+
109
+ BugSage auto-detects the provider from the key prefix (`sk-...` → OpenAI, `crsr_...` → Cursor).
110
+
111
+ **Control enabled environments** (optional):
112
+
113
+ ```bash
114
+ export BUGSAGE_ENABLED_ENVIRONMENTS=development,test,staging
115
+ ```
116
+
117
+ Defaults to `development` and `test`.
118
+
119
+ The canonical install steps live in `lib/bugsage/installation.rb` (`Bugsage::Installation`).
120
+
121
+ ## Configuration
122
+
123
+ BugSage works with zero configuration. Override defaults only when needed in `config/initializers/bugsage.rb` or `config/application.rb`:
124
+
125
+ ```ruby
126
+ # config/initializers/bugsage.rb
127
+ Rails.application.configure do |config|
128
+ config.bugsage.enabled_environments = %i[development test staging]
129
+ config.bugsage.ai_enabled = true
130
+ config.bugsage.ai_provider = :cursor
131
+ end
132
+ ```
133
+
134
+ You can also configure at runtime:
135
+
136
+ ```ruby
137
+ Bugsage.configure do |config|
138
+ config.ai_enabled = true
139
+ config.openai_model = "gpt-4o-mini"
140
+ end
141
+ ```
142
+
143
+ ### Configuration options
144
+
145
+ | Option | Default | Description |
146
+ |--------|---------|-------------|
147
+ | `enabled_environments` | `development`, `test` | Environments where BugSage runs |
148
+ | `show_error_page` | `true` in development only | Replace errors with the BugSage HTML page |
149
+ | `show_dashboard` | `true` in development only | Serve the `/bugsage` session dashboard |
150
+ | `capture_errors` | `true` | Store caught errors in the in-memory session store |
151
+ | `ai_enabled` | auto (`true` when an API key is present) | Show the on-demand AI panel (does not auto-call the API) |
152
+ | `ai_provider` | auto-detected | `:openai` or `:cursor` (auto-detects `crsr_` keys) |
153
+ | `openai_api_key` | `nil` (falls back to env) | OpenAI API key (`sk-...`) |
154
+ | `openai_model` | `gpt-4o-mini` | Model used for OpenAI analysis |
155
+ | `openai_api_base` | `https://api.openai.com/v1` | OpenAI-compatible API base URL |
156
+ | `cursor_api_key` | `nil` (falls back to env) | Cursor API key (`crsr_...`) |
157
+ | `cursor_model` | `nil` (account default) | Cursor Cloud Agents model; omit to use your account default |
158
+ | `cursor_api_base` | `https://api.cursor.com` | Cursor API base URL |
159
+ | `ai_timeout` | `15` (`90` minimum for Cursor) | Request/poll timeout in seconds |
160
+ | `ai_client` | `nil` | Custom AI client (for testing or alternate providers) |
161
+
162
+ ### Default behavior by environment
163
+
164
+ | Environment | Error page | Dashboard | Capture | AI (if enabled) |
165
+ |-------------|------------|-----------|---------|-----------------|
166
+ | **development** | BugSage page | `/bugsage` | Yes | Yes |
167
+ | **test** | Rails default | Off | Yes (silent) | Yes |
168
+ | **production** | Off (disabled) | Off | Off | Off |
169
+
170
+ Restart the Rails server after changing configuration.
171
+
172
+ ### AI suggestions (on-demand)
173
+
174
+ When an API key is available, BugSage shows an **AI Suggestions** panel on the error page and `/bugsage` dashboard with:
175
+
176
+ - **Enable AI** toggle — turn AI requests on or off for your browser session (stored in `localStorage`)
177
+ - **Quick Fix Suggestion** button — calls the AI API only when you click it
178
+ - **Loading animation** — spinner, progress bar, and step messages while AI runs (especially helpful for Cursor’s longer responses)
179
+ - **💬 Chat** — follow-up conversation about the error, the suggested fix, or alternative approaches
180
+
181
+ This keeps error pages fast: rule-based analysis loads instantly, and AI runs only when you need it.
182
+
183
+ Flow:
184
+
185
+ 1. BugSage classifies the error with deterministic rules (instant)
186
+ 2. You click **Quick Fix Suggestion** when you want AI help
187
+ 3. BugSage sends exception details, numbered source context, and request context to the configured provider
188
+ 4. Fixes, confidence, AI notes, and a structured `code_patch` update in the page without a reload
189
+ 5. Use **💬 Chat** to ask questions, request alternatives (e.g. comment out a line instead of deleting it), or refine the fix
190
+ 6. When chat produces a new patch, the code preview and **Apply AI to Codebase** button update automatically
191
+
192
+ #### Structured code patches
193
+
194
+ AI responses include a surgical `code_patch` instead of blind string replacement:
195
+
196
+ | Action | Purpose |
197
+ |--------|---------|
198
+ | `delete_lines` | Remove stray/debug lines |
199
+ | `replace_lines` | Replace specific lines (e.g. comment out instead of delete) |
200
+ | `insert_before` | Insert new code before a line |
201
+ | `no_change` | File already contains the correct fix |
202
+
203
+ Patches use absolute line numbers from numbered source context (±20 lines around the error). BugSage rejects patches that would duplicate code already in the file and preserves indentation on apply.
204
+
205
+ #### Dashboard fix actions
206
+
207
+ After suggestions appear on the `/bugsage` dashboard, use the fix actions (dashboard only — no full-page reload):
208
+
209
+ - **Quick Fix Suggestion** — fetch AI analysis on demand
210
+ - **Apply AI to Codebase** — apply the current `code_patch` to your source file, then open it in Cursor or VS Code
211
+ - **Open in Cursor** / **Open in VS Code** — jump to the failing file and line
212
+ - **Copy Fix** — copy a prompt you can paste into your editor AI chat
213
+ - **Apply Fix to File** — insert a `# BUGSAGE:` comment above the failing line in development
214
+ - **Clear session logs** — wipe captured errors from the dashboard sidebar in place
215
+
216
+ Chat-refined patches are persisted in the session store, so **Apply AI to Codebase** always uses the latest patch from Quick Fix or chat.
217
+
218
+ #### BugSage API endpoints
219
+
220
+ BugSage registers these Rack endpoints automatically:
221
+
222
+ | Endpoint | Method | Purpose |
223
+ |----------|--------|---------|
224
+ | `/bugsage` | GET | Session dashboard |
225
+ | `/bugsage/console` | POST | Inline Rails console eval |
226
+ | `/bugsage/ai-suggest` | POST | On-demand Quick Fix AI enhancement |
227
+ | `/bugsage/ai-chat` | POST | Follow-up chat with optional `code_patch` updates |
228
+ | `/bugsage/apply-fix` | POST | Apply a `code_patch` to a source file (development/test only) |
229
+ | `/bugsage/clear` | POST | Clear session error store |
230
+
231
+ Disable AI entirely with `config.bugsage.ai_enabled = false`.
232
+
233
+ #### OpenAI
234
+
235
+ ```bash
236
+ export OPENAI_API_KEY=sk-your-openai-key-here
237
+ bin/rails server
238
+ ```
239
+
240
+ BugSage also reads `BUGSAGE_OPENAI_API_KEY`.
241
+
242
+ #### Cursor
243
+
244
+ If you only have a Cursor API key (`crsr_...`), BugSage can use the [Cursor Cloud Agents API](https://cursor.com/docs/cloud-agent/api/endpoints):
245
+
246
+ ```bash
247
+ export CURSOR_API_KEY=crsr_your-cursor-key-here
248
+ bin/rails server
249
+ ```
250
+
251
+ BugSage also reads `BUGSAGE_CURSOR_API_KEY`. If you already exported a Cursor key as `OPENAI_API_KEY`, BugSage auto-detects the `crsr_` prefix and routes to Cursor.
252
+
253
+ Optional explicit config:
254
+
255
+ ```ruby
256
+ config.bugsage.ai_enabled = true
257
+ config.bugsage.ai_provider = :cursor
258
+ # config.bugsage.cursor_model = "composer-2.5" # optional; omit for account default
259
+ ```
260
+
261
+ **Note:** Cursor analysis runs through a Cloud Agent and may take up to 90 seconds on the first response. OpenAI responses are usually much faster.
262
+
263
+ The API key must be available in the **same terminal** that starts the Rails server.
264
+
265
+ When AI enhancement succeeds, the error page and dashboard show an **AI-enhanced** badge and **AI notes**. If the API fails (e.g. invalid key, rate limit), BugSage shows rule-based suggestions and logs:
266
+
267
+ ```text
268
+ [BugSage] AI enhancement failed: ...
269
+ ```
270
+
271
+ ## Usage
272
+
273
+ When an exception is caught, BugSage renders a helpful page with:
274
+
275
+ - the exception name
276
+ - highlighted source code near the failure
277
+ - the message
278
+ - suggested fixes
279
+ - confidence score
280
+ - optional AI notes and code patch preview
281
+ - on-demand AI panel with loading animation and follow-up chat
282
+ - inline Rails console (development)
283
+ - Rails request context
284
+
285
+ Open the session dashboard at:
286
+
287
+ ```text
288
+ http://localhost:3000/bugsage
289
+ ```
290
+
291
+ ## Supported exceptions
292
+
293
+ BugSage handles many common Ruby and Rails exceptions, including:
294
+
295
+ ### Ruby
296
+ - `NoMethodError`, `NameError`, `KeyError`, `ArgumentError`, `TypeError`
297
+ - `ZeroDivisionError`, `JSON::ParserError`, `FrozenError`, `RuntimeError`
298
+
299
+ ### Rails / Active Record
300
+ - `ActionController::RoutingError`, `ActionController::ParameterMissing`
301
+ - `ActionController::UnpermittedParameters`, `ActionView::Template::Error`
302
+ - `ActiveRecord::RecordNotFound`, `ActiveRecord::RecordInvalid`
303
+ - `ActiveRecord::RecordNotUnique`, `ActiveRecord::StatementInvalid`
304
+ - `ActiveRecord::ConnectionNotEstablished`, and more
305
+
306
+ ### Generic fallback
307
+ Any other `StandardError` receives a generic BugSage suggestion.
308
+
309
+ ## How and where to check logs
310
+
311
+ When BugSage catches an exception, inspect:
312
+
313
+ - the BugSage error page in the browser
314
+ - the `/bugsage` dashboard for session history
315
+ - `log/development.log` or the terminal running `bin/rails server`
316
+ - `[BugSage] AI enhancement failed` warnings when AI is enabled but the API call fails
317
+
318
+ ## Development
319
+
320
+ After checking out the repo, run:
321
+
322
+ ```bash
323
+ bundle install
324
+ bundle exec rspec
325
+ ```
326
+
327
+ Try the minimal demo app:
328
+
329
+ ```bash
330
+ cd examples/sample_app
331
+ bundle install
332
+ bin/rails server
333
+ ```
334
+
335
+ See [examples/sample_app/README.md](examples/sample_app/README.md).
336
+
337
+ ## Contributing
338
+
339
+ Bug reports and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines, [ARCHITECTURE.md](ARCHITECTURE.md) for system design, and [ROADMAP.md](ROADMAP.md) for planned work.
340
+
341
+ ## License
342
+
343
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
344
+