binocs 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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README.md +528 -0
  4. data/Rakefile +7 -0
  5. data/app/assets/javascripts/binocs/application.js +105 -0
  6. data/app/assets/stylesheets/binocs/application.css +67 -0
  7. data/app/channels/binocs/application_cable/channel.rb +8 -0
  8. data/app/channels/binocs/application_cable/connection.rb +8 -0
  9. data/app/channels/binocs/requests_channel.rb +13 -0
  10. data/app/controllers/binocs/application_controller.rb +62 -0
  11. data/app/controllers/binocs/requests_controller.rb +69 -0
  12. data/app/helpers/binocs/application_helper.rb +61 -0
  13. data/app/models/binocs/application_record.rb +7 -0
  14. data/app/models/binocs/request.rb +198 -0
  15. data/app/views/binocs/requests/_empty_list.html.erb +9 -0
  16. data/app/views/binocs/requests/_request.html.erb +61 -0
  17. data/app/views/binocs/requests/index.html.erb +115 -0
  18. data/app/views/binocs/requests/show.html.erb +227 -0
  19. data/app/views/layouts/binocs/application.html.erb +109 -0
  20. data/config/importmap.rb +6 -0
  21. data/config/routes.rb +11 -0
  22. data/db/migrate/20240101000000_create_binocs_requests.rb +36 -0
  23. data/exe/binocs +86 -0
  24. data/lib/binocs/agent.rb +153 -0
  25. data/lib/binocs/agent_context.rb +165 -0
  26. data/lib/binocs/agent_manager.rb +302 -0
  27. data/lib/binocs/configuration.rb +65 -0
  28. data/lib/binocs/engine.rb +61 -0
  29. data/lib/binocs/log_subscriber.rb +56 -0
  30. data/lib/binocs/middleware/request_recorder.rb +264 -0
  31. data/lib/binocs/swagger/client.rb +100 -0
  32. data/lib/binocs/swagger/path_matcher.rb +118 -0
  33. data/lib/binocs/tui/agent_output.rb +163 -0
  34. data/lib/binocs/tui/agents_list.rb +195 -0
  35. data/lib/binocs/tui/app.rb +726 -0
  36. data/lib/binocs/tui/colors.rb +115 -0
  37. data/lib/binocs/tui/filter_menu.rb +162 -0
  38. data/lib/binocs/tui/help_screen.rb +93 -0
  39. data/lib/binocs/tui/request_detail.rb +899 -0
  40. data/lib/binocs/tui/request_list.rb +268 -0
  41. data/lib/binocs/tui/spirit_animal.rb +235 -0
  42. data/lib/binocs/tui/window.rb +98 -0
  43. data/lib/binocs/tui.rb +24 -0
  44. data/lib/binocs/version.rb +5 -0
  45. data/lib/binocs.rb +27 -0
  46. data/lib/generators/binocs/install/install_generator.rb +61 -0
  47. data/lib/generators/binocs/install/templates/create_binocs_requests.rb +36 -0
  48. data/lib/generators/binocs/install/templates/initializer.rb +25 -0
  49. data/lib/tasks/binocs_tasks.rake +38 -0
  50. metadata +149 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 951ede246b19df8711837e0024c936962a8e56c60351a1fa1c47202ff6923ebb
4
+ data.tar.gz: b21a7315ffd445e61326d0bc7332431cde04f7d44510fdfda24f0938351717a2
5
+ SHA512:
6
+ metadata.gz: 10ec890ba59758423105071b00baa05183d9a22e51b92106831b9b8c4f40d11d8bdc1c391934bc99a1f426c50e012523ce74c4442602c93b32ba3bd3d51389fd
7
+ data.tar.gz: 50c57ebe70c4997edf303bb7bbdda1fd29d2a03474317c4f93fa9281aceaa97b9ee05c23b45ccc9f7ad32c7c1b72a74b542220a22396de92796e34822ca09c7f
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Zincan
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,528 @@
1
+ # Binocs
2
+
3
+ A Laravel Telescope-inspired request monitoring dashboard for Rails applications. Binocs provides real-time visibility into HTTP requests through both a web interface and a terminal UI with vim-style navigation, making debugging and development easier whether you prefer the browser or the command line.
4
+
5
+ ## Features
6
+
7
+ - **Real-time Request Monitoring**: Watch requests stream in as they happen via ActionCable/Turbo Streams
8
+ - **Comprehensive Request Details**: View params, headers, request/response bodies, logs, and exceptions
9
+ - **Powerful Filtering**: Filter by HTTP method, status code, path, controller, and more
10
+ - **Exception Tracking**: Quickly identify and debug errors with full backtrace
11
+ - **Performance Insights**: Track request duration and memory usage
12
+ - **Dark Theme UI**: Beautiful, modern interface built with Tailwind CSS
13
+ - **Terminal UI (TUI)**: Vim-style keyboard navigation for console-based monitoring
14
+ - **AI Agent Integration**: Launch Claude Code or OpenCode directly from request context to debug issues
15
+ - **Swagger Integration**: View OpenAPI documentation for requests and jump to Swagger UI
16
+ - **Production Safe**: Automatically disabled in production environments
17
+
18
+ ## Screenshots
19
+
20
+ ### Web Dashboard
21
+
22
+ ![Web Dashboard - Request List](docs/images/html-list-view.jpg)
23
+ *Real-time request monitoring with filtering and status indicators*
24
+
25
+ ![Web Dashboard - Request Details](docs/images/html-detail-view.jpg)
26
+ *Detailed view showing params, headers, body, logs, and exceptions*
27
+
28
+ ### Terminal UI (TUI)
29
+
30
+ ![TUI - Request List](docs/images/tui-list-view.jpg)
31
+ *Vim-style navigation in your terminal*
32
+
33
+ ![TUI - Request Details](docs/images/tui-detail-view.jpg)
34
+ *Split-screen detail view with tabbed content*
35
+
36
+ ### AI Agent Integration
37
+
38
+ ![AI Agent View](docs/images/ai-view.jpg)
39
+ *Launch AI coding agents directly from request context*
40
+
41
+ ## Requirements
42
+
43
+ - Ruby 3.0+
44
+ - Rails 7.0+
45
+ - ActionCable (for real-time updates)
46
+ - ncurses development libraries (for TUI - typically pre-installed on macOS/Linux)
47
+
48
+ ## Installation
49
+
50
+ ### 1. Add Binocs to your Gemfile
51
+
52
+ ```ruby
53
+ # Gemfile
54
+ gem 'binocs', path: 'path/to/binocs' # For local development
55
+
56
+ # Or from GitHub (once published)
57
+ # gem 'binocs', github: 'zincan/binocs'
58
+ ```
59
+
60
+ ### 2. Install the gem
61
+
62
+ ```bash
63
+ bundle install
64
+ ```
65
+
66
+ ### 3. Run the install generator
67
+
68
+ ```bash
69
+ bin/rails generate binocs:install
70
+ ```
71
+
72
+ This will:
73
+ - Copy the migration file
74
+ - Create an initializer at `config/initializers/binocs.rb`
75
+ - Add the route to mount the engine
76
+
77
+ ### 4. Run migrations
78
+
79
+ ```bash
80
+ bin/rails db:migrate
81
+ ```
82
+
83
+ ### 5. Ensure ActionCable is configured
84
+
85
+ If you haven't set up ActionCable yet, add to your `config/cable.yml`:
86
+
87
+ ```yaml
88
+ development:
89
+ adapter: async
90
+
91
+ test:
92
+ adapter: test
93
+
94
+ production:
95
+ adapter: redis
96
+ url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
97
+ ```
98
+
99
+ ### 6. Start your Rails server
100
+
101
+ ```bash
102
+ bin/rails server
103
+ ```
104
+
105
+ ### 7. Visit the dashboard
106
+
107
+ Open your browser and navigate to: `http://localhost:3000/binocs`
108
+
109
+ ## Configuration
110
+
111
+ Customize Binocs behavior in `config/initializers/binocs.rb`:
112
+
113
+ ```ruby
114
+ Binocs.configure do |config|
115
+ # Enable/disable Binocs (automatically disabled in production)
116
+ config.enabled = true
117
+
118
+ # How long to keep request records (default: 24 hours)
119
+ config.retention_period = 24.hours
120
+
121
+ # Maximum request/response body size to store (default: 64KB)
122
+ config.max_body_size = 64.kilobytes
123
+
124
+ # Paths to ignore (assets, cable, etc.)
125
+ config.ignored_paths = %w[/assets /packs /binocs /cable]
126
+
127
+ # Content types to ignore (images, videos, etc.)
128
+ config.ignored_content_types = %w[image/ video/ audio/ font/]
129
+
130
+ # Maximum number of requests to store (oldest are deleted)
131
+ config.max_requests = 1000
132
+
133
+ # Whether to record request/response bodies
134
+ config.record_request_body = true
135
+ config.record_response_body = true
136
+
137
+ # Optional: Protect the dashboard with basic auth
138
+ config.basic_auth_username = ENV['BINOCS_USERNAME']
139
+ config.basic_auth_password = ENV['BINOCS_PASSWORD']
140
+
141
+ # Swagger/OpenAPI integration (for TUI)
142
+ config.swagger_spec_url = '/api-docs/v1/swagger.yaml' # OpenAPI spec endpoint
143
+ config.swagger_ui_url = '/api-docs/index.html' # Swagger UI URL
144
+
145
+ # Devise authentication (recommended if using Devise with ActionCable)
146
+ # config.authentication_method = :authenticate_user!
147
+
148
+ # Login path for authentication prompts (auto-detected for Devise)
149
+ # config.login_path = '/users/sign_in'
150
+ end
151
+ ```
152
+
153
+ ### Devise Integration
154
+
155
+ If your application uses Devise for authentication, you can require users to be logged in before accessing Binocs. This ensures the ActionCable WebSocket connection works properly.
156
+
157
+ ```ruby
158
+ # config/initializers/binocs.rb
159
+ Binocs.configure do |config|
160
+ # Require Devise authentication (recommended)
161
+ config.authentication_method = :authenticate_user!
162
+
163
+ # Or for admin users:
164
+ # config.authentication_method = :authenticate_admin!
165
+
166
+ # Or use a custom proc for more control:
167
+ # config.authentication_method = -> { authenticate_user! || authenticate_admin! }
168
+ end
169
+ ```
170
+
171
+ With this configured, unauthenticated users will be redirected to your login page, then back to `/binocs` after signing in.
172
+
173
+ **Fallback behavior**: If authentication is not configured but ActionCable requires it, Binocs will detect the WebSocket failure and display a banner prompting users to sign in. You can customize the login path:
174
+
175
+ ```ruby
176
+ config.login_path = '/users/sign_in' # Auto-detected from Devise if not set
177
+ ```
178
+
179
+ ### Swagger Deep Linking (rswag)
180
+
181
+ To enable jumping directly to specific endpoints in Swagger UI, add deep linking to your rswag configuration:
182
+
183
+ ```ruby
184
+ # config/initializers/rswag_ui.rb
185
+ Rswag::Ui.configure do |c|
186
+ c.swagger_endpoint '/api-docs/v1/swagger.yaml', 'API V1 Docs'
187
+
188
+ # Enable deep linking to specific operations
189
+ c.config_object['deepLinking'] = true
190
+ end
191
+ ```
192
+
193
+ With this enabled, pressing `o` in the TUI detail view will open Swagger UI and expand the matching endpoint.
194
+
195
+ ## Usage
196
+
197
+ ### Dashboard Overview
198
+
199
+ The main dashboard shows a list of all recorded requests with:
200
+
201
+ - HTTP method (GET, POST, PUT, PATCH, DELETE)
202
+ - Status code (color-coded by type)
203
+ - Request path
204
+ - Controller#action
205
+ - Duration
206
+ - Timestamp
207
+
208
+ ### Filtering Requests
209
+
210
+ Use the filter bar to narrow down requests:
211
+
212
+ - **Search**: Search by path, controller, or action
213
+ - **Method**: Filter by HTTP method
214
+ - **Status**: Filter by status code range (2xx, 3xx, 4xx, 5xx)
215
+ - **Controller**: Filter by controller name
216
+ - **Has Exception**: Show only requests with exceptions
217
+
218
+ ### Request Details
219
+
220
+ Click on any request to see full details including:
221
+
222
+ - **Overview**: Method, path, status, duration, memory usage
223
+ - **Params**: Filtered request parameters
224
+ - **Headers**: Request and response headers
225
+ - **Body**: Request and response bodies (with JSON formatting)
226
+ - **Logs**: Captured log entries from the request
227
+ - **Exception**: Full exception details with backtrace (if applicable)
228
+
229
+ ### Real-time Updates
230
+
231
+ Requests appear in the dashboard in real-time as they're made to your application. The dashboard uses Turbo Streams over ActionCable for instant updates without page refresh.
232
+
233
+ ## How ActionCable Integration Works
234
+
235
+ Binocs uses Rails' ActionCable and Turbo Streams to provide real-time updates to the dashboard. Here's how the pieces fit together:
236
+
237
+ ### Architecture Overview
238
+
239
+ ```
240
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
241
+ │ Your App │ │ Binocs │ │ Dashboard │
242
+ │ Request │────▶│ Middleware │────▶│ (Browser) │
243
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
244
+ │ ▲
245
+ │ 1. Save to DB │
246
+ │ 2. Broadcast │
247
+ ▼ │
248
+ ┌─────────────────┐ │
249
+ │ Turbo Stream │─────────────┘
250
+ │ (ActionCable) │ WebSocket
251
+ └─────────────────┘
252
+ ```
253
+
254
+ ### Request Recording Flow
255
+
256
+ 1. **Middleware Intercepts Request**: The `Binocs::Middleware::RequestRecorder` sits in your Rails middleware stack and captures every HTTP request (except ignored paths like `/assets`, `/cable`, etc.)
257
+
258
+ 2. **Data Collection**: For each request, Binocs records:
259
+ - HTTP method, path, full URL
260
+ - Request/response headers and bodies
261
+ - Parameters (filtered for sensitive data)
262
+ - Controller and action names
263
+ - Duration and memory usage
264
+ - Any exceptions that occurred
265
+ - Log entries generated during the request
266
+
267
+ 3. **Database Storage**: The request data is saved to the `binocs_requests` table
268
+
269
+ 4. **Real-time Broadcast**: After saving, Binocs broadcasts the new request via Turbo Streams:
270
+ ```ruby
271
+ Turbo::StreamsChannel.broadcast_prepend_to(
272
+ "binocs_requests",
273
+ target: "requests-list",
274
+ partial: "binocs/requests/request",
275
+ locals: { request: request }
276
+ )
277
+ ```
278
+
279
+ 5. **Dashboard Updates**: The dashboard subscribes to the `binocs_requests` stream via ActionCable. When a broadcast arrives, Turbo automatically prepends the new request to the list.
280
+
281
+ ### ActionCable Connection
282
+
283
+ The dashboard establishes a WebSocket connection when you load the page:
284
+
285
+ ```erb
286
+ <%= turbo_stream_from "binocs_requests" %>
287
+ ```
288
+
289
+ This creates a subscription to the `binocs_requests` channel. The connection uses your application's existing ActionCable configuration (`config/cable.yml`).
290
+
291
+ ### Authentication & WebSocket
292
+
293
+ If your application uses Devise (or similar) with ActionCable authentication, the WebSocket connection requires the user to be authenticated. Binocs handles this in two ways:
294
+
295
+ 1. **Recommended**: Configure `authentication_method` to require login before accessing Binocs (see [Devise Integration](#devise-integration))
296
+
297
+ 2. **Fallback**: If WebSocket fails to connect, Binocs displays a banner prompting the user to sign in. The dashboard still works without real-time updates - you can use the Refresh button.
298
+
299
+ ### Disabling Real-time Updates
300
+
301
+ The dashboard includes a "Live/Paused" toggle. When paused:
302
+ - The Turbo Stream subscription is temporarily disabled
303
+ - No new requests appear automatically
304
+ - Click "Refresh" to manually load new requests
305
+
306
+ ### Troubleshooting ActionCable
307
+
308
+ **WebSocket not connecting:**
309
+ - Check that ActionCable is configured in `config/cable.yml`
310
+ - Verify the `/cable` path is accessible
311
+ - Check browser console for WebSocket errors
312
+ - If using Devise, ensure you're authenticated
313
+
314
+ **Requests not appearing in real-time:**
315
+ - Verify `Turbo::StreamsChannel` is available (requires `turbo-rails` gem)
316
+ - Check Rails logs for `[Binocs] Broadcasting new request` messages
317
+ - Ensure the request path isn't in `config.ignored_paths`
318
+
319
+ **High latency or missed updates:**
320
+ - Consider using Redis adapter for ActionCable in production-like environments
321
+ - The async adapter (default for development) works fine for local debugging
322
+
323
+ ## Terminal UI (TUI)
324
+
325
+ Binocs includes a full-featured terminal interface for monitoring requests directly from your console. Run it alongside your Rails server for a vim-style debugging experience.
326
+
327
+ ![TUI List View](docs/images/tui-list-view.jpg)
328
+
329
+ ### Starting the TUI
330
+
331
+ From your Rails application directory:
332
+
333
+ ```bash
334
+ bundle exec binocs
335
+ ```
336
+
337
+ Or if you're in the binocs gem directory:
338
+
339
+ ```bash
340
+ cd /path/to/your/rails/app
341
+ bundle exec binocs
342
+ ```
343
+
344
+ ### Keyboard Navigation
345
+
346
+ **List View:**
347
+
348
+ | Key | Action |
349
+ |-----|--------|
350
+ | `j` / `↓` | Move down |
351
+ | `k` / `↑` | Move up |
352
+ | `g` / `Home` | Go to top |
353
+ | `G` / `End` | Go to bottom |
354
+ | `Ctrl+d` / `PgDn` | Page down |
355
+ | `Ctrl+u` / `PgUp` | Page up |
356
+ | `Enter` / `l` | View request details |
357
+ | `/` | Search by path |
358
+ | `f` | Open filter menu |
359
+ | `c` | Clear all filters |
360
+ | `r` | Refresh list |
361
+ | `d` | Delete selected request |
362
+ | `D` | Delete all requests |
363
+ | `?` | Show help |
364
+ | `q` | Quit |
365
+
366
+ **Detail View:**
367
+
368
+ | Key | Action |
369
+ |-----|--------|
370
+ | `Tab` / `]` / `L` | Next tab |
371
+ | `Shift+Tab` / `[` / `H` | Previous tab |
372
+ | `1`-`8` | Jump to tab by number |
373
+ | `j` / `↓` | Scroll down |
374
+ | `k` / `↑` | Scroll up |
375
+ | `n` | Next request |
376
+ | `p` | Previous request |
377
+ | `o` | Open Swagger docs in browser |
378
+ | `h` / `Esc` | Go back to list |
379
+
380
+ ### TUI Features
381
+
382
+ - **Split-screen layout**: List on left, detail on right when viewing a request
383
+ - **Tabbed detail view**: Overview, Params, Headers, Body, Response, Logs, Exception, Swagger, Agent
384
+ - **AI Agent integration**: Launch coding agents with request context directly from the TUI
385
+ - **Swagger integration**: View OpenAPI docs for any request and open in browser with `o`
386
+ - **Color-coded**: HTTP methods and status codes are highlighted by type
387
+ - **Auto-refresh**: List automatically updates every 2 seconds
388
+ - **Filtering**: Same filtering capabilities as the web interface
389
+ - **Responsive**: Adapts to terminal size changes
390
+ - **Easter egg**: Press `Space` then `s` in detail view to discover your request's spirit animal!
391
+
392
+ ![TUI Detail View](docs/images/tui-detail-view.jpg)
393
+
394
+ ![Spirit Animal Easter Egg](docs/images/spirit-animal.jpg)
395
+
396
+ ## AI Agent Integration
397
+
398
+ Binocs can launch AI coding agents (Claude Code or OpenCode) directly from the context of a captured request. This is useful when you want an AI to help debug or fix an issue based on the request data.
399
+
400
+ ![AI Agent View](docs/images/ai-view.jpg)
401
+
402
+ ### Using AI Agents in the TUI
403
+
404
+ 1. View a request's details and navigate to the **Agent** tab (press `a` or `9`)
405
+ 2. Configure your agent settings (see below)
406
+ 3. Type your prompt describing what you want the AI to do
407
+ 4. Press `Enter` on an empty line to submit
408
+ 5. Watch the AI's output in real-time
409
+
410
+ The agent receives full context about the request including the HTTP method, path, params, headers, request/response bodies, and any exceptions - giving it everything needed to understand and debug the issue.
411
+
412
+ ### Agent Settings
413
+
414
+ While in the Agent tab, you can configure how the agent runs:
415
+
416
+ | Key | Setting | Description |
417
+ |-----|---------|-------------|
418
+ | `t` | **Toggle Tool** | Switch between Claude Code and OpenCode. Claude Code uses `claude` CLI with `--dangerously-skip-permissions` for autonomous operation. OpenCode uses the `opencode` CLI. |
419
+ | `w` | **Toggle Worktree** | Switch between working on your current branch or creating an isolated git worktree. |
420
+
421
+ **Current Branch Mode** (default): The agent makes changes directly on your current git branch. Quick and simple for small fixes.
422
+
423
+ **Worktree Mode**: Creates a new git worktree and branch (e.g., `agent/0117-1423-fix-auth`) for the agent to work in. This keeps your current branch clean and lets you review changes before merging. Press `w` to enable, then enter a name for the worktree/branch.
424
+
425
+ ### Configuration
426
+
427
+ ```ruby
428
+ # config/initializers/binocs.rb
429
+ Binocs.configure do |config|
430
+ config.agent_tool = :claude_code # or :opencode
431
+ config.agent_worktree_base = '../binocs-agents' # where worktrees are created
432
+ end
433
+ ```
434
+
435
+ ## Rake Tasks
436
+
437
+ ```bash
438
+ # Clear all recorded requests
439
+ bin/rails binocs:clear
440
+
441
+ # Prune old requests (based on retention_period)
442
+ bin/rails binocs:prune
443
+
444
+ # Show statistics
445
+ bin/rails binocs:stats
446
+ ```
447
+
448
+ ## Security
449
+
450
+ ### Production Safety
451
+
452
+ Binocs is automatically disabled in production environments. Even if mounted, accessing `/binocs` in production will return a 403 Forbidden response.
453
+
454
+ ### Basic Authentication
455
+
456
+ For additional security in development/staging, enable basic auth:
457
+
458
+ ```ruby
459
+ # config/initializers/binocs.rb
460
+ Binocs.configure do |config|
461
+ config.basic_auth_username = 'admin'
462
+ config.basic_auth_password = 'secret'
463
+ end
464
+ ```
465
+
466
+ ### Sensitive Data
467
+
468
+ Binocs uses Rails' parameter filtering, so sensitive params (like `password`) are automatically masked. Cookies are not stored for security reasons.
469
+
470
+ ## Git Ignore
471
+
472
+ When using the AI Agent feature, Binocs creates temporary files in your project directory that should be added to your `.gitignore`:
473
+
474
+ ```gitignore
475
+ # Binocs AI Agent files
476
+ .binocs-context.md
477
+ .binocs-prompt.md
478
+ ```
479
+
480
+ If you use the worktree mode for agents, the default location is `../binocs-agents/` (a sibling directory to your project), so it won't affect your repo. However, if you configure a custom worktree path inside your project, add that path to `.gitignore` as well.
481
+
482
+ ## Troubleshooting
483
+
484
+ ### Requests not appearing
485
+
486
+ 1. Ensure Binocs is enabled: Check `Binocs.enabled?` returns `true`
487
+ 2. Check the path isn't ignored: Verify the path isn't in `config.ignored_paths`
488
+ 3. Verify migrations ran: Check the `binocs_requests` table exists
489
+
490
+ ### Real-time updates not working
491
+
492
+ 1. Ensure ActionCable is configured and running
493
+ 2. Check browser console for WebSocket errors
494
+ 3. Verify you have `turbo_stream_from "binocs_requests"` in the layout
495
+
496
+ ### High memory usage
497
+
498
+ 1. Reduce `config.retention_period`
499
+ 2. Lower `config.max_requests`
500
+ 3. Set `config.record_response_body = false` if you don't need response bodies
501
+
502
+ ## Development
503
+
504
+ ### Running Tests
505
+
506
+ ```bash
507
+ cd binocs
508
+ bundle install
509
+ bundle exec rspec
510
+ ```
511
+
512
+ ### Building the Gem
513
+
514
+ ```bash
515
+ gem build binocs.gemspec
516
+ ```
517
+
518
+ ## License
519
+
520
+ MIT License. See [MIT-LICENSE](MIT-LICENSE) for details.
521
+
522
+ ## Contributing
523
+
524
+ 1. Fork the repository
525
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
526
+ 3. Commit your changes (`git commit -am 'Add amazing feature'`)
527
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
528
+ 5. Open a Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ require "bundler/gem_tasks"
5
+
6
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
7
+ load "rails/tasks/engine.rake"
@@ -0,0 +1,105 @@
1
+ // Binocs Application JavaScript
2
+ import "@hotwired/turbo-rails"
3
+
4
+ // Auto-scroll to top when new request is prepended
5
+ document.addEventListener("turbo:before-stream-render", (event) => {
6
+ const stream = event.target
7
+ if (stream.action === "prepend" && stream.target === "requests-list") {
8
+ // Highlight the new element briefly
9
+ const originalRender = event.detail.render
10
+ event.detail.render = (streamElement) => {
11
+ originalRender(streamElement)
12
+ const newElement = document.querySelector("#requests-list > :first-child")
13
+ if (newElement) {
14
+ newElement.classList.add("turbo-stream-prepend")
15
+ }
16
+ }
17
+ }
18
+ })
19
+
20
+ // Auto-refresh toggle functionality
21
+ let autoRefreshInterval = null
22
+
23
+ function startAutoRefresh() {
24
+ if (autoRefreshInterval) return
25
+ autoRefreshInterval = setInterval(() => {
26
+ const frame = document.querySelector("#requests-list")
27
+ if (frame) {
28
+ Turbo.visit(window.location.href, { frame: "requests-list" })
29
+ }
30
+ }, 5000)
31
+ }
32
+
33
+ function stopAutoRefresh() {
34
+ if (autoRefreshInterval) {
35
+ clearInterval(autoRefreshInterval)
36
+ autoRefreshInterval = null
37
+ }
38
+ }
39
+
40
+ // WebSocket connection monitoring for authentication
41
+ let connectionAttempts = 0
42
+ let wasEverConnected = false
43
+
44
+ function setupConnectionMonitoring() {
45
+ if (typeof Turbo === 'undefined' || !Turbo.cable) {
46
+ // Turbo cable not available yet, retry
47
+ setTimeout(setupConnectionMonitoring, 100)
48
+ return
49
+ }
50
+
51
+ const consumer = Turbo.cable
52
+
53
+ // Monitor connection events
54
+ const originalOpen = consumer.connection.events.open
55
+ const originalClose = consumer.connection.events.close
56
+
57
+ consumer.connection.events.open = function() {
58
+ wasEverConnected = true
59
+ connectionAttempts = 0
60
+ hideAuthBanner()
61
+ if (originalOpen) originalOpen.call(this)
62
+ }
63
+
64
+ consumer.connection.events.close = function(event) {
65
+ connectionAttempts++
66
+ // If we've never connected and have tried a few times, likely auth issue
67
+ if (!wasEverConnected && connectionAttempts >= 2) {
68
+ showAuthBanner()
69
+ }
70
+ if (originalClose) originalClose.call(this, event)
71
+ }
72
+
73
+ // Also check initial state after a delay
74
+ setTimeout(() => {
75
+ if (!wasEverConnected && !consumer.connection.isOpen()) {
76
+ showAuthBanner()
77
+ }
78
+ }, 2000)
79
+ }
80
+
81
+ function showAuthBanner() {
82
+ const banner = document.getElementById('binocs-auth-banner')
83
+ if (banner) {
84
+ banner.classList.remove('hidden')
85
+ }
86
+ }
87
+
88
+ function hideAuthBanner() {
89
+ const banner = document.getElementById('binocs-auth-banner')
90
+ if (banner) {
91
+ banner.classList.add('hidden')
92
+ }
93
+ }
94
+
95
+ // Initialize connection monitoring when DOM is ready
96
+ document.addEventListener('DOMContentLoaded', setupConnectionMonitoring)
97
+ document.addEventListener('turbo:load', setupConnectionMonitoring)
98
+
99
+ // Expose to window for manual control
100
+ window.Binocs = {
101
+ startAutoRefresh,
102
+ stopAutoRefresh,
103
+ showAuthBanner,
104
+ hideAuthBanner
105
+ }