heathrow 0.7.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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +58 -0
  3. data/README.md +205 -0
  4. data/bin/heathrow +42 -0
  5. data/bin/heathrowd +283 -0
  6. data/docs/ARCHITECTURE.md +1172 -0
  7. data/docs/DATABASE_SCHEMA.md +685 -0
  8. data/docs/DEVELOPMENT_WORKFLOW.md +867 -0
  9. data/docs/DISCORD_SETUP.md +142 -0
  10. data/docs/GMAIL_OAUTH_SETUP.md +120 -0
  11. data/docs/PLUGIN_SYSTEM.md +1370 -0
  12. data/docs/PROJECT_PLAN.md +1022 -0
  13. data/docs/README.md +417 -0
  14. data/docs/REDDIT_SETUP.md +174 -0
  15. data/docs/REPLY_FORWARD.md +182 -0
  16. data/docs/WHATSAPP_TELEGRAM_SETUP.md +306 -0
  17. data/heathrow.gemspec +34 -0
  18. data/heathrowd.service +21 -0
  19. data/img/heathrow.svg +95 -0
  20. data/img/rss_threaded.png +0 -0
  21. data/img/sources.png +0 -0
  22. data/lib/heathrow/address_book.rb +42 -0
  23. data/lib/heathrow/config.rb +332 -0
  24. data/lib/heathrow/database.rb +731 -0
  25. data/lib/heathrow/database_new.rb +392 -0
  26. data/lib/heathrow/event_bus.rb +175 -0
  27. data/lib/heathrow/logger.rb +122 -0
  28. data/lib/heathrow/message.rb +176 -0
  29. data/lib/heathrow/message_composer.rb +399 -0
  30. data/lib/heathrow/message_organizer.rb +774 -0
  31. data/lib/heathrow/migrations/001_initial_schema.rb +248 -0
  32. data/lib/heathrow/notmuch.rb +45 -0
  33. data/lib/heathrow/oauth2_smtp.rb +254 -0
  34. data/lib/heathrow/plugin/base.rb +212 -0
  35. data/lib/heathrow/plugin_manager.rb +141 -0
  36. data/lib/heathrow/poller.rb +93 -0
  37. data/lib/heathrow/smtp_sender.rb +204 -0
  38. data/lib/heathrow/source.rb +39 -0
  39. data/lib/heathrow/sources/base.rb +74 -0
  40. data/lib/heathrow/sources/discord.rb +357 -0
  41. data/lib/heathrow/sources/gmail.rb +294 -0
  42. data/lib/heathrow/sources/imap.rb +198 -0
  43. data/lib/heathrow/sources/instagram.rb +307 -0
  44. data/lib/heathrow/sources/instagram_fetch.py +101 -0
  45. data/lib/heathrow/sources/instagram_send.py +55 -0
  46. data/lib/heathrow/sources/instagram_send_marionette.py +104 -0
  47. data/lib/heathrow/sources/maildir.rb +606 -0
  48. data/lib/heathrow/sources/messenger.rb +212 -0
  49. data/lib/heathrow/sources/messenger_fetch.js +297 -0
  50. data/lib/heathrow/sources/messenger_fetch_marionette.py +138 -0
  51. data/lib/heathrow/sources/messenger_send.js +32 -0
  52. data/lib/heathrow/sources/messenger_send.py +100 -0
  53. data/lib/heathrow/sources/reddit.rb +461 -0
  54. data/lib/heathrow/sources/rss.rb +299 -0
  55. data/lib/heathrow/sources/slack.rb +375 -0
  56. data/lib/heathrow/sources/source_manager.rb +328 -0
  57. data/lib/heathrow/sources/telegram.rb +498 -0
  58. data/lib/heathrow/sources/webpage.rb +207 -0
  59. data/lib/heathrow/sources/weechat.rb +479 -0
  60. data/lib/heathrow/sources/whatsapp.rb +474 -0
  61. data/lib/heathrow/ui/application.rb +8098 -0
  62. data/lib/heathrow/ui/navigation.rb +8 -0
  63. data/lib/heathrow/ui/panes.rb +8 -0
  64. data/lib/heathrow/ui/source_wizard.rb +567 -0
  65. data/lib/heathrow/ui/threaded_view.rb +780 -0
  66. data/lib/heathrow/ui/views.rb +8 -0
  67. data/lib/heathrow/version.rb +3 -0
  68. data/lib/heathrow/wizards/discord_wizard.rb +193 -0
  69. data/lib/heathrow/wizards/slack_wizard.rb +140 -0
  70. data/lib/heathrow.rb +55 -0
  71. metadata +147 -0
@@ -0,0 +1,867 @@
1
+ # Heathrow Development Workflow
2
+
3
+ **Goal:** Ensure consistent, safe, and efficient development process.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Development Environment Setup](#development-environment-setup)
10
+ 2. [Git Workflow](#git-workflow)
11
+ 3. [Coding Standards](#coding-standards)
12
+ 4. [Testing Workflow](#testing-workflow)
13
+ 5. [Documentation Workflow](#documentation-workflow)
14
+ 6. [Review Process](#review-process)
15
+ 7. [Release Process](#release-process)
16
+ 8. [Troubleshooting](#troubleshooting)
17
+
18
+ ---
19
+
20
+ ## Development Environment Setup
21
+
22
+ ### Prerequisites
23
+
24
+ ```bash
25
+ # Ruby 3.0+
26
+ ruby --version
27
+
28
+ # SQLite 3
29
+ sqlite3 --version
30
+
31
+ # Git
32
+ git --version
33
+
34
+ # Optional: w3m for HTML email rendering
35
+ w3m -version
36
+ ```
37
+
38
+ ### Initial Setup
39
+
40
+ ```bash
41
+ # Clone repository
42
+ git clone https://github.com/yourusername/heathrow.git
43
+ cd heathrow
44
+
45
+ # Install dependencies
46
+ gem install sqlite3 minitest rcurses
47
+
48
+ # Create config directories
49
+ mkdir -p ~/.heathrow/{plugins,attachments,backups}
50
+
51
+ # Initialize database
52
+ ruby -Ilib -e "require 'heathrow/database'; Heathrow::Database.new.migrate_to_latest"
53
+
54
+ # Run tests to verify setup
55
+ ruby test/test_all.rb
56
+ ```
57
+
58
+ ### IDE/Editor Configuration
59
+
60
+ **VS Code:**
61
+
62
+ ```json
63
+ {
64
+ "ruby.format": "rubocop",
65
+ "ruby.lint": {
66
+ "rubocop": true
67
+ },
68
+ "files.associations": {
69
+ "*.rb": "ruby"
70
+ }
71
+ }
72
+ ```
73
+
74
+ **Vim:**
75
+
76
+ ```vim
77
+ " .vimrc
78
+ autocmd FileType ruby setlocal expandtab shiftwidth=2 tabstop=2
79
+ autocmd FileType ruby setlocal colorcolumn=100
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Git Workflow
85
+
86
+ ### Branch Strategy
87
+
88
+ **Main Branches:**
89
+ - `main` - Production-ready code
90
+ - `develop` - Integration branch for next release
91
+
92
+ **Supporting Branches:**
93
+ - `feature/*` - New features
94
+ - `bugfix/*` - Bug fixes
95
+ - `hotfix/*` - Emergency production fixes
96
+ - `refactor/*` - Code improvements
97
+ - `docs/*` - Documentation updates
98
+
99
+ ### Branch Naming
100
+
101
+ ```bash
102
+ # Features
103
+ git checkout -b feature/gmail-plugin
104
+ git checkout -b feature/search-engine
105
+
106
+ # Bug fixes
107
+ git checkout -b bugfix/fix-slack-auth
108
+ git checkout -b bugfix/memory-leak-in-ui
109
+
110
+ # Refactoring
111
+ git checkout -b refactor/simplify-filter-engine
112
+
113
+ # Documentation
114
+ git checkout -b docs/update-plugin-guide
115
+ ```
116
+
117
+ ### Commit Messages
118
+
119
+ **Format:**
120
+
121
+ ```
122
+ <type>(<scope>): <subject>
123
+
124
+ <body>
125
+
126
+ <footer>
127
+ ```
128
+
129
+ **Types:**
130
+ - `feat` - New feature
131
+ - `fix` - Bug fix
132
+ - `refactor` - Code refactoring
133
+ - `docs` - Documentation
134
+ - `test` - Test additions/changes
135
+ - `chore` - Maintenance tasks
136
+
137
+ **Examples:**
138
+
139
+ ```bash
140
+ # Good
141
+ git commit -m "feat(plugins): add Gmail OAuth2 authentication"
142
+
143
+ git commit -m "fix(ui): prevent crash when terminal too small
144
+
145
+ Terminal width < 80 caused division by zero in pane calculation.
146
+ Added minimum width check and display warning message.
147
+
148
+ Fixes #123"
149
+
150
+ git commit -m "refactor(database): extract query builder to separate class
151
+
152
+ Improves testability and readability of database queries.
153
+ No functional changes."
154
+
155
+ # Bad
156
+ git commit -m "fixed stuff"
157
+ git commit -m "WIP"
158
+ git commit -m "asdfasdf"
159
+ ```
160
+
161
+ ### Workflow Steps
162
+
163
+ #### 1. Start New Feature
164
+
165
+ ```bash
166
+ # Update develop branch
167
+ git checkout develop
168
+ git pull origin develop
169
+
170
+ # Create feature branch
171
+ git checkout -b feature/my-feature
172
+
173
+ # Make changes...
174
+
175
+ # Commit frequently
176
+ git add lib/heathrow/my_feature.rb
177
+ git commit -m "feat(my-feature): implement core logic"
178
+
179
+ # Push to remote
180
+ git push -u origin feature/my-feature
181
+ ```
182
+
183
+ #### 2. Keep Branch Updated
184
+
185
+ ```bash
186
+ # Rebase on develop regularly
187
+ git fetch origin
188
+ git rebase origin/develop
189
+
190
+ # Resolve conflicts if any
191
+ git add <resolved-files>
192
+ git rebase --continue
193
+
194
+ # Force push (only on feature branches!)
195
+ git push --force-with-lease
196
+ ```
197
+
198
+ #### 3. Submit Pull Request
199
+
200
+ ```bash
201
+ # Ensure all tests pass
202
+ ruby test/test_all.rb
203
+
204
+ # Push final version
205
+ git push origin feature/my-feature
206
+
207
+ # Create PR via GitHub CLI or web interface
208
+ gh pr create --base develop --title "Add My Feature" --body "Description..."
209
+ ```
210
+
211
+ #### 4. After PR Merged
212
+
213
+ ```bash
214
+ # Delete local branch
215
+ git checkout develop
216
+ git pull origin develop
217
+ git branch -d feature/my-feature
218
+
219
+ # Delete remote branch (if not auto-deleted)
220
+ git push origin --delete feature/my-feature
221
+ ```
222
+
223
+ ### Hotfix Workflow
224
+
225
+ ```bash
226
+ # Create hotfix from main
227
+ git checkout main
228
+ git checkout -b hotfix/critical-bug
229
+
230
+ # Fix the issue
231
+ git commit -m "fix(critical): resolve security vulnerability"
232
+
233
+ # Merge to main
234
+ git checkout main
235
+ git merge hotfix/critical-bug
236
+ git tag v1.2.3
237
+ git push origin main --tags
238
+
239
+ # Merge to develop
240
+ git checkout develop
241
+ git merge hotfix/critical-bug
242
+ git push origin develop
243
+
244
+ # Delete hotfix branch
245
+ git branch -d hotfix/critical-bug
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Coding Standards
251
+
252
+ ### Ruby Style Guide
253
+
254
+ **Follow:** [Ruby Style Guide](https://rubystyle.guide/)
255
+
256
+ **Key Points:**
257
+
258
+ 1. **Indentation:** 2 spaces, no tabs
259
+ 2. **Line Length:** 100 characters max
260
+ 3. **Method Length:** 15 lines max (guideline, not strict)
261
+ 4. **Class Length:** 200 lines max (consider splitting)
262
+ 5. **Naming:**
263
+ - Classes: `CamelCase`
264
+ - Methods: `snake_case`
265
+ - Constants: `SCREAMING_SNAKE_CASE`
266
+ - Private methods: prefix with `private`
267
+
268
+ **Example:**
269
+
270
+ ```ruby
271
+ module Heathrow
272
+ class MessageRouter
273
+ MAX_RETRIES = 3
274
+
275
+ def initialize(filter_engine, view_manager, db)
276
+ @filter_engine = filter_engine
277
+ @view_manager = view_manager
278
+ @db = db
279
+ end
280
+
281
+ def route_message(message)
282
+ validate_message(message)
283
+
284
+ views = matching_views(message)
285
+ views.each { |view| add_to_view(message, view) }
286
+
287
+ log_routing(message, views)
288
+ end
289
+
290
+ private
291
+
292
+ def validate_message(message)
293
+ raise ArgumentError, "Message cannot be nil" unless message
294
+ raise ArgumentError, "Message must have sender" unless message.sender
295
+ end
296
+
297
+ def matching_views(message)
298
+ @view_manager.all_views.select do |view|
299
+ @filter_engine.matches?(message, view.filters)
300
+ end
301
+ end
302
+
303
+ def add_to_view(message, view)
304
+ # Implementation...
305
+ end
306
+
307
+ def log_routing(message, views)
308
+ # Implementation...
309
+ end
310
+ end
311
+ end
312
+ ```
313
+
314
+ ### File Organization
315
+
316
+ ```
317
+ lib/heathrow/
318
+ ├── heathrow.rb # Main entry point
319
+ ├── version.rb # Version constant
320
+ ├── config.rb # Configuration
321
+ ├── database.rb # Database layer
322
+ ├── event_bus.rb # Event system
323
+ ├── logger.rb # Logging
324
+ ├── cache.rb # Caching
325
+ ├── message.rb # Message model
326
+ ├── message_router.rb # Message routing
327
+ ├── view_manager.rb # View management
328
+ ├── filter_engine.rb # Filter evaluation
329
+ ├── search_engine.rb # Search
330
+ ├── plugin_manager.rb # Plugin management
331
+ ├── stream_manager.rb # Real-time streaming
332
+ ├── plugin/
333
+ │ ├── base.rb # Plugin base class
334
+ │ ├── errors.rb # Plugin errors
335
+ │ └── registry.rb # Plugin registry
336
+ ├── plugins/
337
+ │ ├── gmail.rb
338
+ │ ├── slack.rb
339
+ │ └── ...
340
+ ├── ui/
341
+ │ ├── application.rb # Main UI
342
+ │ ├── pane_manager.rb # Pane management
343
+ │ ├── input_handler.rb # Input handling
344
+ │ ├── renderer.rb # Rendering
345
+ │ ├── composer.rb # Message composer
346
+ │ └── thread_view.rb # Thread view
347
+ └── migrations/
348
+ ├── 001_initial.rb
349
+ └── ...
350
+ ```
351
+
352
+ ### Documentation Comments
353
+
354
+ **Use YARD format:**
355
+
356
+ ```ruby
357
+ # Fetch messages from the plugin
358
+ #
359
+ # @param since [Integer, nil] Unix timestamp to fetch from (nil for all)
360
+ # @return [Array<Heathrow::Message>] Array of normalized messages
361
+ # @raise [Plugin::ConnectionError] If connection fails
362
+ # @raise [Plugin::AuthenticationError] If authentication fails
363
+ #
364
+ # @example Fetch recent messages
365
+ # messages = plugin.fetch_messages(since: Time.now.to_i - 3600)
366
+ #
367
+ def fetch_messages(since: nil)
368
+ # Implementation...
369
+ end
370
+ ```
371
+
372
+ ---
373
+
374
+ ## Testing Workflow
375
+
376
+ ### Running Tests
377
+
378
+ ```bash
379
+ # Run all tests
380
+ ruby test/test_all.rb
381
+
382
+ # Run specific test file
383
+ ruby test/test_filter_engine.rb
384
+
385
+ # Run specific test
386
+ ruby test/test_filter_engine.rb -n test_simple_equality_filter
387
+
388
+ # Run with verbose output
389
+ ruby test/test_all.rb -v
390
+
391
+ # Run with code coverage (if using SimpleCov)
392
+ COVERAGE=1 ruby test/test_all.rb
393
+ ```
394
+
395
+ ### Writing Tests
396
+
397
+ **Test File Naming:**
398
+ - Unit tests: `test/test_<component>.rb`
399
+ - Integration tests: `test/integration/test_<feature>.rb`
400
+ - E2E tests: `test/e2e/test_<workflow>.rb`
401
+
402
+ **Test Structure:**
403
+
404
+ ```ruby
405
+ require 'minitest/autorun'
406
+ require_relative 'test_helper'
407
+
408
+ class TestMessageRouter < Minitest::Test
409
+ # Setup runs before each test
410
+ def setup
411
+ @db = Database.new(":memory:")
412
+ @filter_engine = FilterEngine.new
413
+ @view_manager = ViewManager.new(@db, @filter_engine)
414
+ @router = MessageRouter.new(@filter_engine, @view_manager, @db)
415
+ end
416
+
417
+ # Teardown runs after each test (optional)
418
+ def teardown
419
+ @db.close
420
+ end
421
+
422
+ # Test methods must start with "test_"
423
+ def test_routes_message_to_matching_view
424
+ # Arrange
425
+ view = @view_manager.create_view("Test", {field: "sender", op: "=", value: "test@example.com"})
426
+ message = create_test_message(sender: "test@example.com")
427
+
428
+ # Act
429
+ @router.route_message(message)
430
+
431
+ # Assert
432
+ messages = @router.messages_for_view(view.id)
433
+ assert_equal 1, messages.count
434
+ assert_equal message.external_id, messages.first.external_id
435
+ end
436
+
437
+ def test_raises_error_on_invalid_message
438
+ assert_raises(ArgumentError) do
439
+ @router.route_message(nil)
440
+ end
441
+ end
442
+
443
+ private
444
+
445
+ def create_test_message(overrides = {})
446
+ TestHelper.create_test_message(overrides)
447
+ end
448
+ end
449
+ ```
450
+
451
+ ### Test Coverage Goals
452
+
453
+ | Component Type | Target Coverage |
454
+ |-------------------|-----------------|
455
+ | Core Layer | 95%+ |
456
+ | Application Layer | 85%+ |
457
+ | UI Layer | 60%+ |
458
+ | Plugins | 75%+ |
459
+ | Overall | 80%+ |
460
+
461
+ ### Continuous Integration
462
+
463
+ **GitHub Actions Workflow:**
464
+
465
+ ```yaml
466
+ # .github/workflows/test.yml
467
+ name: Test
468
+
469
+ on: [push, pull_request]
470
+
471
+ jobs:
472
+ test:
473
+ runs-on: ubuntu-latest
474
+
475
+ steps:
476
+ - uses: actions/checkout@v2
477
+
478
+ - name: Set up Ruby
479
+ uses: ruby/setup-ruby@v1
480
+ with:
481
+ ruby-version: 3.2
482
+
483
+ - name: Install dependencies
484
+ run: gem install sqlite3 minitest rcurses
485
+
486
+ - name: Run tests
487
+ run: ruby test/test_all.rb
488
+
489
+ - name: Run rubocop
490
+ run: gem install rubocop && rubocop
491
+
492
+ - name: Check coverage
493
+ run: |
494
+ COVERAGE=1 ruby test/test_all.rb
495
+ # Fail if coverage < 80%
496
+ ```
497
+
498
+ ---
499
+
500
+ ## Documentation Workflow
501
+
502
+ ### Documentation Types
503
+
504
+ 1. **Code Comments** - YARD format for methods/classes
505
+ 2. **README.md** - Project overview and quickstart
506
+ 3. **docs/** - Detailed guides
507
+ 4. **CHANGELOG.md** - Version history
508
+ 5. **API.md** - API reference (auto-generated from YARD)
509
+
510
+ ### Documentation Standards
511
+
512
+ **Keep documentation:**
513
+ - Up-to-date with code
514
+ - Clear and concise
515
+ - Example-driven
516
+ - Beginner-friendly
517
+
518
+ **Update documentation when:**
519
+ - Adding new feature
520
+ - Changing API
521
+ - Fixing bug that affects usage
522
+ - Deprecating functionality
523
+
524
+ ### Generating API Docs
525
+
526
+ ```bash
527
+ # Install YARD
528
+ gem install yard
529
+
530
+ # Generate docs
531
+ yard doc
532
+
533
+ # View docs
534
+ yard server
535
+ # Open http://localhost:8808
536
+ ```
537
+
538
+ ---
539
+
540
+ ## Review Process
541
+
542
+ ### Pre-Review Checklist
543
+
544
+ Before submitting PR, verify:
545
+
546
+ - [ ] All tests pass
547
+ - [ ] No rubocop violations
548
+ - [ ] Documentation updated
549
+ - [ ] CHANGELOG.md updated
550
+ - [ ] Commit messages follow convention
551
+ - [ ] No commented-out code
552
+ - [ ] No debug print statements
553
+ - [ ] Branch rebased on latest develop
554
+
555
+ ### Code Review Guidelines
556
+
557
+ **For Reviewers:**
558
+
559
+ 1. **Functionality** - Does it work as intended?
560
+ 2. **Tests** - Are there sufficient tests?
561
+ 3. **Readability** - Is the code clear?
562
+ 4. **Performance** - Are there obvious bottlenecks?
563
+ 5. **Security** - Any vulnerabilities?
564
+ 6. **Architecture** - Does it fit the design?
565
+
566
+ **Review Comments:**
567
+
568
+ ```
569
+ # Good
570
+ "Consider extracting this to a separate method for better testability."
571
+ "This could cause a race condition if called from multiple threads."
572
+ "Nice solution! One suggestion: use `find` instead of `select.first` for clarity."
573
+
574
+ # Bad
575
+ "This is wrong."
576
+ "Why did you do it this way?"
577
+ "Just rewrite this."
578
+ ```
579
+
580
+ **Approval Criteria:**
581
+ - At least 1 approval from maintainer
582
+ - All CI checks pass
583
+ - No unresolved discussions
584
+
585
+ ---
586
+
587
+ ## Release Process
588
+
589
+ ### Versioning
590
+
591
+ **Semantic Versioning:** `MAJOR.MINOR.PATCH`
592
+
593
+ - `MAJOR` - Breaking changes
594
+ - `MINOR` - New features (backward compatible)
595
+ - `PATCH` - Bug fixes
596
+
597
+ **Examples:**
598
+ - `1.0.0` - Initial stable release
599
+ - `1.1.0` - Added Slack plugin
600
+ - `1.1.1` - Fixed Slack authentication bug
601
+ - `2.0.0` - Changed config file format (breaking)
602
+
603
+ ### Release Steps
604
+
605
+ #### 1. Prepare Release
606
+
607
+ ```bash
608
+ # Create release branch
609
+ git checkout develop
610
+ git checkout -b release/v1.2.0
611
+
612
+ # Update version
613
+ # Edit lib/heathrow/version.rb
614
+ module Heathrow
615
+ VERSION = "1.2.0"
616
+ end
617
+
618
+ # Update CHANGELOG.md
619
+ # Add release notes under "## [1.2.0] - 2024-01-15"
620
+
621
+ # Commit changes
622
+ git commit -am "chore: prepare v1.2.0 release"
623
+ ```
624
+
625
+ #### 2. Test Release
626
+
627
+ ```bash
628
+ # Run full test suite
629
+ ruby test/test_all.rb
630
+
631
+ # Manual testing
632
+ ./bin/heathrow
633
+
634
+ # Integration testing with real services (if possible)
635
+ ```
636
+
637
+ #### 3. Merge and Tag
638
+
639
+ ```bash
640
+ # Merge to main
641
+ git checkout main
642
+ git merge release/v1.2.0
643
+
644
+ # Tag release
645
+ git tag -a v1.2.0 -m "Release v1.2.0"
646
+ git push origin main --tags
647
+
648
+ # Merge to develop
649
+ git checkout develop
650
+ git merge release/v1.2.0
651
+ git push origin develop
652
+
653
+ # Delete release branch
654
+ git branch -d release/v1.2.0
655
+ ```
656
+
657
+ #### 4. Publish
658
+
659
+ ```bash
660
+ # Build gem
661
+ gem build heathrow.gemspec
662
+
663
+ # Publish to RubyGems
664
+ gem push heathrow-1.2.0.gem
665
+
666
+ # Create GitHub release
667
+ gh release create v1.2.0 --title "v1.2.0" --notes "See CHANGELOG.md"
668
+ ```
669
+
670
+ #### 5. Announce
671
+
672
+ - Post to project blog/website
673
+ - Update documentation site
674
+ - Notify users (mailing list, Discord, etc.)
675
+
676
+ ### CHANGELOG Format
677
+
678
+ ```markdown
679
+ # Changelog
680
+
681
+ All notable changes to this project will be documented in this file.
682
+
683
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
684
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
685
+
686
+ ## [Unreleased]
687
+
688
+ ### Added
689
+ - Feature X that does Y
690
+
691
+ ### Changed
692
+ - Improved performance of Z
693
+
694
+ ### Fixed
695
+ - Bug in A that caused B
696
+
697
+ ## [1.2.0] - 2024-01-15
698
+
699
+ ### Added
700
+ - Gmail plugin with OAuth2 support
701
+ - Full-text search across all messages
702
+ - Message threading support
703
+
704
+ ### Changed
705
+ - Improved UI rendering performance by 50%
706
+ - Updated dependencies to latest versions
707
+
708
+ ### Fixed
709
+ - Crash when terminal width < 80
710
+ - Memory leak in real-time stream manager
711
+
712
+ ### Security
713
+ - Fixed XSS vulnerability in HTML email rendering
714
+
715
+ ## [1.1.0] - 2023-12-01
716
+
717
+ ...
718
+ ```
719
+
720
+ ---
721
+
722
+ ## Troubleshooting
723
+
724
+ ### Common Issues
725
+
726
+ #### Tests Failing Locally
727
+
728
+ ```bash
729
+ # Ensure clean database
730
+ rm ~/.heathrow/heathrow.db
731
+ ruby -Ilib -e "require 'heathrow/database'; Heathrow::Database.new.migrate_to_latest"
732
+
733
+ # Clear cache
734
+ rm -rf /tmp/heathrow_test_*
735
+
736
+ # Reinstall dependencies
737
+ gem uninstall sqlite3 minitest rcurses
738
+ gem install sqlite3 minitest rcurses
739
+
740
+ # Run tests again
741
+ ruby test/test_all.rb
742
+ ```
743
+
744
+ #### Rubocop Violations
745
+
746
+ ```bash
747
+ # Auto-fix simple violations
748
+ rubocop -a
749
+
750
+ # Auto-fix unsafe violations (be careful!)
751
+ rubocop -A
752
+
753
+ # Ignore specific violations (last resort)
754
+ # Add to .rubocop.yml:
755
+ # Style/StringLiterals:
756
+ # Enabled: false
757
+ ```
758
+
759
+ #### Git Conflicts
760
+
761
+ ```bash
762
+ # Abort rebase and start fresh
763
+ git rebase --abort
764
+ git fetch origin
765
+ git rebase origin/develop
766
+
767
+ # Use merge instead (not recommended)
768
+ git merge origin/develop
769
+
770
+ # Resolve conflicts manually
771
+ # Edit conflicted files
772
+ git add <resolved-files>
773
+ git rebase --continue
774
+ ```
775
+
776
+ #### Performance Issues
777
+
778
+ ```bash
779
+ # Profile code
780
+ ruby -r profile test/test_all.rb
781
+
782
+ # Memory profiling
783
+ gem install memory_profiler
784
+ ruby -r memory_profiler -e "MemoryProfiler.report { require 'heathrow' }.pretty_print"
785
+
786
+ # Database performance
787
+ # Add logging to database.rb
788
+ def query(sql, params = [])
789
+ start = Time.now
790
+ result = @db.execute(sql, params)
791
+ puts "Query took #{Time.now - start}s: #{sql}"
792
+ result
793
+ end
794
+ ```
795
+
796
+ ### Getting Help
797
+
798
+ 1. **Check documentation:** `docs/`
799
+ 2. **Search issues:** GitHub issues
800
+ 3. **Ask in discussions:** GitHub discussions
801
+ 4. **IRC/Discord:** Project chat
802
+ 5. **Email:** maintainers
803
+
804
+ ---
805
+
806
+ ## Development Tips
807
+
808
+ ### Productivity
809
+
810
+ 1. **Use aliases:**
811
+
812
+ ```bash
813
+ # .bashrc or .zshrc
814
+ alias ht='./bin/heathrow'
815
+ alias htt='ruby test/test_all.rb'
816
+ alias htl='tail -f ~/.heathrow/heathrow.log'
817
+ ```
818
+
819
+ 2. **Quick iterations:**
820
+
821
+ ```bash
822
+ # Watch files and auto-run tests
823
+ gem install watchr
824
+ # Create Watchfile with test runner
825
+ ```
826
+
827
+ 3. **Debugging:**
828
+
829
+ ```ruby
830
+ # Use pry for debugging
831
+ gem install pry
832
+ # In code:
833
+ require 'pry'
834
+ binding.pry
835
+ ```
836
+
837
+ ### Best Practices
838
+
839
+ 1. **Test-driven development** - Write test first, then implementation
840
+ 2. **Commit often** - Small commits are easier to review and revert
841
+ 3. **Document as you go** - Don't leave it for later
842
+ 4. **Ask for help early** - Don't waste time stuck
843
+ 5. **Review your own code** - Read diff before committing
844
+
845
+ ### Code Review Checklist
846
+
847
+ Before submitting PR:
848
+
849
+ ```markdown
850
+ ## PR Checklist
851
+
852
+ - [ ] Tests pass locally
853
+ - [ ] Added tests for new functionality
854
+ - [ ] Updated documentation
855
+ - [ ] Updated CHANGELOG.md
856
+ - [ ] No rubocop violations
857
+ - [ ] No breaking changes (or clearly documented)
858
+ - [ ] Reviewed my own code in diff view
859
+ - [ ] Tested manually in terminal
860
+ - [ ] Considered edge cases
861
+ - [ ] Checked for security issues
862
+ - [ ] Ensured backward compatibility
863
+ ```
864
+
865
+ ---
866
+
867
+ This workflow ensures consistent, high-quality development across the entire Heathrow project.