source_monitor 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 932dca7d7b8f754262dd37aac3cf722aee017ec53e662116dd97527ec2a8a1f3
4
- data.tar.gz: 7d6ff568a5e3eb1cf5269736771474f19da9e82b18759232b03855735f284819
3
+ metadata.gz: 16d5152ca0edc61e1d7f67878516e93769dd43c34daa757c554d36355b998fec
4
+ data.tar.gz: f93013eedf10c9af8b758b302993f701531b51170a399ea1e09c0f53efb4498d
5
5
  SHA512:
6
- metadata.gz: 1318387b90d5811d52fc5d852a2be9578515a0d69f77baa90ecc1fbab930a3d2067a1e7056f8d2bd15940de2c0799e147203b31e4d91784e3078fb0fa8edc6e5
7
- data.tar.gz: b35f81be14c230f1865642b5aa9f8fd462791c8fe3db293bf0f6326f2fc9fc1295eaef5f9899488d298e01e6eb3e6b316c00ed53595341a17973edd50cbb7b10
6
+ metadata.gz: d06eedf5dd22a3cf5c96a252883870b7f416c53f41da5121100b3a66564e7c3021a963512c6355f3aa52be6e30aba23d74b135e47bc1e6fbc17401fc929d5865
7
+ data.tar.gz: 70655afb16134fecaa25f6547ed8ef05e2fcb7c61fbf3d2b46c7c9b1199eb8f14503db99eb8e165b71927bc9ba4301c3e035e6973eb3fbec85fc3f5be17b1eeb
@@ -17,8 +17,15 @@ These are real issues encountered in previous releases. Each step below accounts
17
17
  5. **Single squashed commit**: Always create ONE commit on the release branch with ALL changes (version bump, changelog, Gemfile.lock, any fixes). Multiple commits cause pre-push hook issues.
18
18
  6. **Diff coverage CI gate**: The `test` CI job enforces diff coverage. Any changed lines in source code (not just test files) must have test coverage. **This applies to ALL changes in the PR diff vs main, including unpushed commits made before the release started.** If the release includes source code changes (bug fixes, features), every changed source line must be covered.
19
19
  7. **Local main divergence after merge**: After the PR merges, `gh pr merge --merge --delete-branch` will attempt to fast-forward local main. This usually succeeds automatically. If it doesn't (divergent history), you must `git reset --hard origin/main` to sync -- this requires user approval since the sandbox blocks it.
20
- 8. **Run local checks BEFORE pushing**: Always run `bin/rubocop` and `PARALLEL_WORKERS=1 bin/rails test` locally before the first push to the release branch. Each CI roundtrip (fail → fix → amend → force-push → re-run) costs ~5 minutes. In v0.7.0, skipping local checks caused two wasted CI cycles: first for uncovered diff lines, then for a RuboCop violation in the fix.
21
- 9. **Zsh glob nomatch**: Commands like `rm -f *.gem` fail in zsh when no files match. Always use `rm -f *.gem 2>/dev/null || true` or check existence first with `ls`.
20
+ 8. **Run FULL local CI suite BEFORE pushing**: Always run ALL of these locally before the first push to the release branch:
21
+ - `bin/rubocop` -- Ruby lint
22
+ - `PARALLEL_WORKERS=1 bin/rails test` -- tests + diff coverage readiness
23
+ - `bin/brakeman --no-pager` -- security scan
24
+ - `yarn build` -- rebuild JS assets (catches ESLint issues; CI runs ESLint separately on JS files)
25
+ Each CI roundtrip (fail → fix → amend → force-push → re-run) costs ~5 minutes. In v0.7.0, skipping local checks caused two wasted CI cycles. In v0.8.0, skipping ESLint (`yarn build`) and diff coverage pre-checks caused another two wasted cycles: first for ESLint `no-undef` on browser globals (MutationObserver, requestAnimationFrame), then for 13 uncovered rescue/error path lines across 3 files.
26
+ 9. **ESLint browser globals**: Any JS file using browser APIs (MutationObserver, requestAnimationFrame, cancelAnimationFrame, IntersectionObserver, etc.) MUST declare them with a `/* global ... */` comment at the top. ESLint's `no-undef` rule in CI will reject them otherwise.
27
+ 10. **Diff coverage rescue paths**: Every `rescue`/fallback/error handling branch in changed source code needs test coverage. Common blind spots: `rescue StandardError => e` logging, `rescue URI::InvalidURIError` returning nil, fallback `false` returns. Write targeted tests for these BEFORE creating the release commit.
28
+ 11. **Zsh glob nomatch**: Commands like `rm -f *.gem` fail in zsh when no files match. Always use `rm -f *.gem 2>/dev/null || true` or check existence first with `ls`.
22
29
 
23
30
  ## Step 1: Git Hygiene
24
31
 
@@ -116,21 +123,26 @@ The changelog follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) f
116
123
 
117
124
  ## Step 5: Local Pre-flight Checks
118
125
 
119
- **CRITICAL**: Run these checks BEFORE creating the release branch and pushing. Each CI failure → fix → amend → force-push cycle wastes ~5 minutes. In v0.7.0, skipping this step caused two wasted CI roundtrips.
126
+ **CRITICAL**: Run the FULL local CI equivalent BEFORE creating the release branch and pushing. Each CI failure → fix → amend → force-push cycle wastes ~5 minutes. In v0.7.0, skipping this step caused two wasted CI roundtrips. In v0.8.0, skipping ESLint and diff coverage pre-checks caused another two wasted cycles.
120
127
 
121
128
  1. **RuboCop**: Run `bin/rubocop` and fix any violations. Auto-fix with `bin/rubocop -a` if needed. This catches lint issues (like `SpaceInsideArrayLiteralBrackets`) that would fail the CI lint job.
122
129
 
123
130
  2. **Tests**: Run `PARALLEL_WORKERS=1 bin/rails test` and ensure all tests pass.
124
131
 
125
132
  3. **Diff coverage pre-check**: If the release includes source code changes beyond version/changelog/lockfile (check with `git diff --name-only origin/main`), review those files for uncovered branches. The CI diff coverage gate will reject any changed source lines without test coverage. Common blind spots:
133
+ - `rescue StandardError` logging/fallback paths
134
+ - `rescue URI::InvalidURIError` nil returns
135
+ - Guard clauses returning early (e.g., `return if blank?`)
126
136
  - Fallback/else branches in new methods
127
- - Error handling paths
128
- - Guard clauses
129
137
  If you find uncovered source lines, write tests for them NOW before creating the release commit — it's far cheaper than a CI roundtrip.
130
138
 
131
139
  4. **Brakeman**: Run `bin/brakeman --no-pager` and ensure zero warnings.
132
140
 
133
- Only proceed to Step 6 when all local checks pass.
141
+ 5. **ESLint / JS build**: If any `.js` files were changed, run `yarn build` to rebuild assets. CI runs ESLint separately on JS files and will catch issues RuboCop doesn't:
142
+ - Browser globals (MutationObserver, requestAnimationFrame, cancelAnimationFrame, IntersectionObserver, etc.) must be declared with `/* global ... */` comments at the top of the file.
143
+ - Missing `/* global */` declarations cause ESLint `no-undef` failures.
144
+
145
+ Only proceed to Step 6 when ALL five checks pass.
134
146
 
135
147
  ## Step 6: Create Release Branch with Single Squashed Commit
136
148
 
data/CHANGELOG.md CHANGED
@@ -15,6 +15,16 @@ All notable changes to this project are documented below. The format follows [Ke
15
15
 
16
16
  - No unreleased changes yet.
17
17
 
18
+ ## [0.8.1] - 2026-02-21
19
+
20
+ ### Fixed
21
+
22
+ - **OPML import now imports all selected feeds across pages.** Previously, only the 25 feeds visible on the current preview page were imported. Pagination links inside the preview form triggered full-page navigation (bypassing Turbo Frames), which caused a "leave site?" warning and lost selections from other pages. Hidden fields now preserve selections across pages, and pagination uses Turbo Frame navigation.
23
+
24
+ ### Changed
25
+
26
+ - Removed deprecated `rails/tasks/statistics.rake` from Rakefile (Rails 8.2 compatibility).
27
+
18
28
  ## [0.8.0] - 2026-02-21
19
29
 
20
30
  ### Added
data/CLAUDE.md CHANGED
@@ -4,10 +4,10 @@
4
4
 
5
5
  ## Active Context
6
6
 
7
- **Milestone:** polish-and-reliability
8
- **Phase:** 1 -- Backend Fixes (pending planning)
9
- **Last shipped:** aia-ssl-fix (2026-02-20) -- 2 phases, 7 plans, 8 commits
10
- **Previous:** upgrade-assurance (2026-02-13), generator-enhancements (2026-02-12)
7
+ **Milestone:** (none active)
8
+ **Last shipped:** polish-and-reliability (2026-02-21) -- v0.8.0, 3 phases, 1134 tests
9
+ **Previous:** aia-ssl-fix (2026-02-20), upgrade-assurance (2026-02-13)
10
+ **Next action:** /vbw:vibe to start a new milestone
11
11
 
12
12
  ## Key Decisions
13
13
 
@@ -97,9 +97,24 @@ Run /vbw:help for all commands.
97
97
  - `bin/rubocop` -- zero offenses before commit.
98
98
  - `bin/brakeman --no-pager` -- zero warnings before merge.
99
99
  - `bin/rails test` -- all tests pass.
100
+ - `yarn build` -- rebuild JS assets if any `.js` files changed (ESLint runs in CI).
100
101
  - No N+1 queries (use `includes`/`preload`).
101
102
  - No hardcoded credentials (use Rails credentials or ENV).
102
103
 
104
+ ### Pre-Push CI Checklist (run ALL before pushing to GitHub)
105
+
106
+ Before pushing any branch (especially release branches), run the full CI equivalent locally:
107
+
108
+ 1. `bin/rubocop` -- catches Ruby lint issues
109
+ 2. `PARALLEL_WORKERS=1 bin/rails test` -- catches test failures AND diff coverage gaps
110
+ 3. `bin/brakeman --no-pager` -- catches security issues
111
+ 4. `yarn build` -- rebuilds JS and catches ESLint issues (CI runs ESLint separately)
112
+
113
+ **Why:** CI failures cost ~5 min per round-trip. In v0.8.0, skipping ESLint and diff coverage checks locally caused 2 wasted CI cycles. Common blind spots:
114
+ - JS files need `/* global */` declarations for browser APIs (MutationObserver, requestAnimationFrame, etc.)
115
+ - Every `rescue` / fallback / error path in new source code needs test coverage (CI diff coverage gate rejects uncovered lines)
116
+ - `yarn build` must run after JS changes to sync sourcemaps
117
+
103
118
  ## QA and UAT Rules
104
119
 
105
120
  - **Browser-first verification:** During VBW QA (`/vbw:qa`) and UAT (`/vbw:verify`), ALWAYS start by using `agent-browser` to test UI scenarios yourself before presenting checkpoints to the user. Navigate to the dummy app (port 3002), take snapshots/screenshots, and verify visual and functional behavior with agents first.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- source_monitor (0.8.0)
4
+ source_monitor (0.8.1)
5
5
  cssbundling-rails (~> 1.4)
6
6
  faraday (~> 2.9)
7
7
  faraday-follow_redirects (~> 0.4)
data/Rakefile CHANGED
@@ -5,6 +5,4 @@ require "bundler/setup"
5
5
  APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
6
6
  load "rails/tasks/engine.rake"
7
7
 
8
- load "rails/tasks/statistics.rake"
9
-
10
8
  require "bundler/gem_tasks"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.8.1
@@ -60,6 +60,11 @@
60
60
  data: { turbo: false, action: "confirm-navigation#disable" },
61
61
  html: { class: "block" } do |form| %>
62
62
  <%= hidden_field_tag :filter, @filter %>
63
+ <%# Preserve selections from other pages so form submission includes ALL selected IDs %>
64
+ <% visible_ids = @paginated_entries.map { |e| e[:id] } %>
65
+ <% @preview_entries.select { |e| e[:selected] && !visible_ids.include?(e[:id]) }.each do |entry| %>
66
+ <%= hidden_field_tag "import_session[selected_source_ids][]", entry[:id] %>
67
+ <% end %>
63
68
  <div class="overflow-x-auto">
64
69
  <table class="min-w-full divide-y divide-slate-200 text-left text-sm" data-controller="select-all">
65
70
  <thead class="bg-slate-50 text-xs font-semibold uppercase tracking-wide text-slate-500">
@@ -131,7 +136,7 @@
131
136
  <%= link_to "Previous",
132
137
  source_monitor.step_import_session_path(import_session, step: "preview", **prev_params),
133
138
  class: "inline-flex items-center rounded-md border border-slate-300 px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50",
134
- data: { turbo_frame: "import_session_step" } %>
139
+ data: { turbo: true, turbo_frame: "import_session_step" } %>
135
140
  <% else %>
136
141
  <span class="inline-flex items-center rounded-md border border-slate-200 px-3 py-2 text-sm font-medium text-slate-300">Previous</span>
137
142
  <% end %>
@@ -140,7 +145,7 @@
140
145
  <%= link_to "Next",
141
146
  source_monitor.step_import_session_path(import_session, step: "preview", **next_params),
142
147
  class: "inline-flex items-center rounded-md border border-slate-300 px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50",
143
- data: { turbo_frame: "import_session_step" } %>
148
+ data: { turbo: true, turbo_frame: "import_session_step" } %>
144
149
  <% else %>
145
150
  <span class="inline-flex items-center rounded-md border border-slate-200 px-3 py-2 text-sm font-medium text-slate-300">Next</span>
146
151
  <% end %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SourceMonitor
4
- VERSION = "0.8.0"
4
+ VERSION = "0.8.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: source_monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - dchuk