Enforce strict version matching in doctor and recommend doctor on errors#3070
Enforce strict version matching in doctor and recommend doctor on errors#3070
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a DOCTOR_RECOMMENDATION constant and appends it to many diagnostic messages; promotes non-exact gem/npm constraints to errors; adds automatic version synchronization (VersionSynchronizer auto-fix), refactors version parsing to track non-exact specs, and updates related tests. Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Doctor as Doctor
participant VS as VersionSynchronizer
participant FS as FileSystem
Dev->>Doctor: run doctor (--fix)
Doctor->>VS: auto_fix_versions (sync write: true)
VS->>VS: parse specs (parse_supported_spec / parse_npm_alias_spec / strip_range_prefix)
alt changes detected
VS->>FS: write updated package.json
end
VS-->>Doctor: return changes, unsupported_specs
Doctor-->>Dev: emit diagnostics (messages include DOCTOR_RECOMMENDATION)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Autofix Details
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Wrong version used for pro package install command
- Updated
check_npm_wildcard_forto choose the Pro gem version forreact-on-rails-proinstall commands instead of always using the base gem version.
- Updated
- ✅ Fixed: Duplicate Gemfile and npm wildcard checks produce repeated errors
- Removed the extra Doctor-level wildcard check call from
check_react_on_rails_versionsso only SystemChecker emits those version-pattern errors once.
- Removed the extra Doctor-level wildcard check call from
Or push these changes by commenting:
@cursor push 060361f0e2
Preview (060361f0e2)
diff --git a/react_on_rails/lib/react_on_rails/doctor.rb b/react_on_rails/lib/react_on_rails/doctor.rb
--- a/react_on_rails/lib/react_on_rails/doctor.rb
+++ b/react_on_rails/lib/react_on_rails/doctor.rb
@@ -142,9 +142,8 @@
end
def check_react_on_rails_versions
- # Use system_checker for comprehensive package validation instead of duplicating
+ # SystemChecker already validates wildcard/version-pattern constraints.
checker.check_react_on_rails_packages
- check_version_wildcards
check_pro_package_consistency
auto_fix_versions if fix
end
@@ -565,8 +564,13 @@
return unless npm_version
if /[~^><*]/.match?(npm_version) || npm_version.include?(" ")
+ gem_version = if package_name == "react-on-rails-pro"
+ ReactOnRails::Utils.react_on_rails_pro_version
+ else
+ ReactOnRails::VERSION
+ end
install_cmd = ReactOnRails::Utils.package_manager_install_exact_command(
- package_name, ReactOnRails::VersionSyntaxConverter.new.rubygem_to_npm(ReactOnRails::VERSION)
+ package_name, ReactOnRails::VersionSyntaxConverter.new.rubygem_to_npm(gem_version)
)
checker.add_error(<<~MSG.strip)
🚫 package.json uses a non-exact version for #{package_name}: #{npm_version}
diff --git a/react_on_rails/spec/lib/react_on_rails/doctor_spec.rb b/react_on_rails/spec/lib/react_on_rails/doctor_spec.rb
--- a/react_on_rails/spec/lib/react_on_rails/doctor_spec.rb
+++ b/react_on_rails/spec/lib/react_on_rails/doctor_spec.rb
@@ -84,6 +84,41 @@
end
end
+ describe "#check_react_on_rails_versions" do
+ let(:doctor) { described_class.new(verbose: false, fix: false) }
+ let(:checker) { doctor.instance_variable_get(:@checker) }
+
+ before do
+ allow(checker).to receive(:check_react_on_rails_packages)
+ allow(doctor).to receive(:check_pro_package_consistency)
+ end
+
+ it "relies on SystemChecker for version-pattern checks" do
+ expect(checker).to receive(:check_react_on_rails_packages)
+ expect(doctor).not_to receive(:check_version_wildcards)
+ expect(doctor).to receive(:check_pro_package_consistency)
+
+ doctor.send(:check_react_on_rails_versions)
+ end
+ end
+
+ describe "#check_npm_wildcard_for" do
+ let(:doctor) { described_class.new(verbose: false, fix: false) }
+
+ it "uses the Pro gem version in the install command for react-on-rails-pro" do
+ allow(ReactOnRails::Utils).to receive(:react_on_rails_pro_version).and_return("16.4.1")
+ expect(ReactOnRails::Utils).to receive(:package_manager_install_exact_command)
+ .with("react-on-rails-pro", "16.4.1")
+ .and_return("npm install react-on-rails-pro@16.4.1")
+
+ doctor.send(
+ :check_npm_wildcard_for,
+ { "react-on-rails-pro" => "^16.4.0" },
+ "react-on-rails-pro"
+ )
+ end
+ end
+
describe "#check_react_on_rails_initializer" do
let(:doctor) { described_class.new(verbose: false, fix: false) }
let(:checker) { doctor.instance_variable_get(:@checker) }You can send follow-ups to the cloud agent here.
Review: Enforce strict version matching in doctor and recommend doctor on errorsOverall this is a well-structured PR that properly aligns the Doctor/SystemChecker diagnostic behavior with the runtime enforcement already in I left inline comments for the issues below — one is a bug, the rest are design/consistency concerns. Bug (should fix before merge)
Design concerns
Smaller issues
|
There was a problem hiding this comment.
Review Summary
This PR improves the developer experience by making wildcard version constraints hard errors (matching runtime behavior), adding bundle exec rake react_on_rails:doctor guidance to all relevant error messages, extending Pro-package coverage, and teaching sync_versions to rewrite range specs (^, ~, >=) rather than skip them.
Overall assessment: Safe to merge after fixing the wrong version in the Pro package install command suggestion (see inline comment). All other changes are clean improvements.
Confidence score: 4/5
File Analyses
| File | Confidence | Summary |
|---|---|---|
doctor.rb |
3/5 | Adds auto_fix_versions, escalates wildcard checks to errors, extends Pro checks; check_npm_wildcard_for uses wrong version for Pro install command |
system_checker.rb |
5/5 | Escalates wildcard version checks from warnings to errors and extends checks to cover Pro packages |
version_checker.rb |
5/5 | Adds DOCTOR_RECOMMENDATION to all runtime version error messages |
version_synchronizer.rb |
5/5 | Adds range-prefix stripping so ^/~/>= specs are parsed and rewritten instead of skipped |
error.rb |
5/5 | Introduces DOCTOR_RECOMMENDATION constant for consistent error messaging |
configuration.rb |
5/5 | Appends DOCTOR_RECOMMENDATION to configuration validation error messages |
packer_utils.rb |
5/5 | Appends DOCTOR_RECOMMENDATION to nested_entries and autobundling error messages |
system_checker_spec.rb |
5/5 | Updates tests to expect errors instead of warnings for wildcard version patterns |
version_synchronizer_spec.rb |
5/5 | Updates test to reflect new range-spec rewriting behavior instead of skipping |
Sequence Diagram
sequenceDiagram
participant Dev as Developer
participant VC as VersionChecker (runtime)
participant Doc as Doctor rake task
participant SS as SystemChecker
participant VS as VersionSynchronizer
Dev->>VC: App boots
VC-->>Dev: Error + DOCTOR_RECOMMENDATION if wildcard/mismatch
Dev->>Doc: bundle exec rake react_on_rails:doctor [FIX=true]
Doc->>SS: check_react_on_rails_packages
SS-->>Doc: errors on wildcard constraints (npm & gem)
Doc->>SS: check_version_wildcards (npm + gem, base + pro)
SS-->>Doc: error if ^/~/>= found
Doc->>SS: check_pro_package_consistency
SS-->>Doc: error on mismatched pro/base setup
alt FIX=true
Doc->>VS: sync(write: true)
VS-->>Doc: rewrites range specs to exact versions
Doc-->>Dev: versions synced
else FIX=false
Doc-->>Dev: Suggest sync_versions WRITE=true
end
Greptile SummaryThis PR improves the developer experience by making wildcard version constraints hard errors (matching runtime behavior), adding Confidence Score: 4/5Safe to merge after fixing the wrong version in the Pro package install command suggestion One P1 bug where the doctor wildcard-fix command for react-on-rails-pro will suggest the wrong package version; all other changes are clean improvements with passing specs react_on_rails/lib/react_on_rails/doctor.rb lines 568-570 Important Files Changed
Sequence DiagramsequenceDiagram
participant Dev as Developer
participant VC as VersionChecker (runtime)
participant Doc as Doctor rake task
participant SS as SystemChecker
participant VS as VersionSynchronizer
Dev->>VC: App boots
VC-->>Dev: Error + DOCTOR_RECOMMENDATION if wildcard/mismatch
Dev->>Doc: bundle exec rake react_on_rails:doctor [FIX=true]
Doc->>SS: check_react_on_rails_packages
SS-->>Doc: errors on wildcard constraints (npm & gem)
Doc->>SS: check_version_wildcards (npm + gem, base + pro)
SS-->>Doc: error if ^/~/>= found
Doc->>SS: check_pro_package_consistency
SS-->>Doc: error on mismatched pro/base setup
alt FIX=true
Doc->>VS: sync(write: true)
VS-->>Doc: rewrites range specs to exact versions
Doc-->>Dev: versions synced
else FIX=false
Doc-->>Dev: Suggest sync_versions WRITE=true
end
Reviews (1): Last reviewed commit: "Enforce strict version matching in docto..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
react_on_rails/lib/react_on_rails/doctor.rb (1)
144-150:⚠️ Potential issue | 🟠 MajorRun the version checks after
FIX=truewritespackage.json.Line 149 mutates the file only after
checker.check_react_on_rails_packagesandcheck_version_wildcardshave already recorded errors from the old contents. A successful sync will still leave stale errors inchecker.messages, soFIX=true rake react_on_rails:doctorcan exit non-zero even though it already repaired the version drift.♻️ Proposed fix
def check_react_on_rails_versions + auto_fix_versions if fix # Use system_checker for comprehensive package validation instead of duplicating checker.check_react_on_rails_packages check_version_wildcards check_pro_package_consistency - auto_fix_versions if fix endAlso applies to: 585-602
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/lib/react_on_rails/doctor.rb` around lines 144 - 150, The current check_react_on_rails_versions flow runs checker.check_react_on_rails_packages and check_version_wildcards before auto_fix_versions, causing stale errors in checker.messages after FIX=true writes package.json; change the flow so that if fix is truthy you call auto_fix_versions (which mutates package.json) before invoking checker.check_react_on_rails_packages and check_version_wildcards, and clear or re-run checker.messages (or reinstantiate the checker) after the auto-fix so the subsequent checks reflect the updated file; apply the same reorder+clear logic to the analogous block/method around the 585-602 region to prevent the same stale-error issue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@react_on_rails/lib/react_on_rails/doctor.rb`:
- Around line 568-579: The error message builds install_cmd using
ReactOnRails::VERSION which causes incorrect npm install suggestions for Pro
users; change the logic that computes install_cmd (where
ReactOnRails::Utils.package_manager_install_exact_command is invoked) to use
ReactOnRails::Utils.react_on_rails_pro_version when the package_name corresponds
to the Pro package (or when react_on_rails_pro_version is present) instead of
always using ReactOnRails::VERSION, then pass that computed version into
ReactOnRails::VersionSyntaxConverter and keep the rest of the checker.add_error
message intact so the fix hint points to the correct Pro gem version.
- Around line 527-544: The gem and npm wildcard checks are too permissive;
update check_gem_wildcard_for to examine all Gemfile lines for a given gem (not
just the first match) and detect missing or continuation-line version specs
(treat absence or version on following lines as non-exact) and update
check_npm_wildcard_for to stop using a simple blacklist and instead call or
reuse VersionChecker.semver_wildcard? to determine if an npm spec is non-exact
(treat numeric ranges like "19", "19.0", tags like "latest"/"beta", and range
operators as wildcards); keep using checker.add_error and checker.add_success
but base the decision on VersionChecker.semver_wildcard? (or equivalent
exact-match whitelist) and ensure the suggested exact gem version uses the same
ReactOnRails::VERSION / Utils.react_on_rails_pro_version logic already present.
In `@react_on_rails/lib/react_on_rails/system_checker.rb`:
- Around line 247-259: The code currently converts any gem/npm version mismatch
into a hard doctor error (add_error) and recommends sync_versions, but that
should not happen for workspace: or local path/URL installs which VersionChecker
explicitly skips and which VersionSynchronizer cannot rewrite; update the
mismatch branch in system_checker.rb to first detect local/workspace specs using
VersionChecker (call the existing helper that identifies skipped/local specs,
e.g. VersionChecker.local_spec? or VersionChecker.skipped_spec?) and if true do
NOT call add_error or recommend sync_versions (either skip the check or emit a
non-failing warning/message); otherwise keep the existing add_error with
gem_version, package_name, npm_version and the sync_versions fix text. Ensure
you reference and reuse the VersionChecker helper so local-link/monorepo setups
are not hard-errored.
- Around line 766-785: The current check_gemfile_version_pattern_for method only
matches a subset of non-exact operators; replace the fragile regex-based
detection with proper parsing using RubyGems API: for the found gem_line (in
check_gemfile_version_pattern_for) extract the version requirement (e.g. via
Gem::Requirement.extract or Gem::Requirement.new on the version string parsed
from gem_line) and call .exact? to decide if it’s an exact constraint; if not
exact, call add_error with the same message (using
ReactOnRails::Utils.react_on_rails_pro_version or ReactOnRails::VERSION for
#{gem_name}) so all non-exact operators like >, <, <=, >=, ~, ^ are reliably
caught.
In `@react_on_rails/lib/react_on_rails/version_synchronizer.rb`:
- Around line 149-156: The normalization in strip_range_prefix currently
discards whether the original spec was a range (non-exact), causing
detect_changes to treat range specs like exact pins; modify the
parsing/normalization so you preserve a boolean flag (e.g.,
parsed_spec[:non_exact]) when the original version_spec contained range prefixes
or non-exact forms, and update detect_changes to skip only when
normalized_current_version == expected_version AND parsed_spec[:non_exact] is
false (i.e., only skip exact-original specs); ensure this non_exact flag is set
where strip_range_prefix/related parsing runs and used in the detect_changes
comparisons that reference normalized_current_version and expected_version.
---
Outside diff comments:
In `@react_on_rails/lib/react_on_rails/doctor.rb`:
- Around line 144-150: The current check_react_on_rails_versions flow runs
checker.check_react_on_rails_packages and check_version_wildcards before
auto_fix_versions, causing stale errors in checker.messages after FIX=true
writes package.json; change the flow so that if fix is truthy you call
auto_fix_versions (which mutates package.json) before invoking
checker.check_react_on_rails_packages and check_version_wildcards, and clear or
re-run checker.messages (or reinstantiate the checker) after the auto-fix so the
subsequent checks reflect the updated file; apply the same reorder+clear logic
to the analogous block/method around the 585-602 region to prevent the same
stale-error issue.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b618e850-49ad-4a0d-9cc6-59ab5e2d7e9b
📒 Files selected for processing (9)
react_on_rails/lib/react_on_rails/configuration.rbreact_on_rails/lib/react_on_rails/doctor.rbreact_on_rails/lib/react_on_rails/error.rbreact_on_rails/lib/react_on_rails/packer_utils.rbreact_on_rails/lib/react_on_rails/system_checker.rbreact_on_rails/lib/react_on_rails/version_checker.rbreact_on_rails/lib/react_on_rails/version_synchronizer.rbreact_on_rails/spec/lib/react_on_rails/system_checker_spec.rbreact_on_rails/spec/lib/react_on_rails/version_synchronizer_spec.rb
Review SummaryThe overall direction is solid — escalating wildcard constraints to errors, extending checks to Pro packages, and centralizing the "run doctor" guidance are all improvements. The Bugs1. False positive success for unconstrained Gemfile entries (see inline on
2. Conflicting success + error for range specs in When Dead Code3. Its only call site ( 4. Removed from Minor5. Silent intent change for The range-prefix regex also matches bare 6. Minor coupling concern — see inline comment. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Refactored SystemChecker methods are now unreachable dead code
- Removed the now-unreachable wildcard/version-pattern methods from SystemChecker and deleted their direct private-method specs so only Doctor’s active wildcard checks remain.
Or push these changes by commenting:
@cursor push e5fd6d7032
Preview (e5fd6d7032)
diff --git a/react_on_rails/lib/react_on_rails/system_checker.rb b/react_on_rails/lib/react_on_rails/system_checker.rb
--- a/react_on_rails/lib/react_on_rails/system_checker.rb
+++ b/react_on_rails/lib/react_on_rails/system_checker.rb
@@ -736,58 +736,6 @@
MSG
end
- def check_version_patterns(npm_version, _gem_version)
- # Check for version range patterns in package.json
- return unless /^[\^~><*]/.match?(npm_version) || npm_version.include?(" ")
-
- add_error(<<~MSG.strip)
- 🚫 NPM package uses a non-exact version: #{npm_version}
-
- React on Rails requires exact version matching. Non-exact constraints will
- cause a runtime error on app startup.
-
- Fix: bundle exec rake react_on_rails:sync_versions WRITE=true
- MSG
- end
-
- def check_gemfile_version_patterns
- gemfile_path = ENV["BUNDLE_GEMFILE"] || "Gemfile"
- return unless File.exist?(gemfile_path)
-
- begin
- gemfile_content = File.read(gemfile_path)
- check_gemfile_version_pattern_for(gemfile_content, "react_on_rails")
- if ReactOnRails::Utils.react_on_rails_pro?
- check_gemfile_version_pattern_for(gemfile_content,
- "react_on_rails_pro")
- end
- rescue StandardError
- # Ignore errors reading Gemfile
- end
- end
-
- def check_gemfile_version_pattern_for(gemfile_content, gem_name)
- gem_line = gemfile_content.lines.find { |line| line.match(/^\s*gem\s+['"]#{gem_name}['"]/) }
- return unless gem_line
-
- return unless /['"][~^]/.match?(gem_line) || />=\s*/.match?(gem_line)
-
- version = if gem_name == "react_on_rails_pro"
- ReactOnRails::Utils.react_on_rails_pro_version
- else
- ReactOnRails::VERSION
- end
- add_error(<<~MSG.strip)
- 🚫 Gemfile uses a non-exact version constraint for #{gem_name}.
-
- React on Rails requires exact version matching between the gem and npm package.
- Non-exact constraints can cause versions to drift apart, leading to runtime errors.
-
- Fix: Use an exact version in your Gemfile:
- gem '#{gem_name}', '#{version}'
- MSG
- end
-
def report_dependency_versions(package_json)
all_deps = (package_json["dependencies"] || {}).merge(package_json["devDependencies"] || {})
diff --git a/react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb b/react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
--- a/react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
+++ b/react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
@@ -220,72 +220,6 @@
end
end
- describe "#check_version_patterns" do
- it "errors on caret version patterns" do
- checker.send(:check_version_patterns, "^16.0.0", "16.0.0")
- expect(checker.errors?).to be true
- expect(checker.messages.last[:content]).to include("non-exact version")
- end
-
- it "errors on tilde version patterns" do
- checker.send(:check_version_patterns, "~16.0.0", "16.0.0")
- expect(checker.errors?).to be true
- expect(checker.messages.last[:content]).to include("non-exact version")
- end
-
- it "does not warn about exact versions" do
- initial_message_count = checker.messages.count
- checker.send(:check_version_patterns, "16.0.0", "16.0.0")
- expect(checker.messages.count).to eq(initial_message_count)
- end
- end
-
- describe "#check_gemfile_version_patterns" do
- context "when Gemfile has version patterns" do
- let(:gemfile_content) do
- <<~GEMFILE
- gem 'rails', '~> 7.0'
- gem 'react_on_rails', '~> 16.0'
- gem 'other_gem'
- GEMFILE
- end
-
- before do
- gemfile_path = ENV["BUNDLE_GEMFILE"] || "Gemfile"
- allow(File).to receive(:exist?).with(gemfile_path).and_return(true)
- allow(File).to receive(:read).with(gemfile_path).and_return(gemfile_content)
- stub_const("ReactOnRails::VERSION", "16.0.0")
- end
-
- it "errors on non-exact version patterns" do
- checker.send(:check_gemfile_version_patterns)
- expect(checker.errors?).to be true
- expect(checker.messages.last[:content]).to include("non-exact version constraint")
- end
- end
-
- context "when Gemfile has exact versions" do
- let(:gemfile_content) do
- <<~GEMFILE
- gem 'rails', '7.0.0'
- gem 'react_on_rails', '16.0.0'
- GEMFILE
- end
-
- before do
- gemfile_path = ENV["BUNDLE_GEMFILE"] || "Gemfile"
- allow(File).to receive(:exist?).with(gemfile_path).and_return(true)
- allow(File).to receive(:read).with(gemfile_path).and_return(gemfile_content)
- end
-
- it "does not warn about exact versions" do
- initial_message_count = checker.messages.count
- checker.send(:check_gemfile_version_patterns)
- expect(checker.messages.count).to eq(initial_message_count)
- end
- end
- end
-
describe "#check_react_on_rails_npm_package" do
context "when package.json exists with react-on-rails" do
let(:package_json_content) doYou can send follow-ups to the cloud agent here.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
react_on_rails/lib/react_on_rails/doctor.rb (1)
610-627: Consider surfacing unsupported/missing specs from auto-fix results.The
VersionSynchronizer.syncreturnsunsupported_specsandmissing_source_specsin itsResultstruct, but these are not reported to the user. When auto-fix can't handle certain specs (e.g., upper-bound constraints like<or<=), the user may benefit from knowing why no changes were made.💡 Optional enhancement to report skipped specs
if result.changes.any? checker.add_success(" ✅ FIX=true: Synced package.json versions (#{result.changes.length} update(s))") result.changes.each do |change| checker.add_info(" #{change[:section]}.#{change[:package]}: #{change[:from]} -> #{change[:to]}") end else checker.add_info(" ℹ️ FIX=true: No package.json version changes needed") end + + if result.unsupported_specs.any? + checker.add_info(" ℹ️ FIX=true: Skipped unsupported specs: #{result.unsupported_specs.join(', ')}") + end + + if result.missing_source_specs.any? + checker.add_info(" ℹ️ FIX=true: Missing source versions: #{result.missing_source_specs.join(', ')}") + end rescue StandardError => e🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@react_on_rails/lib/react_on_rails/doctor.rb` around lines 610 - 627, The auto_fix_versions method currently ignores result.unsupported_specs and result.missing_source_specs from ReactOnRails::VersionSynchronizer.sync; update auto_fix_versions to check result.unsupported_specs and result.missing_source_specs after obtaining result and report them via checker.add_warning or checker.add_info (e.g., " ⚠️ FIX=true: Unsupported specs skipped: ..." and " ⚠️ FIX=true: Missing source specs: ...") so users see which packages were skipped and why; locate this logic in the auto_fix_versions method and use the existing checker object to surface these lists when they are non-empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@react_on_rails/lib/react_on_rails/doctor.rb`:
- Around line 583-608: In check_npm_wildcard_for, skip specs that are local or
workspace links by returning success (or skipping validation) when npm_version
starts with "workspace:", "file:" or "link:" (same guard used in
system_checker.rb) before applying
ReactOnRails::VersionSynchronizer::EXACT_VERSION_REGEX; update the logic in
check_npm_wildcard_for to detect these prefixes and avoid flagging them as
errors when present.
In `@react_on_rails/lib/react_on_rails/system_checker.rb`:
- Around line 739-751: Remove the dead-version-pattern helper methods from
SystemChecker: delete check_version_patterns, check_gemfile_version_patterns,
and check_gemfile_version_pattern_for along with any private helper references
and their tests; ensure no other code calls these methods (search for those
exact method names) and leave Doctor#check_version_wildcards as the single
source of truth for wildcard/non-exact version checks to avoid duplicate errors.
---
Nitpick comments:
In `@react_on_rails/lib/react_on_rails/doctor.rb`:
- Around line 610-627: The auto_fix_versions method currently ignores
result.unsupported_specs and result.missing_source_specs from
ReactOnRails::VersionSynchronizer.sync; update auto_fix_versions to check
result.unsupported_specs and result.missing_source_specs after obtaining result
and report them via checker.add_warning or checker.add_info (e.g., " ⚠️
FIX=true: Unsupported specs skipped: ..." and " ⚠️ FIX=true: Missing source
specs: ...") so users see which packages were skipped and why; locate this logic
in the auto_fix_versions method and use the existing checker object to surface
these lists when they are non-empty.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cfc3dd28-58da-4d05-a288-5e50fdfc03c0
📒 Files selected for processing (4)
react_on_rails/lib/react_on_rails/doctor.rbreact_on_rails/lib/react_on_rails/system_checker.rbreact_on_rails/lib/react_on_rails/version_synchronizer.rbreact_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
✅ Files skipped from review due to trivial changes (1)
- react_on_rails/lib/react_on_rails/version_synchronizer.rb
🚧 Files skipped from review as they are similar to previous changes (1)
- react_on_rails/spec/lib/react_on_rails/system_checker_spec.rb
Review feedback addressedAll 15 review threads resolved across 4 reviewers (claude[bot], cursor[bot], greptile-apps[bot], coderabbitai[bot]). Fixed (items 1-6)
Skipped with rationale (replied + resolved)
Tests253 specs passing, 0 failures. RuboCop clean. Posted by I (Claude Code) addressing review feedback on PR #3070. |
ReviewThe overall direction is solid — aligning doctor's strictness with the runtime VersionChecker behavior and surfacing actionable fix commands is the right call. A few issues need attention before merging: Bugs1. 2. No-version Gemfile entry is reported as success (inline comment on Dead Code3. Three unreachable methods remain in Improvement4. Minor Observations
|
Code Review: PR #3070Overall this is a solid, well-motivated PR. The alignment between doctor's static checks and the runtime Bug —
|
- Remove = from non_exact_range_spec? regex: =16.5.0 is a valid exact pin in npm semver, not a range. Including it caused false "non-exact version" errors in doctor output. - Add = to strip_range_prefix so VersionSynchronizer can auto-fix =X.Y.Z specs during sync. - Guard the FIX=true info message behind result.changes.any? so it only appears when changes were actually made. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review feedback addressed in 223edd4I (Claude Code) triaged 4 unresolved review comments from claude[bot]. Fixed (2):
Skipped with rationale (2):
All 4 threads replied to and resolved. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON, but it could not run because on-demand usage is turned off. To enable Bugbot Autofix, turn on on-demand usage and set a spend limit in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 223edd4. Configure here.
|
|
||
| def non_exact_range_spec?(npm_version) | ||
| npm_version.match?(/\A[\^~><*]/) || npm_version.include?(" ") | ||
| end |
There was a problem hiding this comment.
Missing = in non_exact_range_spec? character class
Medium Severity
The non_exact_range_spec? regex /\A[\^~><*]/ is missing the = character that the PR discussion explicitly says was added. Explicit-equals npm specs like =16.5.0 won't be caught, allowing them to flow into check_package_version_sync's version-comparison code instead of being silently delegated to Doctor. This contradicts the comment at lines 225–227 stating "Non-exact version checks are handled by Doctor#check_version_wildcards to avoid duplicate diagnostics," resulting in both SystemChecker and Doctor reporting on the same spec.
Reviewed by Cursor Bugbot for commit 223edd4. Configure here.
| # frozen_string_literal: true | ||
|
|
||
| module ReactOnRails | ||
| DOCTOR_RECOMMENDATION = "For detailed diagnostics, run: bundle exec rake react_on_rails:doctor" |
There was a problem hiding this comment.
The DOCTOR_RECOMMENDATION string constant is semantically unrelated to error classes, yet it now loads alongside ReactOnRails::Error whenever react_on_rails/error is required. This couples an operational message to a foundational error-class file and can create ordering confusion for any autoloader that expects error.rb to define only error classes.
Consider moving it to a dedicated constants file (e.g. lib/react_on_rails/constants.rb) or hoisting it into the top-level lib/react_on_rails.rb where other module-level constants live:
| DOCTOR_RECOMMENDATION = "For detailed diagnostics, run: bundle exec rake react_on_rails:doctor" | |
| # frozen_string_literal: true | |
| module ReactOnRails | |
| DOCTOR_RECOMMENDATION = "For detailed diagnostics, run: bundle exec rake react_on_rails:doctor" | |
| class Error < StandardError | |
| end | |
| end |
(No functional change needed here if the placement is intentional, but a comment explaining why it lives in error.rb would help future readers.)
|
|
||
| def check_gem_wildcard_for(gemfile_content, gem_name) | ||
| lines = gemfile_content.lines | ||
| line_index = lines.index { |line| line.match(/^\s*gem\s+['"]#{gem_name}['"]/) } |
There was a problem hiding this comment.
gem_name is interpolated directly into a Regexp literal without escaping. The two current call-sites pass "react_on_rails" and "react_on_rails_pro" — both safe — but this is a latent robustness issue if the method is ever called with an arbitrary string.
| line_index = lines.index { |line| line.match(/^\s*gem\s+['"]#{gem_name}['"]/) } | |
| line_index = lines.index { |line| line.match(/^\s*gem\s+['"]#{Regexp.escape(gem_name)}['"]/) } |
| next unless deps.key?(package_name) | ||
|
|
||
| check_npm_wildcard_for(deps, package_name) | ||
| break # only report once per package (avoid duplicates if listed in multiple sections) |
There was a problem hiding this comment.
The break correctly avoids double-reporting a package that appears in multiple sections, but it silently picks whichever section happens to be enumerated first (PACKAGE_SECTIONS order: dependencies → devDependencies → …). If a package appears in both dependencies and devDependencies with different versions, the second entry is completely ignored.
This is probably acceptable for the common case, but a one-line comment would clarify the intent and prevent a future reader from thinking the break is a bug:
| break # only report once per package (avoid duplicates if listed in multiple sections) | |
| break # report once per package; first-found section wins (avoids duplicate diagnostics) |
| if result.changes.any? | ||
| checker.add_info(" ℹ️ FIX=true only updates package.json; update Gemfile constraints manually if needed.") | ||
| end |
There was a problem hiding this comment.
The Gemfile-constraint guidance is only shown when result.changes.any?, so it is never displayed when FIX=true but npm is already synced while the Gemfile still has wildcard constraints. In that scenario auto_fix_versions runs, finds nothing to write, and the user silently misses the hint that they still need to fix Gemfile by hand.
The note should also appear when there are unsupported/skipped specs (which includes Gemfile wildcards that couldn't be auto-fixed):
| if result.changes.any? | |
| checker.add_info(" ℹ️ FIX=true only updates package.json; update Gemfile constraints manually if needed.") | |
| end | |
| if result.changes.any? || result.unsupported_specs.any? || result.missing_source_specs.any? | |
| checker.add_info(" ℹ️ FIX=true only updates package.json; update Gemfile constraints manually if needed.") | |
| end |
Review: Enforce strict version matching in doctor and recommend doctor on errorsOverall this is a well-structured PR that closes a real UX gap — the old behaviour where doctor only warned while the runtime hard-crashed was confusing. The test coverage is solid and the refactors are clean. A few things worth addressing before merging: Breaking change needs an UPGRADING noteThe escalation of minor version mismatches from warnings to errors (in The CHANGELOG has a line about it, but this deserves an entry in
|
…e-dedup * origin/main: (51 commits) Fix Content-Length mismatch and null renderingRequest errors in node renderer (#3069) Improve memory debugging docs with simpler heap snapshot approach (#3072) Enforce strict version matching in doctor and recommend doctor on errors (#3070) Remove immediate_hydration feature from codebase (#2834) Fix infinite fork loop when node renderer worker fails to bind port (#2881) Fix TanStack Router SSR hydration mismatch in Pro async path (#2932) Improve node renderer error messages for malformed render requests (#3068) Add interactive mode prompt to create-react-on-rails-app (#3063) docs: replace hardcoded version numbers with unversioned install commands (#2893) Remove Contributing section from docs sidebar (#3064) Consolidate docs comparison pages into single evaluation entry (#3065) Docs route cleanup: canonicalize worst verbose URL slugs (#3067) Add agent summary blocks to high-value docs pages (#3066) Fix brittle positional assertions in create-app tests (#2923) Auto-resolve renderer password from ENV in Rails Pro (#2921) Standardize bundle env vars from =yes to =true (#2925) Fix Pro generator multiline and template-literal rewrites (#2918) Fix spec/dummy Procfile.dev SERVER_BUNDLE_ONLY to match template convention (#2922) Add llms docs entry points (#2916) Bump version to 16.6.0.rc.0 ... # Conflicts: # packages/create-react-on-rails-app/src/create-app.ts
…lacement-2835-main * origin/main: (44 commits) Fix Content-Length mismatch and null renderingRequest errors in node renderer (#3069) Improve memory debugging docs with simpler heap snapshot approach (#3072) Enforce strict version matching in doctor and recommend doctor on errors (#3070) Remove immediate_hydration feature from codebase (#2834) Fix infinite fork loop when node renderer worker fails to bind port (#2881) Fix TanStack Router SSR hydration mismatch in Pro async path (#2932) Improve node renderer error messages for malformed render requests (#3068) Add interactive mode prompt to create-react-on-rails-app (#3063) docs: replace hardcoded version numbers with unversioned install commands (#2893) Remove Contributing section from docs sidebar (#3064) Consolidate docs comparison pages into single evaluation entry (#3065) Docs route cleanup: canonicalize worst verbose URL slugs (#3067) Add agent summary blocks to high-value docs pages (#3066) Fix brittle positional assertions in create-app tests (#2923) Auto-resolve renderer password from ENV in Rails Pro (#2921) Standardize bundle env vars from =yes to =true (#2925) Fix Pro generator multiline and template-literal rewrites (#2918) Fix spec/dummy Procfile.dev SERVER_BUNDLE_ONLY to match template convention (#2922) Add llms docs entry points (#2916) Bump version to 16.6.0.rc.0 ... # Conflicts: # CHANGELOG.md
### Summary Adds missing changelog entries to the `[Unreleased]` section for PRs merged since `v16.6.0.rc.0`. Analyzed 19 commits on `origin/main` since the last tag, identified 1 missing user-visible PR (#3069), and skipped 10 non-user-visible PRs (docs, tests, internal refactors). **New entries added:** - **Added**: `[Pro] Configurable HTTP keep-alive timeout for node renderer connections` (PR #3069) - **Fixed**: `[Pro] Fixed SSR failures from stale persistent HTTP/2 connections` (PR #3069) **Entries already present** (added in prior changelog updates): PRs #2834, #2881, #2918, #2921, #2923, #2932, #3063, #3068, #3070. **Skipped** (not user-visible): #2893 (docs), #2916 (docs), #2922 (test fix), #2923 (test fix), #2925 (internal refactor), #3064 (docs), #3065 (docs), #3066 (docs), #3067 (docs), #3072 (docs). ### Pull Request checklist - [x] ~Add/update test to cover these changes~ - [x] ~Update documentation~ - [x] Update CHANGELOG file ### Other Information No code changes — CHANGELOG.md only. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk because this PR only changes documentation (`CHANGELOG.md`) and does not modify runtime code. > > **Overview** > Updates `CHANGELOG.md` *[Unreleased]* to include missing Pro release notes for PR `#3069`, documenting the new `renderer_http_keep_alive_timeout` config and the associated fix for SSR failures from stale persistent HTTP/2 connections to the node renderer. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8d1a480. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Interactive mode selection prompt for CLI tool when no explicit mode is specified * Configurable keep-alive timeout setting for Pro users (default 30 seconds) * **Bug Fixes** * Enhanced validation and error handling for invalid request payloads * Improved template literal handling in code generation * Better HTTP connection stability with enhanced diagnostic messaging <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ors (#3070) ## Summary - **Escalate doctor wildcard checks from warnings to errors** — matching runtime VersionChecker behavior that hard-crashes on non-exact versions (^, ~, >=). Previously, doctor only warned about these patterns while the app would crash at boot. - **Extend wildcard checks to cover Pro packages** — `check_npm_wildcards` and `check_gem_wildcards` now check both `react-on-rails`/`react_on_rails` and `react-on-rails-pro`/`react_on_rails_pro`. - **Add doctor recommendation to all VersionChecker error messages** — every runtime crash from version_checker.rb now tells users to run `bundle exec rake react_on_rails:doctor`. - **Add doctor recommendation to configuration and packer_utils errors** — config validation errors, autobundling errors, and compile conflicts all now suggest running doctor. - **Doctor suggests `sync_versions` on version mismatches** — error messages now include `bundle exec rake react_on_rails:sync_versions WRITE=true` as a fix. - **`FIX=true` doctor auto-runs `sync_versions`** — when doctor detects version issues and FIX mode is enabled, it automatically syncs package.json versions to match gem versions. - **`sync_versions` now handles range specs instead of skipping them** — previously `^16.5.0`, `~16.5.0`, `>=16.5.0` were reported as "unsupported" and skipped. Now they're parsed, the range prefix is stripped, and the version is rewritten to the exact expected version. Addresses review feedback from #2893 (review) ## Test plan - [x] `version_checker_spec.rb` — 74 examples, 0 failures - [x] `version_synchronizer_spec.rb` — 20 examples, 0 failures (updated test for new range-handling behavior) - [x] `system_checker_spec.rb` — 81 examples, 0 failures (updated tests for error vs warning escalation) - [x] `doctor_spec.rb` — 152 examples, 0 failures - [x] RuboCop — 0 offenses on all changed files ��� Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Tightens version validation from warnings to errors and adds auto-fix behavior, which may cause previously passing CI/boot flows to fail until versions are pinned exactly. Changes are mostly in diagnostic tooling but affect startup/runtime error paths and developer workflows. > > **Overview** > Makes version hygiene **strict and actionable**: `react_on_rails:doctor` now treats non-exact gem/npm specs (`^`, `~`, `>=`, etc.) as errors (including Pro gems/packages) and can auto-run `sync_versions` when `FIX=true` to rewrite range specs to exact expected versions. > > Improves remediation messaging across the stack by adding a shared `ReactOnRails::DOCTOR_RECOMMENDATION` to configuration/autobundling validations and `VersionChecker` runtime crashes, and by updating mismatch errors to recommend `bundle exec rake react_on_rails:sync_versions WRITE=true`. > > `sync_versions` is enhanced to parse and rewrite supported semver range prefixes (and npm alias variants) while refusing rewrites that would violate a declared `>=` lower bound; tests and a React 18/19-compatible `act` helper in the TanStack Router Pro test are updated accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 223edd4. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Optional automatic version synchronization that can update package files and report changes. * **Bug Fixes** * Non-exact version constraints and minor-version mismatches now produce errors (with clearer remediation steps). * Improved handling of workspace/local package specs and stricter version-matching diagnostics. * **Chores** * Diagnostic messages now include guidance to run the doctor task for remediation. * **Tests** * Updated tests and test helpers to reflect the new validation and sync behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
### Summary Adds missing changelog entries to the `[Unreleased]` section for PRs merged since `v16.6.0.rc.0`. Analyzed 19 commits on `origin/main` since the last tag, identified 1 missing user-visible PR (#3069), and skipped 10 non-user-visible PRs (docs, tests, internal refactors). **New entries added:** - **Added**: `[Pro] Configurable HTTP keep-alive timeout for node renderer connections` (PR #3069) - **Fixed**: `[Pro] Fixed SSR failures from stale persistent HTTP/2 connections` (PR #3069) **Entries already present** (added in prior changelog updates): PRs #2834, #2881, #2918, #2921, #2923, #2932, #3063, #3068, #3070. **Skipped** (not user-visible): #2893 (docs), #2916 (docs), #2922 (test fix), #2923 (test fix), #2925 (internal refactor), #3064 (docs), #3065 (docs), #3066 (docs), #3067 (docs), #3072 (docs). ### Pull Request checklist - [x] ~Add/update test to cover these changes~ - [x] ~Update documentation~ - [x] Update CHANGELOG file ### Other Information No code changes — CHANGELOG.md only. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk because this PR only changes documentation (`CHANGELOG.md`) and does not modify runtime code. > > **Overview** > Updates `CHANGELOG.md` *[Unreleased]* to include missing Pro release notes for PR `#3069`, documenting the new `renderer_http_keep_alive_timeout` config and the associated fix for SSR failures from stale persistent HTTP/2 connections to the node renderer. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8d1a480. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Interactive mode selection prompt for CLI tool when no explicit mode is specified * Configurable keep-alive timeout setting for Pro users (default 30 seconds) * **Bug Fixes** * Enhanced validation and error handling for invalid request payloads * Improved template literal handling in code generation * Better HTTP connection stability with enhanced diagnostic messaging <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ors (#3070) ## Summary - **Escalate doctor wildcard checks from warnings to errors** — matching runtime VersionChecker behavior that hard-crashes on non-exact versions (^, ~, >=). Previously, doctor only warned about these patterns while the app would crash at boot. - **Extend wildcard checks to cover Pro packages** — `check_npm_wildcards` and `check_gem_wildcards` now check both `react-on-rails`/`react_on_rails` and `react-on-rails-pro`/`react_on_rails_pro`. - **Add doctor recommendation to all VersionChecker error messages** — every runtime crash from version_checker.rb now tells users to run `bundle exec rake react_on_rails:doctor`. - **Add doctor recommendation to configuration and packer_utils errors** — config validation errors, autobundling errors, and compile conflicts all now suggest running doctor. - **Doctor suggests `sync_versions` on version mismatches** — error messages now include `bundle exec rake react_on_rails:sync_versions WRITE=true` as a fix. - **`FIX=true` doctor auto-runs `sync_versions`** — when doctor detects version issues and FIX mode is enabled, it automatically syncs package.json versions to match gem versions. - **`sync_versions` now handles range specs instead of skipping them** — previously `^16.5.0`, `~16.5.0`, `>=16.5.0` were reported as "unsupported" and skipped. Now they're parsed, the range prefix is stripped, and the version is rewritten to the exact expected version. Addresses review feedback from #2893 (review) ## Test plan - [x] `version_checker_spec.rb` — 74 examples, 0 failures - [x] `version_synchronizer_spec.rb` — 20 examples, 0 failures (updated test for new range-handling behavior) - [x] `system_checker_spec.rb` — 81 examples, 0 failures (updated tests for error vs warning escalation) - [x] `doctor_spec.rb` — 152 examples, 0 failures - [x] RuboCop — 0 offenses on all changed files ��� Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Tightens version validation from warnings to errors and adds auto-fix behavior, which may cause previously passing CI/boot flows to fail until versions are pinned exactly. Changes are mostly in diagnostic tooling but affect startup/runtime error paths and developer workflows. > > **Overview** > Makes version hygiene **strict and actionable**: `react_on_rails:doctor` now treats non-exact gem/npm specs (`^`, `~`, `>=`, etc.) as errors (including Pro gems/packages) and can auto-run `sync_versions` when `FIX=true` to rewrite range specs to exact expected versions. > > Improves remediation messaging across the stack by adding a shared `ReactOnRails::DOCTOR_RECOMMENDATION` to configuration/autobundling validations and `VersionChecker` runtime crashes, and by updating mismatch errors to recommend `bundle exec rake react_on_rails:sync_versions WRITE=true`. > > `sync_versions` is enhanced to parse and rewrite supported semver range prefixes (and npm alias variants) while refusing rewrites that would violate a declared `>=` lower bound; tests and a React 18/19-compatible `act` helper in the TanStack Router Pro test are updated accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 223edd4. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Optional automatic version synchronization that can update package files and report changes. * **Bug Fixes** * Non-exact version constraints and minor-version mismatches now produce errors (with clearer remediation steps). * Improved handling of workspace/local package specs and stricter version-matching diagnostics. * **Chores** * Diagnostic messages now include guidance to run the doctor task for remediation. * **Tests** * Updated tests and test helpers to reflect the new validation and sync behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
### Summary Adds missing changelog entries to the `[Unreleased]` section for PRs merged since `v16.6.0.rc.0`. Analyzed 19 commits on `origin/main` since the last tag, identified 1 missing user-visible PR (#3069), and skipped 10 non-user-visible PRs (docs, tests, internal refactors). **New entries added:** - **Added**: `[Pro] Configurable HTTP keep-alive timeout for node renderer connections` (PR #3069) - **Fixed**: `[Pro] Fixed SSR failures from stale persistent HTTP/2 connections` (PR #3069) **Entries already present** (added in prior changelog updates): PRs #2834, #2881, #2918, #2921, #2923, #2932, #3063, #3068, #3070. **Skipped** (not user-visible): #2893 (docs), #2916 (docs), #2922 (test fix), #2923 (test fix), #2925 (internal refactor), #3064 (docs), #3065 (docs), #3066 (docs), #3067 (docs), #3072 (docs). ### Pull Request checklist - [x] ~Add/update test to cover these changes~ - [x] ~Update documentation~ - [x] Update CHANGELOG file ### Other Information No code changes — CHANGELOG.md only. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk because this PR only changes documentation (`CHANGELOG.md`) and does not modify runtime code. > > **Overview** > Updates `CHANGELOG.md` *[Unreleased]* to include missing Pro release notes for PR `#3069`, documenting the new `renderer_http_keep_alive_timeout` config and the associated fix for SSR failures from stale persistent HTTP/2 connections to the node renderer. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8d1a480. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Interactive mode selection prompt for CLI tool when no explicit mode is specified * Configurable keep-alive timeout setting for Pro users (default 30 seconds) * **Bug Fixes** * Enhanced validation and error handling for invalid request payloads * Improved template literal handling in code generation * Better HTTP connection stability with enhanced diagnostic messaging <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>



Summary
check_npm_wildcardsandcheck_gem_wildcardsnow check bothreact-on-rails/react_on_railsandreact-on-rails-pro/react_on_rails_pro.bundle exec rake react_on_rails:doctor.sync_versionson version mismatches — error messages now includebundle exec rake react_on_rails:sync_versions WRITE=trueas a fix.FIX=truedoctor auto-runssync_versions— when doctor detects version issues and FIX mode is enabled, it automatically syncs package.json versions to match gem versions.sync_versionsnow handles range specs instead of skipping them — previously^16.5.0,~16.5.0,>=16.5.0were reported as "unsupported" and skipped. Now they're parsed, the range prefix is stripped, and the version is rewritten to the exact expected version.Addresses review feedback from #2893 (review)
Test plan
version_checker_spec.rb— 74 examples, 0 failuresversion_synchronizer_spec.rb— 20 examples, 0 failures (updated test for new range-handling behavior)system_checker_spec.rb— 81 examples, 0 failures (updated tests for error vs warning escalation)doctor_spec.rb— 152 examples, 0 failures��� Generated with Claude Code
Note
Medium Risk
Tightens version validation from warnings to errors and adds auto-fix behavior, which may cause previously passing CI/boot flows to fail until versions are pinned exactly. Changes are mostly in diagnostic tooling but affect startup/runtime error paths and developer workflows.
Overview
Makes version hygiene strict and actionable:
react_on_rails:doctornow treats non-exact gem/npm specs (^,~,>=, etc.) as errors (including Pro gems/packages) and can auto-runsync_versionswhenFIX=trueto rewrite range specs to exact expected versions.Improves remediation messaging across the stack by adding a shared
ReactOnRails::DOCTOR_RECOMMENDATIONto configuration/autobundling validations andVersionCheckerruntime crashes, and by updating mismatch errors to recommendbundle exec rake react_on_rails:sync_versions WRITE=true.sync_versionsis enhanced to parse and rewrite supported semver range prefixes (and npm alias variants) while refusing rewrites that would violate a declared>=lower bound; tests and a React 18/19-compatibleacthelper in the TanStack Router Pro test are updated accordingly.Reviewed by Cursor Bugbot for commit 223edd4. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Bug Fixes
Chores
Tests