Skip to content

fix: address deferred review items from PR #2849#3093

Merged
justin808 merged 9 commits intomainfrom
jg/2880-dev-server-cra-fixes
Apr 13, 2026
Merged

fix: address deferred review items from PR #2849#3093
justin808 merged 9 commits intomainfrom
jg/2880-dev-server-cra-fixes

Conversation

@justin808
Copy link
Copy Markdown
Member

@justin808 justin808 commented Apr 9, 2026

Summary

  • Refactor server manager browser-open: remove non-idiomatic next in Thread.new, remove report_on_exception = false that suppressed genuine crashes, add WSL browser support (wslview/wsl-open), let explicit --open-browser bypass TTY guard, resolve marker path lazily, narrow rescued socket exceptions
  • Fix misleading Pro note that said Pro works "without a license"

Details

Server manager (server_manager.rb)

  • Thread.new refactor: Replaced next (non-idiomatic in Thread.new) with standard conditionals; removed report_on_exception = false so genuine crashes surface in development
  • WSL support: Detects WSL via WSL_DISTRO_NAME/WSLENV env vars and tries wslview/wsl-open before xdg-open
  • Platform diagnostic: Warns user when no browser launcher is found (with WSL-specific install hint)
  • Explicit vs auto-open TTY gating: --open-browser (deliberate user request) now bypasses TTY/CI guard; --open-browser-once (auto-open) still respects it
  • Lazy marker path: Replaced OPEN_BROWSER_ONCE_MARKER constant (resolved at class-load time) with open_browser_once_marker method (resolved at call time) to avoid wrong path when file is required before chdir into Rails root
  • Narrowed exception handling: http_get_localhost now rescues specific socket/connection errors instead of broad StandardError

Generator (base_generator.rb)

  • Updated home_page_pro_note_for_oss_app to not claim Pro works "without a license" (Pro raises on boot when unlicensed)

Closes #2880

Test plan

  • bundle exec rspec spec/react_on_rails/dev/server_manager_spec.rb — 93 examples, 0 failures
  • bundle exec rspec spec/react_on_rails/generators/install_generator_spec.rb:73 — passes
  • bundle exec rubocop on all changed files — no offenses
  • Verify WSL browser detection in WSL environment
  • Verify --open-browser works in non-TTY context (e.g., Docker)

🤖 Generated with Claude Code


Note

Medium Risk
Medium risk because it changes development process management and SSR webpack configuration, which can affect local workflows and server-bundle debugging/stack traces across platforms.

Overview
Stabilizes development ergonomics across environments. ServerManager browser auto-open was refactored to distinguish explicit --open-browser from guarded auto-open (--open-browser-once), add WSL launcher support (wslview/wsl-open), improve failure warnings, lazily resolve the once-marker path, and narrow localhost polling exception handling.

Avoids a webpack 5.106+ SSR regression. Server webpack configs switch away from devtool = 'eval' to cheap-module-source-map in development (and false in production) to prevent ESM default-export issues and improve SSR stack trace mapping.

Also updates generator messaging to remove the claim that Pro can be evaluated without a license, fixes generator chmod to use destination_root, adds .playwright-cli/ to .gitignore, and adds a Jest assertion ensuring scriptSanitizedVal keeps a stable function name for webpack compatibility.

Reviewed by Cursor Bugbot for commit bd84af3. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed server-side rendering (SSR) error stack traces to accurately map line numbers by updating source map configuration.
    • Improved browser auto-open functionality on WSL systems with better launcher detection and fallback handling.
  • Documentation

    • Updated Pro licensing guidance to clarify users must review upgrade documentation and obtain proper licenses before enabling Pro features.
  • Tests

    • Added test coverage for function naming stability and browser auto-open behavior across different environments.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 9, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Updates server webpack configuration to use source maps instead of eval-based devtools, refactors browser-opening logic to distinguish explicit versus automatic opens with WSL detection, improves marker file handling, and updates related tests and documentation strings.

Changes

Cohort / File(s) Summary
Pro Documentation
react_on_rails/lib/generators/react_on_rails/base_generator.rb
Updated Pro feature notice to direct users to review Pro docs and upgrade guide before enabling, removing the claim that Pro can be evaluated without a license.
Server-side Webpack Configuration
react_on_rails/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt, react_on_rails/spec/dummy/config/webpack/serverWebpackConfig.js, react_on_rails_pro/spec/dummy/config/webpack/serverWebpackConfig.js, react_on_rails_pro/spec/execjs-compatible-dummy/config/webpack/serverWebpackConfig.js
Changed serverWebpackConfig.devtool from 'eval' to 'cheap-module-source-map' to address webpack 5.106+ ESM reference errors and improve SSR error stack trace mapping.
Browser Launch Management
react_on_rails/lib/react_on_rails/dev/server_manager.rb
Refactored browser-opening logic: replaced frozen marker constant with lazy path computation, introduced explicit flag to distinguish manual (--open-browser) from automatic opens, updated TTY/CI gating to bypass checks for explicit requests, added WSL detection with wslview/wsl-open preference, refined marker file flow, and narrowed exception handling for localhost connection errors.
Server Manager Specifications
react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb
Added test coverage for explicit vs. auto-open flag behavior, CI gating differences, WSL detection and browser launcher selection across wslview, wsl-open, and xdg-open, and refactored marker setup to use computed path instead of constant.
Test Infrastructure
react_on_rails/spec/react_on_rails/support/generator_spec_helper.rb
Updated base_server_webpack_content fixture to reflect devtool change from 'eval' to 'cheap-module-source-map'.
Script Sanitization Test
packages/react-on-rails/tests/scriptSanitizedVal.test.js
Added test asserting scriptSanitizedVal function name remains stable under webpack 5.106.0.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Poem

🐰 Hop along, dear browsers bright,
No more eval's twisted plight!
WSL knows where you dwell,
Explicit opens break the spell—
Source maps guide our errors true,
The rail-stack hops ahead for you! 🚂✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: address deferred review items from PR #2849' is directly related to the changeset, which implements solutions for all deferred items from issue #2880 concerning dev server browser behavior, WSL detection, exception handling, and generator messaging.
Linked Issues check ✅ Passed The PR successfully addresses all key coding objectives from issue #2880: distinguishes explicit vs auto-open TTY gating [#2880], adds WSL detection and browser launcher support [#2880], narrows socket exception rescues [#2880], refactors marker path strategy [#2880], and updates Pro licensing messaging [PR summary].
Out of Scope Changes check ✅ Passed All changes are scoped to the deferred review items: server manager refactoring, browser detection, exception handling, generator messaging, and related test coverage. The create-react-on-rails-app ergonomics items (gpgsign, staging, git template sync, DB configurability) remain deferred as intended.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jg/2880-dev-server-cra-fixes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 9, 2026

Overall this is a well-structured cleanup. The motivations are sound (lazy marker resolution, narrowed exception handling, WSL support, explicit-vs-auto TTY distinction). A few items worth addressing before merge.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 9, 2026

Greptile Summary

This PR addresses deferred review items from #2849 by cleaning up the browser-open thread in server_manager.rb (removing non-idiomatic next/report_on_exception = false, adding WSL launcher detection, lazily resolving the once-marker path, narrowing socket exception rescues, and letting explicit --open-browser bypass TTY/CI gating) and fixing a misleading generator note that implied Pro works without a license.

Confidence Score: 5/5

Safe to merge — all findings are P2 style suggestions with no correctness impact.

All three changed files are logically correct. The thread refactor, WSL support, lazy marker path, and narrowed exception handling are all well-reasoned and pass the 93-example spec suite. The only gaps are a missing spec for the --open-browser explicit-bypass path and a subtle API-level ambiguity when both flags are true simultaneously — neither affects runtime correctness given CLI mutual exclusivity.

No files require special attention.

Vulnerabilities

No security concerns identified. The WSL detection reads only environment variables (WSL_DISTRO_NAME, WSLENV). Browser launchers are invoked via system(*command, url) with fixed, platform-resolved command arrays — no shell interpolation of user input. The explicit flag bypasses TTY gating only for deliberate user requests, not for environment-driven auto-opens.

Important Files Changed

Filename Overview
react_on_rails/lib/react_on_rails/dev/server_manager.rb Refactors browser-open thread logic: removes non-idiomatic next/report_on_exception = false, adds WSL launcher support, makes explicit bypass TTY gating for --open-browser, lazily resolves the once-marker path with Dir.pwd, and narrows socket exception rescues — all logically correct.
react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb Tests updated to match new signatures (adds explicit: false kwarg, stubs open_browser_once_marker method instead of stub_const); missing a spec for the --open-browser explicit-bypass path through schedule_browser_open_if_requested.
react_on_rails/lib/generators/react_on_rails/base_generator.rb Corrects misleading generator note that implied Pro works without a license; replacement text accurately directs users to docs and a license before enabling Pro.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[schedule_browser_open_if_requested] --> B{open_browser or open_browser_once?}
    B -- No --> Z[return]
    B -- Yes --> C["explicit = open_browser && !open_browser_once"]
    C --> D["schedule_browser_open(port, route, once, explicit)"]
    D --> E{"browser_auto_open_allowed?(explicit)"}
    E -- "explicit=true" --> G[Skip CI/TTY check → allowed]
    E -- "explicit=false" --> F{"!CI && stdin.tty? && stdout.tty?"}
    F -- No --> Z
    F -- Yes --> G
    G --> H[Thread.new]
    H --> I{wait_for_app_route?}
    I -- No/timeout --> Z
    I -- Yes --> J[prepare_browser_open_once_marker]
    J -- :already_opened --> Z
    J -- :claimed/:not_requested --> K[open_browser url]
    K -- success --> Z
    K -- fail --> L[clear marker if claimed]
    L --> M[warn user with URL]
Loading

Comments Outside Diff (1)

  1. react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb, line 79-84 (link)

    P2 Missing spec for explicit --open-browser path

    The spec at line 79 only verifies the open_browser_once: true case (which yields explicit: false). There's no corresponding test checking that open_browser: true, open_browser_once: false propagates explicit: true to schedule_browser_open, nor a unit test confirming that browser_auto_open_allowed?(explicit: true) returns true even when CI is set or the streams are non-TTY. The explicit TTY-bypass is the core new behavior in this PR and would benefit from dedicated coverage.

    it "schedules an explicit browser open (bypasses TTY guard) when --open-browser is passed" do
      expect(described_class).to receive(:schedule_browser_open)
        .with(3000, route: "/", once: false, explicit: true)
      expect(ReactOnRails::Dev::ProcessManager).to receive(:run_with_process_manager).with("Procfile.dev")
    
      described_class.start(:development, nil, route: "/", open_browser: true)
    end

Reviews (1): Last reviewed commit: "fix: address deferred review items from ..." | Re-trigger Greptile

Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2e4efd05f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb Outdated
Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 10, 2026

Review

Overall this is a solid cleanup of the server manager browser-open code. The changes are well-motivated, the refactoring improves correctness (removing report_on_exception = false, lazy marker path, narrowed exception handling), and the WSL support fills a real gap. A few things to address:

Must fix

  • Errno::EPIPE missing from LOCALHOST_CONNECT_ERRORS — a server that accepts the TCP connection but drops it mid-request will raise EPIPE on the write side; this is still a "not ready" condition and should be retried silently. See inline comment.

Should add

  • Missing test: explicit: true path — the core new behavior (--open-browser bypassing TTY/CI gating) has no spec coverage. Neither schedule_browser_open_if_requested with open_browser: true nor browser_auto_open_allowed?(explicit: true) in a CI/non-tty context is tested. See inline comment.

  • Missing WSL testswsl?, linux_browser_command fallback ordering, and the WSL diagnostic hint in open_browser are all new code with no specs. See inline comment.

Minor

  • WSLENV as a WSL signalWSL_DISTRO_NAME is the authoritative indicator; WSLENV is also set by Windows-side tooling and could produce a false positive in Docker images that inherit a Windows host env. Low risk, but worth a comment in wsl?. See inline comment.

Looks good

  • Thread refactor (removing next, replacing report_on_exception = false with a rescue that surfaces a warning) is strictly better.
  • open_browser_once_marker as a method instead of a constant correctly fixes the load-time path resolution bug.
  • devtool change to cheap-module-source-map is the right fix for the webpack 5.106+ ESM regression and the comment explains the reason clearly.
  • Generator copy fix is accurate.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb (1)

1083-1086: This no longer proves the Dir.chdir regression fix.

Stubbing open_browser_once_marker keeps the spec aligned with the new implementation, but it also stops testing the original failure mode. Please add one regression example that changes the working directory after load and asserts the marker path resolves from the new cwd.

Also applies to: 1123-1123

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb` around lines
1083 - 1086, The current spec stubs open_browser_once_marker which masks the
Dir.chdir regression; add a regression example that does not stub
open_browser_once_marker but instead calls Dir.chdir to a new temporary
directory after loading the class and then asserts
described_class.open_browser_once_marker (or the produced marker_path) is
resolved relative to the new working directory (i.e., create a temp dir,
Dir.chdir into it, call the code that returns the marker path via
described_class.open_browser_once_marker, and expect the returned path to
start_with or equal File.join(Dir.pwd, "browser_opened_once")); apply the same
change to the duplicate example area referenced around the second occurrence.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb`:
- Around line 1083-1086: The current spec stubs open_browser_once_marker which
masks the Dir.chdir regression; add a regression example that does not stub
open_browser_once_marker but instead calls Dir.chdir to a new temporary
directory after loading the class and then asserts
described_class.open_browser_once_marker (or the produced marker_path) is
resolved relative to the new working directory (i.e., create a temp dir,
Dir.chdir into it, call the code that returns the marker path via
described_class.open_browser_once_marker, and expect the returned path to
start_with or equal File.join(Dir.pwd, "browser_opened_once")); apply the same
change to the duplicate example area referenced around the second occurrence.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cf38d9e4-1460-4265-af3e-63a8736be96d

📥 Commits

Reviewing files that changed from the base of the PR and between 16ac897 and 02fb18d.

📒 Files selected for processing (8)
  • react_on_rails/lib/generators/react_on_rails/base_generator.rb
  • react_on_rails/lib/generators/react_on_rails/templates/base/base/config/webpack/serverWebpackConfig.js.tt
  • react_on_rails/lib/react_on_rails/dev/server_manager.rb
  • react_on_rails/spec/dummy/config/webpack/serverWebpackConfig.js
  • react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb
  • react_on_rails/spec/react_on_rails/support/generator_spec_helper.rb
  • react_on_rails_pro/spec/dummy/config/webpack/serverWebpackConfig.js
  • react_on_rails_pro/spec/execjs-compatible-dummy/config/webpack/serverWebpackConfig.js

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 12, 2026

size-limit report 📦

Path Size
react-on-rails/client bundled (gzip) 62.63 KB (-0.12% 🔽)
react-on-rails/client bundled (gzip) (time) 62.63 KB (-0.12% 🔽)
react-on-rails/client bundled (brotli) 53.78 KB (+0.02% 🔺)
react-on-rails/client bundled (brotli) (time) 53.78 KB (+0.02% 🔺)
react-on-rails-pro/client bundled (gzip) 63.57 KB (-0.14% 🔽)
react-on-rails-pro/client bundled (gzip) (time) 63.57 KB (-0.14% 🔽)
react-on-rails-pro/client bundled (brotli) 54.6 KB (-0.09% 🔽)
react-on-rails-pro/client bundled (brotli) (time) 54.6 KB (-0.09% 🔽)
registerServerComponent/client bundled (gzip) 127.39 KB (-0.06% 🔽)
registerServerComponent/client bundled (gzip) (time) 127.39 KB (-0.06% 🔽)
registerServerComponent/client bundled (brotli) 61.59 KB (+0.05% 🔺)
registerServerComponent/client bundled (brotli) (time) 61.59 KB (+0.05% 🔺)
wrapServerComponentRenderer/client bundled (gzip) 122.02 KB (0%)
wrapServerComponentRenderer/client bundled (gzip) (time) 122.02 KB (0%)
wrapServerComponentRenderer/client bundled (brotli) 56.73 KB (0%)
wrapServerComponentRenderer/client bundled (brotli) (time) 56.73 KB (0%)

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 12, 2026

Overall this is a solid set of fixes. The webpack 5.106+ regression fix, WSL browser support, narrowed exception handling, and generator copy update are all well-reasoned. See inline comments for specifics.

Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb Outdated
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb Fixed
Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb Fixed
@justin808
Copy link
Copy Markdown
Member Author

Review feedback addressed in 1f04d40

Fixed (5 items):

  1. Added missing exceptions to LOCALHOST_CONNECT_ERRORSEOFError, Errno::EPIPE, and Errno::EAFNOSUPPORT are now included. These transient boot-time errors were previously caught by the broad rescue StandardError; the narrowed list omitted them, which could crash the polling thread and permanently prevent browser auto-open.

  2. Fixed double warning when no browser launcher found — Removed the new warning from open_browser and consolidated into the caller's single message, which now includes both the URL and the WSL-specific hint.

  3. Added spec coverage for explicit: true path — Tests verify that --open-browser propagates explicit: true through schedule_browser_open_if_requested, and that browser_auto_open_allowed?(explicit: true) returns true even when CI is set.

  4. Added WSL detection specs — Coverage for wsl? (WSL_DISTRO_NAME, WSLENV, neither) and linux_browser_command fallback ordering (wslview → wsl-open → xdg-open → nil).

  5. Added comment clarifying WSLENV — Documented that WSL_DISTRO_NAME is the authoritative WSL indicator; WSLENV is a weaker fallback.

Declined with rationale (4 items):

  • Both-flags-true guard (2 comments) — CLI enforces mutual exclusivity
  • Errno::EADDRNOTAVAIL removal — keeping it is defensive and harmless
  • Dir.pwd mutability concern — extremely unlikely in dev-server context

All 12 review threads resolved. 104 specs passing, RuboCop clean.

Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
Comment thread react_on_rails/lib/react_on_rails/dev/server_manager.rb
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 12, 2026

Review: fix: address deferred review items from PR #2849

Overall this is a solid, well-reasoned set of fixes. The refactors are well-motivated and the test additions are thorough. A few targeted notes below.

What works well

  • report_on_exception removal + rescue StandardError: Correct trade. The old report_on_exception = false suppressed all crashes; the new rescue surfaces them as warn messages without crashing the parent process. The Ruby-idiomatic if/else replaces next cleanly.
  • Lazy open_browser_once_marker: Good fix for the load-time vs. run-time Dir.pwd race. The allow(described_class).to receive(:open_browser_once_marker) stub in specs is cleaner than stub_const.
  • LOCALHOST_CONNECT_ERRORS constant: Narrowing from StandardError to a named list is the right call. The inclusion of Errno::EAFNOSUPPORT, Errno::EPIPE, and EOFError covers the realistic startup-polling failure modes.
  • scriptSanitizedVal named function: Adding a function.name assertion is a good regression guard for the webpack 5.106+ compatibility fix.
  • cheap-module-source-map over eval: Correct response to the webpack regression. The comment in the template/dummy configs is informative.

Issues (inline comments posted)

  1. explicit flag when both --open-browser and --open-browser-once are passed (server_manager.rb:864): explicit = open_browser && !open_browser_oncefalse, so the TTY guard applies and the marker is written. Behaviour is defensible but undocumented and untested.

  2. Misleading WSL install hint via WSLENV false positive (server_manager.rb:898): WSLENV can be present in a Docker container that inherited the Windows host env (Docker-in-WSL). If wslview/wsl-open don't exist there, the hint says "install wslu (for wslview) or wsl-open" — wrong advice. Using ENV.key?("WSL_DISTRO_NAME") (kernel-set, not inheritable) would be more precise.

  3. No install hint for non-WSL Linux without xdg-open (server_manager.rb:989): linux_browser_command returns nil silently; the user only sees the generic "Could not open browser automatically." message with no guidance on what to install (xdg-utils).

Minor / non-blocking

  • browser_auto_open_allowed? TTY test coverage: The two new specs only exercise the CI env var path. The $stdin.tty?/$stdout.tty? branches can't be easily tested in RSpec, which is fine — just worth a comment in the spec explaining why they're omitted.
  • open_browser_once_marker called multiple times in a single open sequence: prepare_browser_open_once_marker and clear_browser_open_once_marker_if_claimed each call Dir.pwd independently. If something changes Dir.pwd between calls (edge case), the paths diverge. A local variable capturing the result once at the top of schedule_browser_open would make this airtight, but it's theoretical.

@justin808
Copy link
Copy Markdown
Member Author

Review feedback addressed in 73b9415

Fixed (2 items):

  1. Uninitialized saved variable in WSL detection spec — Added saved = {} initialization before ENV.to_h.slice so the ensure block always has a valid hash, even if setup raises.

  2. cheap-module-source-map set unconditionally — Devtool is now conditional: false in production (no .map files), cheap-module-source-map in development (SSR error traces). Both avoid the webpack 5.106+ eval regression. Applied consistently across the template, all spec dummy configs, gen-examples, and the generator spec helper.

Declined with rationale (6 items):

  1. Duplicate of TODO for first version #1 (second saved variable comment)
  2. Test for open_browser: true, open_browser_once: true — flags are documented as mutually exclusive; codifying unsupported combos isn't useful
  3. WSL hint uses wsl? instead of strict WSL_DISTRO_NAME — intentional design choice; false positive consequence is benign since the hint lists all relevant tools
  4. Dir.chdir between marker ops — extremely theoretical; marker mechanism is best-effort by design
  5. Test fails on Linux CI (cursor[bot]) — incorrect finding: test already uses regex matcher with .* wildcard
  6. Duplicate of Add Unit tests #5

All 8 review threads resolved.

Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb Fixed
Comment thread react_on_rails/spec/react_on_rails/dev/server_manager_spec.rb Fixed
schedule_browser_open(procfile_port(procfile), route: route, once: open_browser_once)
# --open-browser is an explicit user request and bypasses TTY gating.
# --open-browser-once is an auto-open and respects TTY/CI guards.
explicit = open_browser && !open_browser_once
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When both open_browser: true and open_browser_once: true are supplied simultaneously (unusual, but possible through layered CLI option parsing), explicit evaluates to false and the TTY/CI guard is silently applied — the --open-browser-once semantics win. This is probably the right conservative choice, but the comment above only describes the individual flags, not this combined case.

Consider a one-line note or an early guard:

Suggested change
explicit = open_browser && !open_browser_once
# --open-browser is an explicit user request and bypasses TTY gating.
# --open-browser-once is an auto-open and respects TTY/CI guards.
# If both are passed, --open-browser-once semantics win (explicit = false).
explicit = open_browser && !open_browser_once

# WSL_DISTRO_NAME is the authoritative indicator (set by the WSL kernel).
# WSLENV is a weaker signal — it can appear in non-WSL contexts (e.g. Docker
# images that inherit a Windows host env) but is included as a fallback.
ENV.key?("WSL_DISTRO_NAME") || ENV.key?("WSLENV")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WSLENV false-positive is well-explained in the comment. One downstream consequence worth noting: if a Docker container inherits WSLENV from a Windows host (and --open-browser is used explicitly so the TTY guard is bypassed), wsl? returns true, wslview/wsl-open won't be found, and control falls through to xdg-open. If that also fails, the hint message reads "On WSL, install wslu…" — which is misleading for someone in Docker.

One option is to differentiate the hint based on WSL_DISTRO_NAME (authoritative) vs. the fallback WSLENV:

def authoritative_wsl?
  ENV.key?("WSL_DISTRO_NAME")
end

…and use that for the hint while keeping the broader wsl? for the launcher-preference order. Low priority given the narrow trigger conditions, but flagging for awareness.

# which checks both NODE_ENV and RAILS_ENV. Checking NODE_ENV here surfaces
# misconfigurations (e.g. NODE_ENV=production + RAILS_ENV=development) at Rails boot
# time rather than waiting for the Node renderer to reject the request.
runtime_envs = [ENV.fetch("RAILS_ENV", nil), ENV.fetch("NODE_ENV", nil)].compact_blank.map(&:downcase)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good use of compact_blank over compact — it correctly treats RAILS_ENV="" as unset rather than passing an empty string through to downcase and matching nothing. One note: the allowed_envs local freeze is harmless but unnecessary (the %w[] literal creates a new array every call; freezing it doesn't gain anything here since it's not stored). Minor style nit, not worth changing on its own.

# time rather than waiting for the Node renderer to reject the request.
runtime_envs = [ENV.fetch("RAILS_ENV", nil), ENV.fetch("NODE_ENV", nil)].compact_blank.map(&:downcase)
allowed_envs = %w[development test].freeze
return if runtime_envs.any? && runtime_envs.all? { |e| allowed_envs.include?(e) }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition runtime_envs.any? && runtime_envs.all? { ... } is correct: an empty array (both envs unset) falls through to raise, matching the "fail-closed" spec. One edge case worth a spec: RAILS_ENV=test, NODE_ENV=staging — one allowed, one not. all? returns false → raises. That's the right call, but it might surprise someone who expected RAILS_ENV=test to be enough. The new test matrix in the error message covers this with the "(mixed envs)" row, so documentation is already there.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 12, 2026

Review posted via inline comments. See discussion threads on server_manager.rb lines 864 and 1004, and configuration.rb lines 277 and 279 for specific observations. Overall the PR is well-structured with no blocking issues.

justin808 and others added 8 commits April 12, 2026 13:34
Server manager browser-open improvements:
- Refactor Thread.new block: remove non-idiomatic `next`, remove
  `report_on_exception = false` that suppressed genuine crashes
- Add WSL browser support: detect WSL_DISTRO_NAME/WSLENV and try
  wslview/wsl-open before falling back to xdg-open
- Warn user when no browser launcher is found (with WSL-specific hint)
- Let explicit --open-browser bypass TTY/CI guard since the developer
  deliberately requested it; auto-opens still respect the guard
- Resolve marker-file path lazily at call time instead of at
  constant-definition time to avoid wrong path when required before
  chdir into Rails root
- Narrow rescued exceptions in http_get_localhost from broad
  StandardError to specific socket/connection error classes

Generator fix:
- Update misleading Pro note that said Pro works "without a license"
  (Pro raises on boot without one)

Closes #2880

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
…ck 5.106.0 regression

webpack 5.106.0 introduced a regression where the 'eval' devtool causes
"ReferenceError: __WEBPACK_DEFAULT_EXPORT__ is not defined" when bundling
ESM modules with default exports for server-side rendering via ExecJS.

Switch from 'eval' to 'cheap-module-source-map' which provides original
line numbers in SSR error traces without using eval(). This affects the
generator template, spec dummy apps, and the generator spec helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Add EOFError, Errno::EPIPE, and Errno::EAFNOSUPPORT to
  LOCALHOST_CONNECT_ERRORS to prevent polling thread crash on
  transient boot-time errors (previously caught by broad
  rescue StandardError)
- Fix double warning when no browser launcher is found by
  consolidating messages into the caller with WSL hint
- Add comment clarifying WSLENV is a weaker WSL signal than
  WSL_DISTRO_NAME
- Add spec coverage for explicit: true path (--open-browser
  bypasses TTY/CI gating)
- Add spec coverage for WSL detection and linux_browser_command
  fallback ordering

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Use ENV.key?("WSL_DISTRO_NAME") instead of wsl? for WSL install hint
  to avoid false-positive advice in Docker-in-WSL containers where
  WSLENV is inherited from the Windows host
- Add xdg-open to the WSL hint since it works on WSLg environments
- Add install guidance for non-WSL Linux when no browser launcher found

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Use wsl? helper for WSL hint instead of raw ENV check, so WSLENV-only
  environments also see the WSL install guidance
- Consolidate duplicate browser warnings: remove early warning from
  linux_browser_command and enrich the single diagnostic in
  schedule_browser_open with platform-specific install hints
- Fix test ENV["CI"] cleanup to restore original value using around block
  instead of unconditionally deleting (matches existing WSL test pattern)

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Initialize `saved = {}` before ENV.to_h.slice in WSL detection spec
  to prevent NameError if the ensure block runs before assignment
- Scope cheap-module-source-map devtool to development only; disable
  devtool in production to avoid generating .map files while still
  avoiding the webpack 5.106+ eval regression in all environments
- Use regex matcher in browser-open warning spec to handle
  platform-specific hint text on Linux CI

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@justin808 justin808 force-pushed the jg/2880-dev-server-cra-fixes branch from 73b9415 to 2929a8b Compare April 13, 2026 02:58
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 13, 2026

Code Review

Overall this is a clean, well-structured PR. The changes are well-scoped, the test coverage is solid, and the reasoning in the PR description and inline comments is clear. A few observations worth addressing:

Substantive items

explicit flag when both --open-browser and --open-browser-once are set

In schedule_browser_open_if_requested, explicit = open_browser && !open_browser_once, so passing both flags at once produces explicit: false — the TTY/CI guard is respected even though the user explicitly passed --open-browser. The behavior is arguably correct (once-semantics wins), but it silently overrides an explicit user request without any warning or documentation. If both can be set from bin/dev, a small comment or guard would clarify the intent.

open_browser_once_marker called twice inside the same thread

The lazy Dir.pwd approach correctly solves the class-load-time path issue. However, prepare_browser_open_once_marker and clear_browser_open_once_marker_if_claimed each call open_browser_once_marker separately, evaluating Dir.pwd twice within the same thread execution. If something changes Dir.pwd between those two calls (unlikely in a running Rails app, but possible in tests), the delete silently no-ops via the Errno::ENOENT rescue. Consider capturing the path once at the start of the Thread.new block and threading it through.

wsl? with WSLENV false-positive

The code comment already calls this out. Worth noting: the false-positive path (Docker-on-Windows with WSLENV set) is safe at runtime because WSL launchers won't be found and the code falls back to xdg-open. No code change needed, just flagging it for awareness.

Minor items

  • spec/react_on_rails/dev/server_manager_spec.rb line 326: saved = {} at class-evaluation time inside the describe block is redundant — the around block immediately re-initialises it.
  • The browser_auto_open_allowed? tests cover CI gating but not $stdin.tty? / $stdout.tty? — hard to unit-test, so this is understandable.
  • The webpack devtool change and the generator destination_root fix are both clean and the test snapshot update is correctly kept in sync.

schedule_browser_open(procfile_port(procfile), route: route, once: open_browser_once)
# --open-browser is an explicit user request and bypasses TTY gating.
# --open-browser-once is an auto-open and respects TTY/CI guards.
explicit = open_browser && !open_browser_once
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When both --open-browser and --open-browser-once are passed together, explicit becomes false (true && !true), so the TTY/CI guard is respected even though the user explicitly passed --open-browser. The once-semantics silently wins. This is likely the intended behaviour, but a comment here would make it explicit:

Suggested change
explicit = open_browser && !open_browser_once
explicit = open_browser && !open_browser_once
# Note: when both flags are set, once-semantics takes precedence and the
# TTY/CI guard is respected (explicit is false). This is intentional.

Alternatively, consider emitting a warning if both flags are supplied so the user knows which behaviour they get.


# Resolved lazily at call time so the path is correct even when this file
# is required before the process has chdir'd into the Rails app root.
def open_browser_once_marker
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dir.pwd is evaluated freshly on each call, which means prepare_browser_open_once_marker and clear_browser_open_once_marker_if_claimed may resolve to different absolute paths if Dir.pwd is mutated between calls (unlikely in production, but possible in concurrent test runs). The Errno::ENOENT rescue makes this safe, but it silently leaves the marker file behind in that edge case.

Consider capturing the path once before the thread enters the wait loop and passing it through:

# In schedule_browser_open, before Thread.new:
marker_path = open_browser_once_marker
Thread.new do
  # … use marker_path directly instead of calling open_browser_once_marker
end

This keeps the lazy-resolution benefit (path is correct at spawn time, not at class-load time) while avoiding the double evaluation.

end

describe "WSL detection" do
saved = {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class-level saved = {} is never actually read — the around block immediately re-initializes it on line 329. It can be dropped:

Suggested change
saved = {}
describe "WSL detection" do

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
schedule_browser_open(procfile_port(procfile), route: route, once: open_browser_once)
# --open-browser is an explicit user request and bypasses TTY gating.
# --open-browser-once is an auto-open and respects TTY/CI guards.
explicit = open_browser && !open_browser_once
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edge case: when both open_browser: true and open_browser_once: true are passed together, explicit evaluates to false and TTY/CI guards apply — even though the user explicitly requested a browser open with --open-browser. If these flags are intended to be mutually exclusive at the CLI level this is fine, but it's worth adding a guard or a comment clarifying that assumption.

Suggested change
explicit = open_browser && !open_browser_once
explicit = open_browser && !open_browser_once
# Note: passing both --open-browser and --open-browser-once simultaneously
# is not a supported combination; --open-browser-once takes precedence.

# WSL_DISTRO_NAME is the authoritative indicator (set by the WSL kernel).
# WSLENV is a weaker signal — it can appear in non-WSL contexts (e.g. Docker
# images that inherit a Windows host env) but is included as a fallback.
ENV.key?("WSL_DISTRO_NAME") || ENV.key?("WSLENV")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here acknowledges the risk correctly, but there's a downstream UX consequence worth noting: when WSLENV is set in a non-WSL Linux context (e.g. a Docker container inheriting a Windows host env) and no browser launcher is found, the user receives the WSL-specific hint ("On WSL, install wslu…") rather than the Linux hint ("Install xdg-utils…"). This is misleading.

Consider only relying on WSL_DISTRO_NAME (the authoritative kernel-set indicator) and dropping WSLENV as a fallback, or at least checking that wslview/wsl-open are actually available before treating the environment as WSL in the error path.

end

describe "WSL detection" do
saved = {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The saved = {} at the describe block level is dead code — it's immediately overwritten by the saved = {} assignment at the start of the around block (Ruby blocks are closures, so the outer variable is mutated). The describe-level initialiser can be removed.

Suggested change
saved = {}
describe "WSL detection" do

files = Dir.children(template_bin_path).reject { |filename| filename == "dev" }
files << "dev" unless preserve_existing_bin_dev?
files.map { |filename| "bin/#{filename}" }
files.map { |filename| File.join(destination_root, "bin/#{filename}") }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor style nit: prefer passing path components as separate arguments to File.join so the intent is clearer and interpolation isn't needed.

Suggested change
files.map { |filename| File.join(destination_root, "bin/#{filename}") }
files.map { |filename| File.join(destination_root, "bin", filename) }

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 13, 2026

Review summary

Overall this is a solid, well-motivated set of changes. The refactoring is clear, the new tests are thorough, and the webpack devtool fix addresses a real regression. A few items worth addressing:

Medium

explicit flag logic (server_manager.rb:864) — When both open_browser and open_browser_once are true, explicit becomes false and TTY/CI guards apply even though the user explicitly requested --open-browser. This is probably unreachable in practice (the flags are mutually exclusive at the CLI), but it's a silent edge case. A comment or a guard would make the intent unambiguous. See inline.

Low

WSLENV false positive → misleading error hint (server_manager.rb:1004) — The comment already acknowledges this, but the downstream consequence is concrete: a Docker container that inherits WSLENV from a Windows host will get "On WSL, install wslu…" instead of "Install xdg-utils…" when no browser launcher is found. Dropping WSLENV as a fallback, or deferring the WSL-specific hint until at least one WSL launcher was attempted, would avoid the misdirection. See inline.

saved = {} dead code in spec (server_manager_spec.rb:326) — The describe-level saved = {} is immediately overwritten inside the around block (Ruby closures mutate the outer binding). It can be removed. See inline.

File.join style nit (install_generator.rb:448) — Minor: prefer File.join(destination_root, "bin", filename) over string interpolation. See inline.

Positive notes

  • Removing report_on_exception = false is a great catch — suppressing thread exceptions in development makes real bugs invisible.
  • The lazy open_browser_once_marker method is the right fix for the class-load-time Dir.pwd issue.
  • Narrowing http_get_localhost rescue to LOCALHOST_CONNECT_ERRORS instead of StandardError is a good hardening step.
  • The webpack cheap-module-source-map change is well-justified and the test guard (scriptSanitizedVal.name) is a clever way to pin the behaviour that webpack 5.106+ broke.
  • The bin_scripts_to_chmod destination_root fix is correct and the added comment explains the why clearly.

@justin808 justin808 merged commit 119f723 into main Apr 13, 2026
42 checks passed
@justin808 justin808 deleted the jg/2880-dev-server-cra-fixes branch April 13, 2026 03:27
justin808 added a commit that referenced this pull request Apr 18, 2026
…ages

* origin/main:
  Fix initial page startup race for late-loading client bundles (#3151)
  chore: apply prettier formatting to tracked docs files (#3153)
  docs: comprehensive RSC API documentation and registration consolidation (#3140)
  Split rspec-package-tests into parallel generator/unit shards (#3134)
  fix: add concurrency groups to long-running CI workflows (#3133)
  refactor: add RenderRequest, JsCodeBuilder, and RenderingStrategy abstractions (#3094)
  fix: address deferred review items from PR #2849 (#3093)
  Add complimentary OSS license policy for React on Rails Pro (#3123)
  fix: centralize CI docs-only detection and add CLI flag validation (#3091)
  refactor: replace stub-throw + Object.assign with capability-based composition (#3096)
  Enhance address-review with parallel fixes, self-review, and Greptile verification (#3121)
  fix: Doctor no longer fails custom projects for missing bin/dev (#3117)
  fix: cap webpack <5.106.0 to prevent ExecJS SSR breakage (#3095)
  Add Rspack + RSC compatibility tests and documentation (#1828) (#3120)
  Add error scenarios hub and test pages (#2497)
  docs: document polyfill requirements for web-targeted server bundles (#3092)
  docs: RSC integration pitfalls from tutorial app (#3087)
  docs: fix render function/helper API documentation (#3088)
  Doctor: accept TS/TSX server bundle suffixes (#3111)
  feat: add CI guard requiring sidebar updates when adding docs (#3089)
justin808 added a commit that referenced this pull request Apr 18, 2026
## Summary
- Refactor server manager browser-open: remove non-idiomatic `next` in
Thread.new, remove `report_on_exception = false` that suppressed genuine
crashes, add WSL browser support (wslview/wsl-open), let explicit
`--open-browser` bypass TTY guard, resolve marker path lazily, narrow
rescued socket exceptions
- Fix misleading Pro note that said Pro works "without a license"

## Details

### Server manager (`server_manager.rb`)
- **Thread.new refactor**: Replaced `next` (non-idiomatic in Thread.new)
with standard conditionals; removed `report_on_exception = false` so
genuine crashes surface in development
- **WSL support**: Detects WSL via `WSL_DISTRO_NAME`/`WSLENV` env vars
and tries `wslview`/`wsl-open` before `xdg-open`
- **Platform diagnostic**: Warns user when no browser launcher is found
(with WSL-specific install hint)
- **Explicit vs auto-open TTY gating**: `--open-browser` (deliberate
user request) now bypasses TTY/CI guard; `--open-browser-once`
(auto-open) still respects it
- **Lazy marker path**: Replaced `OPEN_BROWSER_ONCE_MARKER` constant
(resolved at class-load time) with `open_browser_once_marker` method
(resolved at call time) to avoid wrong path when file is required before
chdir into Rails root
- **Narrowed exception handling**: `http_get_localhost` now rescues
specific socket/connection errors instead of broad `StandardError`

### Generator (`base_generator.rb`)
- Updated `home_page_pro_note_for_oss_app` to not claim Pro works
"without a license" (Pro raises on boot when unlicensed)

Closes #2880

## Test plan
- [x] `bundle exec rspec spec/react_on_rails/dev/server_manager_spec.rb`
— 93 examples, 0 failures
- [x] `bundle exec rspec
spec/react_on_rails/generators/install_generator_spec.rb:73` — passes
- [x] `bundle exec rubocop` on all changed files — no offenses
- [ ] Verify WSL browser detection in WSL environment
- [ ] Verify `--open-browser` works in non-TTY context (e.g., Docker)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Medium risk because it changes development process management and SSR
webpack configuration, which can affect local workflows and
server-bundle debugging/stack traces across platforms.
> 
> **Overview**
> **Stabilizes development ergonomics across environments.**
`ServerManager` browser auto-open was refactored to distinguish explicit
`--open-browser` from guarded auto-open (`--open-browser-once`), add WSL
launcher support (`wslview`/`wsl-open`), improve failure warnings,
lazily resolve the once-marker path, and narrow localhost polling
exception handling.
> 
> **Avoids a webpack 5.106+ SSR regression.** Server webpack configs
switch away from `devtool = 'eval'` to `cheap-module-source-map` in
development (and `false` in production) to prevent ESM default-export
issues and improve SSR stack trace mapping.
> 
> Also updates generator messaging to remove the claim that Pro can be
evaluated without a license, fixes generator `chmod` to use
`destination_root`, adds `.playwright-cli/` to `.gitignore`, and adds a
Jest assertion ensuring `scriptSanitizedVal` keeps a stable function
name for webpack compatibility.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
bd84af3. 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

* **Bug Fixes**
* Fixed server-side rendering (SSR) error stack traces to accurately map
line numbers by updating source map configuration.
* Improved browser auto-open functionality on WSL systems with better
launcher detection and fallback handling.

* **Documentation**
* Updated Pro licensing guidance to clarify users must review upgrade
documentation and obtain proper licenses before enabling Pro features.

* **Tests**
* Added test coverage for function naming stability and browser
auto-open behavior across different environments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow-up: Deferred review items from PR #2849

1 participant