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.
- checksums.yaml +7 -0
- data/ARCHITECTURE.md +442 -0
- data/CHANGELOG.md +28 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +301 -0
- data/LICENSE.txt +21 -0
- data/README.md +344 -0
- data/ROADMAP.md +217 -0
- data/SECURITY.md +83 -0
- data/docs/AI.md +167 -0
- data/docs/Configuration.md +168 -0
- data/docs/GettingStarted.md +146 -0
- data/docs/RELEASE_CHECKLIST.md +346 -0
- data/docs/Troubleshooting.md +181 -0
- data/docs/images/BadRequest.png +0 -0
- data/docs/images/BadRequest2.png +0 -0
- data/docs/images/BugSage_Logo.png +0 -0
- data/docs/images/BugSage_Social_Preview.png +0 -0
- data/docs/images/NoMethodError.png +0 -0
- data/docs/images/NoMethodError2.png +0 -0
- data/docs/images/README.md +38 -0
- data/docs/releases/README.md +21 -0
- data/docs/releases/v0.2.0.md +40 -0
- data/exe/bugsage +7 -0
- data/lib/bugsage/ai_analyzer.rb +145 -0
- data/lib/bugsage/ai_chat.rb +388 -0
- data/lib/bugsage/ai_context.rb +69 -0
- data/lib/bugsage/ai_panel.rb +708 -0
- data/lib/bugsage/ai_support.rb +36 -0
- data/lib/bugsage/auto_configurator.rb +97 -0
- data/lib/bugsage/cli.rb +59 -0
- data/lib/bugsage/code_context.rb +81 -0
- data/lib/bugsage/code_patch.rb +147 -0
- data/lib/bugsage/configuration.rb +149 -0
- data/lib/bugsage/console_context.rb +51 -0
- data/lib/bugsage/cursor_client.rb +165 -0
- data/lib/bugsage/dashboard.rb +627 -0
- data/lib/bugsage/editor_links.rb +34 -0
- data/lib/bugsage/error_page.rb +298 -0
- data/lib/bugsage/exception_handler.rb +66 -0
- data/lib/bugsage/exception_support.rb +95 -0
- data/lib/bugsage/exceptions_app.rb +31 -0
- data/lib/bugsage/fix_applicator.rb +107 -0
- data/lib/bugsage/formatter.rb +37 -0
- data/lib/bugsage/http_error_capture.rb +104 -0
- data/lib/bugsage/http_response_error.rb +14 -0
- data/lib/bugsage/inline_console.rb +226 -0
- data/lib/bugsage/installation.rb +94 -0
- data/lib/bugsage/installer.rb +66 -0
- data/lib/bugsage/json_endpoint.rb +34 -0
- data/lib/bugsage/locales/en.yml +439 -0
- data/lib/bugsage/middleware.rb +152 -0
- data/lib/bugsage/openai_client.rb +103 -0
- data/lib/bugsage/page_actions.rb +255 -0
- data/lib/bugsage/railtie.rb +49 -0
- data/lib/bugsage/request_context.rb +56 -0
- data/lib/bugsage/rule.rb +271 -0
- data/lib/bugsage/session_clear.rb +35 -0
- data/lib/bugsage/store.rb +60 -0
- data/lib/bugsage/suggestion.rb +58 -0
- data/lib/bugsage/trace_cleaner.rb +24 -0
- data/lib/bugsage/translations.rb +85 -0
- data/lib/bugsage/version.rb +5 -0
- data/lib/bugsage.rb +65 -0
- data/lib/generators/bugsage/install/install_generator.rb +21 -0
- data/lib/generators/bugsage/install/templates/bugsage.rb +22 -0
- data/scripts/publish-github-release.sh +38 -0
- data/sig/bugsage.rbs +4 -0
- metadata +157 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 72635552fb95259e516473d915bddc52999e395d87a04059fbc3cc01758ddeef
|
|
4
|
+
data.tar.gz: 7892ef79c17b9a77297e43282f5da94235c3e9dd53bd8750802a276b8fed7b7a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8c0fb401a30fa421e24f2c5f547a55f80a8ad2580eb2f4f1f3d7be4605d3d87b6184773d5a08997f5fa5f6967b14595772c3600c26a7f42a44cc0fbfa9f2f7ee
|
|
7
|
+
data.tar.gz: c5fcd6d1ecf9c242a90a1893e048e27f7c33348dd7347fb1e87e53a74c70e8add0ea1a2f2b7c1c41e23b39841269e93d019941c632220e44bfd6178620c92b6c
|
data/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document describes how BugSage is structured inside a Rails application: boot wiring, request flow, exception classification, AI enhancement, and the session dashboard.
|
|
4
|
+
|
|
5
|
+
Related docs: [ROADMAP.md](ROADMAP.md) · [docs/Configuration.md](docs/Configuration.md) · [docs/AI.md](docs/AI.md) · [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overall architecture
|
|
10
|
+
|
|
11
|
+
BugSage is a **development-oriented Rack middleware + Railtie** gem. It does not replace your application logic. It observes failures at the Rack/Rails boundary, classifies them with a deterministic rule engine, stores session events in memory, and optionally refines suggestions with an external AI provider **on demand**.
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart TB
|
|
15
|
+
subgraph Host["Rails application"]
|
|
16
|
+
App["Controllers / Views / Jobs"]
|
|
17
|
+
Rack["Rack stack"]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
subgraph BugSage["BugSage gem"]
|
|
21
|
+
Railtie["Railtie"]
|
|
22
|
+
MW["Middleware"]
|
|
23
|
+
EH["ExceptionHandler"]
|
|
24
|
+
Rules["Rule engine"]
|
|
25
|
+
Store["Store (in-memory)"]
|
|
26
|
+
UI["ErrorPage / Dashboard"]
|
|
27
|
+
AI["AiAnalyzer / AiChat"]
|
|
28
|
+
Providers["OpenAI / Cursor clients"]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Railtie --> MW
|
|
32
|
+
Railtie --> EH
|
|
33
|
+
Rack --> MW
|
|
34
|
+
MW --> App
|
|
35
|
+
MW --> EH
|
|
36
|
+
EH --> Rules
|
|
37
|
+
EH --> Store
|
|
38
|
+
EH --> UI
|
|
39
|
+
MW -->|"POST /bugsage/*"| AI
|
|
40
|
+
AI --> Providers
|
|
41
|
+
AI --> Store
|
|
42
|
+
UI --> Store
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Design principles**
|
|
46
|
+
|
|
47
|
+
| Principle | How it shows up |
|
|
48
|
+
|-----------|-----------------|
|
|
49
|
+
| Rules first | `Rule.match` always runs before AI |
|
|
50
|
+
| Zero-config | `Bugsage::Railtie` inserts middleware and `exceptions_app` |
|
|
51
|
+
| Safe writes | `FixApplicator` limited to development/test |
|
|
52
|
+
| Opt-in AI | Provider called only via Quick Fix / Chat endpoints |
|
|
53
|
+
| Pass-through HTTP | API 4xx/5xx bodies are captured without replacing the client response |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Folder structure
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
lib/
|
|
61
|
+
bugsage.rb # gem entry: requires, Bugsage.configure / .t
|
|
62
|
+
bugsage/
|
|
63
|
+
railtie.rb # Rails boot hooks
|
|
64
|
+
configuration.rb # settings + predicates
|
|
65
|
+
auto_configurator.rb # env-based defaults (keys, environments)
|
|
66
|
+
middleware.rb # Rack entry + /bugsage routes
|
|
67
|
+
exception_handler.rb # classify → store → optionally render
|
|
68
|
+
exceptions_app.rb # Rails exceptions_app adapter
|
|
69
|
+
exception_support.rb # unwrap / extract exceptions from env
|
|
70
|
+
rule.rb # deterministic classification
|
|
71
|
+
suggestion.rb # suggestion value object
|
|
72
|
+
store.rb # in-memory session event list
|
|
73
|
+
http_error_capture.rb # HTTP ≥ 400 → HttpResponseError
|
|
74
|
+
http_response_error.rb
|
|
75
|
+
error_page.rb # HTML error page
|
|
76
|
+
dashboard.rb # HTML session dashboard
|
|
77
|
+
inline_console.rb # POST /bugsage/console
|
|
78
|
+
ai_panel.rb # POST /bugsage/ai-suggest + UI panel
|
|
79
|
+
ai_chat.rb # POST /bugsage/ai-chat
|
|
80
|
+
ai_analyzer.rb # AI prompt + merge into Suggestion
|
|
81
|
+
ai_context.rb # request-scoped AI context
|
|
82
|
+
openai_client.rb
|
|
83
|
+
cursor_client.rb
|
|
84
|
+
code_patch.rb # surgical patch model
|
|
85
|
+
fix_applicator.rb # POST /bugsage/apply-fix
|
|
86
|
+
page_actions.rb # dashboard/error action UI
|
|
87
|
+
editor_links.rb # Cursor / VS Code deep links
|
|
88
|
+
code_context.rb # source frames + HTML helpers
|
|
89
|
+
trace_cleaner.rb # filter framework frames
|
|
90
|
+
translations.rb # Bugsage.t + locale loading
|
|
91
|
+
locales/en.yml
|
|
92
|
+
formatter.rb # terminal formatter (CLI)
|
|
93
|
+
cli.rb / installation.rb / installer.rb
|
|
94
|
+
generators/bugsage/install/
|
|
95
|
+
exe/bugsage
|
|
96
|
+
docs/
|
|
97
|
+
spec/
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Runtime assets shipped in the gem are primarily under `lib/bugsage/` (plus `exe/` and docs when packaged).
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Main components
|
|
105
|
+
|
|
106
|
+
| Component | Responsibility |
|
|
107
|
+
|-----------|----------------|
|
|
108
|
+
| **`Railtie`** | Register config, middleware, `exceptions_app`, debug interceptor, i18n |
|
|
109
|
+
| **`Middleware`** | Serve BugSage endpoints; wrap `@app.call`; capture exceptions / HTTP errors |
|
|
110
|
+
| **`ExceptionsApp`** | Handle Rails-routed exception responses (`/404`, etc.) |
|
|
111
|
+
| **`ExceptionHandler`** | Orchestrate extract → `Rule.match` → `Store` → render |
|
|
112
|
+
| **`Rule`** | Map exception classes/messages to `Suggestion` |
|
|
113
|
+
| **`Suggestion`** | Issue, location, root cause, fixes, confidence, optional `code_patch` |
|
|
114
|
+
| **`Store`** | Process-local ring buffer of session events (max 100) |
|
|
115
|
+
| **`HttpErrorCapture`** | Build synthetic `HttpResponseError` from status + body |
|
|
116
|
+
| **`ErrorPage` / `Dashboard`** | HTML UIs over a suggestion or `Store.all` |
|
|
117
|
+
| **`AiPanel` / `AiChat` / `AiAnalyzer`** | On-demand AI enhancement and chat refinement |
|
|
118
|
+
| **`CodePatch` / `FixApplicator`** | Parse, preview, and apply surgical edits |
|
|
119
|
+
| **`Configuration` / `AutoConfigurator`** | Explicit + env-driven settings |
|
|
120
|
+
| **`JsonEndpoint` / `RequestContext` / `AiSupport`** | Shared Rack JSON, request context, and AI helpers |
|
|
121
|
+
| **`Translations`** | Locale YAML and `Bugsage.t` |
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Railtie initialization
|
|
126
|
+
|
|
127
|
+
When Rails boots and the gem is loaded (`require "bugsage"` loads the Railtie if `Rails::Railtie` is defined), BugSage registers several initializers:
|
|
128
|
+
|
|
129
|
+
```mermaid
|
|
130
|
+
sequenceDiagram
|
|
131
|
+
participant Rails
|
|
132
|
+
participant Railtie as Bugsage::Railtie
|
|
133
|
+
participant Config as Configuration
|
|
134
|
+
participant Auto as AutoConfigurator
|
|
135
|
+
participant App as Rails::Application
|
|
136
|
+
|
|
137
|
+
Rails->>Railtie: load railtie
|
|
138
|
+
Railtie->>App: config.bugsage = OrderedOptions
|
|
139
|
+
Railtie->>Config: copy app.config.bugsage.*
|
|
140
|
+
Railtie->>Auto: apply!(ENV)
|
|
141
|
+
Note over Auto: BUGSAGE_ENABLED_ENVIRONMENTS<br/>OPENAI_/CURSOR_ API keys
|
|
142
|
+
Railtie->>Railtie: Translations.load!
|
|
143
|
+
Railtie->>App: middleware.use Middleware
|
|
144
|
+
Railtie->>App: exceptions_app = ExceptionsApp
|
|
145
|
+
Railtie->>App: DebugExceptions interceptor → store_exception
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Initializers (in order of intent)
|
|
149
|
+
|
|
150
|
+
1. **`bugsage.configuration`** — Copy `config.bugsage` options into `Bugsage.configuration`, then run `AutoConfigurator.apply!`
|
|
151
|
+
2. **`bugsage.i18n`** — Load `lib/bugsage/locales/*.yml`
|
|
152
|
+
3. **`bugsage.middleware`** — `app.config.middleware.use Bugsage::Middleware`
|
|
153
|
+
4. **`bugsage.exceptions_app`** — Preserve previous `exceptions_app` as fallback; set `Bugsage::ExceptionsApp`
|
|
154
|
+
5. **`bugsage.debug_interceptor`** — When Rails debug exceptions fire, silently `store_exception` if capture is enabled
|
|
155
|
+
|
|
156
|
+
No `routes.rb` changes are required: BugSage endpoints are handled inside the middleware by path/method matching.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Middleware flow
|
|
161
|
+
|
|
162
|
+
`Bugsage::Middleware#call` is the primary runtime entry point.
|
|
163
|
+
|
|
164
|
+
```mermaid
|
|
165
|
+
flowchart TD
|
|
166
|
+
Start([HTTP request]) --> Path{PATH_INFO?}
|
|
167
|
+
|
|
168
|
+
Path -->|GET /bugsage| Dash[Dashboard.render Store.all]
|
|
169
|
+
Path -->|POST /bugsage/console| Console[InlineConsole]
|
|
170
|
+
Path -->|POST /bugsage/ai-suggest| Suggest[AiPanel]
|
|
171
|
+
Path -->|POST /bugsage/ai-chat| Chat[AiChat]
|
|
172
|
+
Path -->|POST /bugsage/apply-fix| Apply[FixApplicator]
|
|
173
|
+
Path -->|POST /bugsage/clear| Clear[SessionClear]
|
|
174
|
+
Path -->|other| Enabled{config.enabled?}
|
|
175
|
+
|
|
176
|
+
Enabled -->|no| AppOnly[Pass to @app]
|
|
177
|
+
Enabled -->|yes| AppCall["status, headers, body = @app.call(env)"]
|
|
178
|
+
|
|
179
|
+
AppCall --> Extract[Extract body via each]
|
|
180
|
+
Extract --> Own{Already a BugSage HTML response?}
|
|
181
|
+
Own -->|yes| Pass[Pass through]
|
|
182
|
+
Own -->|no| Cascade{X-Cascade: pass?}
|
|
183
|
+
Cascade -->|yes| RouteCap[Synthesize RoutingError → capture]
|
|
184
|
+
Cascade -->|no| Exc{Exception in env?}
|
|
185
|
+
Exc -->|yes| CapExc[capture_exception]
|
|
186
|
+
CapExc -->|show_error_page| Page[ExceptionHandler.render_response]
|
|
187
|
+
CapExc -->|capture only| StoreOnly[ExceptionHandler.store_exception]
|
|
188
|
+
Exc -->|no| HTTP{status >= 400 and capture_http_errors?}
|
|
189
|
+
HTTP -->|yes| CapHTTP[store_http_error]
|
|
190
|
+
HTTP -->|no| Pass
|
|
191
|
+
CapHTTP --> Pass
|
|
192
|
+
RouteCap --> Page
|
|
193
|
+
Page --> End([Rack triple])
|
|
194
|
+
Pass --> End
|
|
195
|
+
Dash --> End
|
|
196
|
+
Console --> End
|
|
197
|
+
Suggest --> End
|
|
198
|
+
Chat --> End
|
|
199
|
+
Apply --> End
|
|
200
|
+
Clear --> End
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Body handling
|
|
204
|
+
|
|
205
|
+
Rails API responses often use `ActionDispatch::Response::RackBody`, which implements `each` but not `map`. Middleware collects parts with `each`, closes the original body, then returns a new array body so capture and pass-through remain safe.
|
|
206
|
+
|
|
207
|
+
### Capture modes
|
|
208
|
+
|
|
209
|
+
| Mode | When | Outcome |
|
|
210
|
+
|------|------|---------|
|
|
211
|
+
| Render error page | `show_error_page?` (default: development) | Replace response with BugSage HTML |
|
|
212
|
+
| Store only | `capture_errors?` without show page (for example test) | Keep Rails response; add `Store` event |
|
|
213
|
+
| HTTP capture | status ≥ 400, no exception, not a BugSage path | Store `HttpResponseError`; **preserve** original body |
|
|
214
|
+
| Disabled | env not in `enabled_environments` | Middleware no-ops after endpoint short-circuits |
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Exception handling
|
|
219
|
+
|
|
220
|
+
```mermaid
|
|
221
|
+
flowchart LR
|
|
222
|
+
Exc[Exception or HttpResponseError] --> Support[ExceptionSupport.unwrap / extract]
|
|
223
|
+
Support --> Rule[Rule.match]
|
|
224
|
+
Rule --> Sug[Suggestion]
|
|
225
|
+
Sug --> Store[Store.add]
|
|
226
|
+
Sug --> Ctx[ConsoleContext / AiContext]
|
|
227
|
+
Sug --> Page{render?}
|
|
228
|
+
Page -->|yes| HTML[ErrorPage.render]
|
|
229
|
+
Page -->|no| Done[Return / continue]
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Pipeline (`ExceptionHandler.process`)
|
|
233
|
+
|
|
234
|
+
1. Ensure BugSage is `enabled?`
|
|
235
|
+
2. `ExceptionSupport.extract` / unwrap Rails wrappers
|
|
236
|
+
3. `Rule.match(exception)` → `Suggestion` (or bail)
|
|
237
|
+
4. Build request context from Rack env
|
|
238
|
+
5. `Store.add` when `capture_errors?`
|
|
239
|
+
6. Set console / AI context when those features are active
|
|
240
|
+
7. Optionally return `[status, headers, ErrorPage HTML]`
|
|
241
|
+
|
|
242
|
+
### Rules
|
|
243
|
+
|
|
244
|
+
`Rule::MATCHERS` is an ordered list of class (and optional message) definitions. More specific classes must appear before parents (for example `NoMethodError` before `NameError`). Unmatched exceptions receive a generic suggestion.
|
|
245
|
+
|
|
246
|
+
HTTP API failures become `Bugsage::HttpResponseError`, which has its own matcher/handler.
|
|
247
|
+
|
|
248
|
+
### Parallel entry: `ExceptionsApp`
|
|
249
|
+
|
|
250
|
+
Rails may invoke `config.exceptions_app` for routing and certain public exception flows. `ExceptionsApp` extracts the exception and delegates to `ExceptionHandler`, with a fallback to the previous exceptions app when BugSage does not handle the case.
|
|
251
|
+
|
|
252
|
+
### Debug interceptor
|
|
253
|
+
|
|
254
|
+
`ActionDispatch::DebugExceptions.register_interceptor` stores exceptions even when Rails is already rendering its own debug page—useful when capture is on but the BugSage HTML page is not replacing the response.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## AI integration
|
|
259
|
+
|
|
260
|
+
AI is **never** invoked automatically during exception render. Rendering stays rule-based; AI runs only when the UI posts to BugSage endpoints.
|
|
261
|
+
|
|
262
|
+
```mermaid
|
|
263
|
+
sequenceDiagram
|
|
264
|
+
participant Browser
|
|
265
|
+
participant MW as Middleware
|
|
266
|
+
participant Panel as AiPanel / AiChat
|
|
267
|
+
participant Analyzer as AiAnalyzer
|
|
268
|
+
participant Client as OpenAiClient / CursorClient
|
|
269
|
+
participant Store
|
|
270
|
+
|
|
271
|
+
Browser->>MW: Exception → ErrorPage / Dashboard HTML
|
|
272
|
+
Note over Browser,Store: Suggestion is rules-only; Store has event
|
|
273
|
+
Browser->>MW: POST /bugsage/ai-suggest
|
|
274
|
+
MW->>Panel: handle_request
|
|
275
|
+
Panel->>Analyzer: enhance(suggestion, exception, context)
|
|
276
|
+
Analyzer->>Client: complete(system, user)
|
|
277
|
+
Client-->>Analyzer: JSON (+ code_patch)
|
|
278
|
+
Analyzer-->>Panel: hybrid Suggestion
|
|
279
|
+
Panel->>Store: update_at(index)
|
|
280
|
+
Panel-->>Browser: JSON fixes / patch preview
|
|
281
|
+
|
|
282
|
+
Browser->>MW: POST /bugsage/ai-chat
|
|
283
|
+
MW->>Panel: AiChat.handle_request
|
|
284
|
+
Panel->>Client: chat(...)
|
|
285
|
+
Panel->>Store: persist refined code_patch
|
|
286
|
+
Panel-->>Browser: reply + code_patch
|
|
287
|
+
|
|
288
|
+
Browser->>MW: POST /bugsage/apply-fix
|
|
289
|
+
Note over MW: FixApplicator (dev/test only)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Components
|
|
293
|
+
|
|
294
|
+
| Piece | Role |
|
|
295
|
+
|-------|------|
|
|
296
|
+
| `AiContext` | Holds last exception/suggestion for the page or dashboard row |
|
|
297
|
+
| `AiPanel` | Quick Fix endpoint + embedded panel UI/JS |
|
|
298
|
+
| `AiChat` | Follow-up chat; may return updated `code_patch` |
|
|
299
|
+
| `AiAnalyzer` | Builds prompts, calls client, merges into `Suggestion` |
|
|
300
|
+
| `OpenAiClient` / `CursorClient` | HTTP providers (`CursorClient` polls Cloud Agents; longer timeout) |
|
|
301
|
+
| `CodePatch` | `delete_lines` / `replace_lines` / `insert_before` / `no_change` |
|
|
302
|
+
|
|
303
|
+
Provider selection: explicit `ai_provider`, else key prefix (`crsr_` → Cursor, otherwise OpenAI). See [docs/AI.md](docs/AI.md).
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Dashboard
|
|
308
|
+
|
|
309
|
+
The dashboard is an HTML UI rendered by `Dashboard.render(Store.all)` for `GET /bugsage`.
|
|
310
|
+
|
|
311
|
+
```mermaid
|
|
312
|
+
flowchart TB
|
|
313
|
+
Store[(Store.all)] --> Dash[Dashboard.render]
|
|
314
|
+
Dash --> List[Sidebar: issues + confidence]
|
|
315
|
+
Dash --> Detail[Detail: source, fixes, context]
|
|
316
|
+
Detail --> Actions[PageActions / AI panel / Chat]
|
|
317
|
+
Actions --> Endpoints["/bugsage/ai-suggest · ai-chat · apply-fix · clear · console"]
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**Characteristics**
|
|
321
|
+
|
|
322
|
+
- In-memory, per Rails process (cleared on restart)
|
|
323
|
+
- Newest events first; capped at `Store::MAX_ENTRIES` (100)
|
|
324
|
+
- Includes both raised exceptions and captured HTTP errors
|
|
325
|
+
- Fix actions (apply patch, open editor, clear) are dashboard-centric; the full-page error view focuses on analysis + console + AI panel
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Configuration
|
|
330
|
+
|
|
331
|
+
Configuration is a plain Ruby object (`Bugsage::Configuration`) accessed via:
|
|
332
|
+
|
|
333
|
+
```ruby
|
|
334
|
+
Bugsage.configure { |config| ... }
|
|
335
|
+
# or Rails
|
|
336
|
+
Rails.application.configure do |config|
|
|
337
|
+
config.bugsage.ai_enabled = true
|
|
338
|
+
end
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
```mermaid
|
|
342
|
+
flowchart LR
|
|
343
|
+
Init["config/initializers or application.rb"] --> Ordered["app.config.bugsage"]
|
|
344
|
+
Ordered --> Copy[Railtie copies into Bugsage.configuration]
|
|
345
|
+
Env["ENV vars"] --> Auto[AutoConfigurator.apply!]
|
|
346
|
+
Auto --> Copy
|
|
347
|
+
Copy --> Predicates["enabled? show_error_page? capture_http_errors? ai_configured? ..."]
|
|
348
|
+
Predicates --> Runtime[Middleware / Handler / AI]
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Important env knobs:
|
|
352
|
+
|
|
353
|
+
- `BUGSAGE_ENABLED_ENVIRONMENTS`
|
|
354
|
+
- `OPENAI_API_KEY` / `BUGSAGE_OPENAI_API_KEY`
|
|
355
|
+
- `CURSOR_API_KEY` / `BUGSAGE_CURSOR_API_KEY`
|
|
356
|
+
|
|
357
|
+
Full option table: [docs/Configuration.md](docs/Configuration.md).
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Future plugin architecture
|
|
362
|
+
|
|
363
|
+
BugSage does not yet ship a formal plugin API. The roadmap targets a small, stable extension surface that preserves **rules first**.
|
|
364
|
+
|
|
365
|
+
### Intended extension points (v0.5 → v2.0)
|
|
366
|
+
|
|
367
|
+
```mermaid
|
|
368
|
+
flowchart TB
|
|
369
|
+
Core[BugSage core] --> RulesAPI[Rule registry]
|
|
370
|
+
Core --> Enrichers[Suggestion enrichers]
|
|
371
|
+
Core --> Providers[AI provider interface]
|
|
372
|
+
Core --> Sinks[Event sinks / Store adapters]
|
|
373
|
+
|
|
374
|
+
PluginA[Custom rules gem] --> RulesAPI
|
|
375
|
+
PluginB[Datadog / file store] --> Sinks
|
|
376
|
+
PluginC[Local LLM provider] --> Providers
|
|
377
|
+
PluginD[Security checks pack] --> Enrichers
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
| Hook | Purpose | Compatibility goal |
|
|
381
|
+
|------|---------|-------------------|
|
|
382
|
+
| **Rule registry** | Register matchers without editing `rule.rb` | Same `Suggestion` shape |
|
|
383
|
+
| **AI provider interface** | `#complete` / `#chat` like existing clients | Drop-in via `config.ai_client` (already partially supported) |
|
|
384
|
+
| **Enrichers** | Post-process suggestions (security/performance notes) | Pure functions; no Rack coupling |
|
|
385
|
+
| **Store adapters** | Persist beyond process memory | Implement `add` / `all` / `update_at` / `clear!` |
|
|
386
|
+
| **Event filters** | Skip capture for paths/statuses | Called from middleware before store |
|
|
387
|
+
|
|
388
|
+
### Near-term approach (before a formal API)
|
|
389
|
+
|
|
390
|
+
Until plugins land:
|
|
391
|
+
|
|
392
|
+
1. Prefer contributing rules upstream with specs
|
|
393
|
+
2. Use `config.ai_client` for alternate providers in tests or private apps
|
|
394
|
+
3. Keep host-app overrides in an initializer rather than monkey-patching middleware
|
|
395
|
+
|
|
396
|
+
Design constraints for future plugins:
|
|
397
|
+
|
|
398
|
+
- Must not auto-call AI on every exception
|
|
399
|
+
- Must not enable production writing of patches by default
|
|
400
|
+
- Must document whether they change zero-config defaults
|
|
401
|
+
|
|
402
|
+
See [ROADMAP.md](ROADMAP.md) for milestone placement.
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Request & data lifecycle (summary)
|
|
407
|
+
|
|
408
|
+
```mermaid
|
|
409
|
+
stateDiagram-v2
|
|
410
|
+
[*] --> Request
|
|
411
|
+
Request --> BugSageEndpoint: /bugsage*
|
|
412
|
+
Request --> App: enabled?
|
|
413
|
+
App --> Classified: exception or HTTP≥400
|
|
414
|
+
App --> PassThrough: success / ignored
|
|
415
|
+
Classified --> Stored: Suggestion in Store
|
|
416
|
+
Stored --> Rendered: ErrorPage optional
|
|
417
|
+
Stored --> Enhanced: user triggers AI
|
|
418
|
+
Enhanced --> Patched: user applies code_patch
|
|
419
|
+
BugSageEndpoint --> [*]
|
|
420
|
+
PassThrough --> [*]
|
|
421
|
+
Rendered --> [*]
|
|
422
|
+
Patched --> [*]
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## Key files cheat sheet
|
|
428
|
+
|
|
429
|
+
| Concern | Start here |
|
|
430
|
+
|---------|------------|
|
|
431
|
+
| Boot | `lib/bugsage/railtie.rb` |
|
|
432
|
+
| Request flow | `lib/bugsage/middleware.rb` |
|
|
433
|
+
| Classify / render / store | `lib/bugsage/exception_handler.rb`, `rule.rb` |
|
|
434
|
+
| HTTP capture | `http_error_capture.rb` |
|
|
435
|
+
| UI | `error_page.rb`, `dashboard.rb` |
|
|
436
|
+
| AI | `ai_panel.rb`, `ai_chat.rb`, `ai_analyzer.rb` |
|
|
437
|
+
| Patches | `code_patch.rb`, `fix_applicator.rb` |
|
|
438
|
+
| Settings | `configuration.rb`, `auto_configurator.rb` |
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
*This architecture reflects BugSage v0.2.x. Update this document when boot wiring, store persistence, or the plugin API changes.*
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
## [0.2.0] - 2026-07-13
|
|
4
|
+
|
|
5
|
+
GitHub release notes: [docs/releases/v0.2.0.md](docs/releases/v0.2.0.md)
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Zero-config Rails setup via `Bugsage::AutoConfigurator` on boot
|
|
9
|
+
- `rails generate bugsage:install` generator and `bundle exec bugsage install` CLI
|
|
10
|
+
- `Bugsage::Installation` guide with canonical install steps
|
|
11
|
+
- Inline Rails console on error page and `/bugsage` dashboard
|
|
12
|
+
- Optional AI-enhanced suggestions with OpenAI and Cursor providers
|
|
13
|
+
- Auto-detection of API key type (`sk-...` vs `crsr_...`) from environment variables
|
|
14
|
+
- Session dashboard at `/bugsage` with split-pane layout and source highlighting
|
|
15
|
+
- Env-based configuration through Rails Railtie and `config.bugsage`
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- AI is auto-enabled when an API key is present (override with `config.bugsage.ai_enabled = false`)
|
|
19
|
+
- README updated with step-by-step zero-config installation guide
|
|
20
|
+
|
|
21
|
+
## [0.1.1] - 2026-07-09
|
|
22
|
+
|
|
23
|
+
- Expanded Rails exception handling for routing, parameter, template, storage, Redis, Faraday, CSRF, flash, and signed-message errors
|
|
24
|
+
- Added regression coverage for the new exception categories
|
|
25
|
+
|
|
26
|
+
## [0.1.0] - 2026-07-08
|
|
27
|
+
|
|
28
|
+
- Initial release
|
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
"bugsage" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
|
|
4
|
+
|
|
5
|
+
* Participants will be tolerant of opposing views.
|
|
6
|
+
* Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
|
|
7
|
+
* When interpreting the words and actions of others, participants should always assume good intentions.
|
|
8
|
+
* Behaviour which can be reasonably considered harassment will not be tolerated.
|
|
9
|
+
|
|
10
|
+
If you have any concerns about behaviour within this project, please contact us at ["TODO: Write your email address"](mailto:"TODO: Write your email address").
|