Conversation
…that survives upgrades
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a narrow, well-tested compatibility fix that preserves existing behavior outside Homebrew keg installations while making service and child-process Node paths survive upgrades. It introduces no schema, security-sensitive, deployment, product-default, or static-analysis configuration changes. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe boot service now resolves Homebrew Node executables to stable ChangesHomebrew Node path durability
Estimated code review effort: 3 (Moderate) | ~20 minutes Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant Homebrew
participant BootService
participant LaunchAgent
participant ServiceLauncher
participant ManagedRuntime
Homebrew->>BootService: provide host.execPath
BootService->>Homebrew: resolve stable opt path
Homebrew-->>BootService: return existing durable nodePath
BootService->>LaunchAgent: write nodePath to service definition
LaunchAgent->>ServiceLauncher: start with absolute node path
ServiceLauncher->>ManagedRuntime: spawn using launcherNodePath()
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The service now survives Homebrew Node upgrades by preferring stable opt links while retaining safe fallbacks, and managed runtimes preserve a durable startup path. The covered fallback and upgrade scenarios show no current merge-blocking risk. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Note 🤖 Claude Fable 5.1 on behalf of Mnigos Closing: since #11510 the background service runs the self-contained |
t3 service install/service updaterecordprocess.execPathas the service's Node. Node reports the realpath, so a Homebrew install becomes/opt/homebrew/Cellar/node/<version>/bin/node, a path thatbrew upgrade nodedeletes. The running service survives on the old inode, but the next launchd or systemd start fails even thoughnodestill works through the Homebrew prefix. The launcher also spawns managed runtimes throughprocess.execPath, so a live handoff after a keg removal breaks the same way.Following the triage on #11054:
optlink (<prefix>/opt/<formula>/bin/node) wheneverexecPathsits in a Homebrew keg and that link exists. It stays absolute, follows the current keg across upgrades, and covers versioned formulae such asnode@22and Linuxbrew prefixes. Any otherexecPathis used as before. The same path goes into the unit'sPATHentry and into the runtime validation run.process.argv0) when that is absolute, and falls back toprocess.execPathotherwise.homebrewOwnershipFromCommandPathfrom provider maintenance already parses keg layouts, so the keg detection is shared.Verification
bootService.test.ts: keg to opt-link mapping (plain, versioned and Linuxbrew formulae, non-keg paths), and a macOS install that writes the keg path while the opt link is missing and the opt link once it exists, with noCellarleft in the plist.serviceLauncher.test.ts: absoluteargv0wins, a barenodefalls back toexecPath.vp test runon both files (43 tests), server typecheck and lint on the touched files are clean.Fixes #11054. Implemented with Claude Code (Claude Fable 5.1).
Summary by CodeRabbit