Skip to content

fix(merge): portable Node-based merge-driver prepare hook (cross-shell Windows/POSIX)#7

Merged
unbraind merged 2 commits into
mainfrom
chore/portable-prepare-merge-driver
Jul 22, 2026
Merged

fix(merge): portable Node-based merge-driver prepare hook (cross-shell Windows/POSIX)#7
unbraind merged 2 commits into
mainfrom
chore/portable-prepare-merge-driver

Conversation

@unbraind

@unbraind unbraind commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Portable Node-based merge-driver prepare hook (cross-shell)

Replaces the guarded POSIX prepare hook with a Node script so npm install /
npm ci wire pm-cli's field-aware Git merge drivers identically on POSIX shells
and Windows cmd.exe
. Fleet-standard rollout (all 18 repos).

Why

On the xydx merge-driver harmonization wave two bots independently flagged the
guarded POSIX form if command -v pm >/dev/null 2>&1; then pm merge install; fi:
Greptile (P1) — Windows cmd.exe (npm's default script shell) cannot parse
if/fi, so npm install / npm ci fails at prepare on native Windows even
when pm is present
; CodeRabbit — recommended a portable Node-based check.
The bare form conversely breaks POSIX --omit=dev. Only a Node guard is correct
on all platforms (npm invokes node <file> the same way on both shells).

Change

  • New scripts/prepare-merge-driver.mjs — resolves pm presence by scanning
    PATH (PATHEXT-aware on Windows), never executing pm: absent → silent skip
    (production / --omit=dev), present → pm merge install fail-loud (a broken
    or incompatible CLI surfaces a non-zero exit, not a silent skip).
  • package.jsonpreparenode scripts/prepare-merge-driver.mjs.
  • README.md — merge-driver note harmonized to the portable Node form.

Script intentionally not in package.json files: prepare only runs from a full
checkout (local-dev / git-install / publish), never for npm-registry consumers.

Validation (real-data)

present + tracker → exit 0 (drivers wired); absent (PATH stripped) → exit 0
(skip); present + broken pm → exit 1 (fail-loud); sh -c → identical. The script
is byte-identical to the canary pm-beads#40,
which passed full CI + CodeRabbit + Sourcery review.

Tracking

  • No per-repo merge-driver tracker item (adoption tracked earlier); this PR references the fleet rollout only.
  • Companion rollout: pm-cli-website-5cx1 (fleet-wide 18-repo portable-hook rollout)

🤖 Generated with Claude Code


Summary by cubic

Replaced the POSIX-only prepare hook with a portable node script so npm install/npm ci consistently wire pm-cli merge drivers on POSIX and Windows cmd.exe. Hardened PATH detection (PATHEXT-aware, handles quoted entries and empty POSIX components, ignores non-executable files) and cleanly skips on production/--omit=dev; satisfies Linear pm-cli-website-5cx1.

  • Bug Fixes
    • Added scripts/prepare-merge-driver.mjs: scans PATH (PATHEXT-aware) without executing pm; treats empty POSIX entries as . and strips quotes on Windows; rejects dirs/non-exec files; runs pm merge install if found (fail-loud), otherwise no-op.
    • Updated package.json prepare to node scripts/prepare-merge-driver.mjs and aligned README notes.

Written for commit 614e0b2. Summary will update on new commits.

Review in cubic

Replace the guarded POSIX prepare hook with a Node script
(scripts/prepare-merge-driver.mjs) so npm install/ci wire pm-cli's field-aware
merge drivers identically on POSIX shells and Windows cmd.exe.

The guarded POSIX 'if command -v pm; then pm merge install; fi' form cannot be
parsed by Windows cmd.exe (Greptile P1 + CodeRabbit on the xydx wave), so
install failed at prepare on native Windows; the bare form broke POSIX
--omit=dev. The Node guard resolves pm presence via a PATH scan (PATHEXT-aware,
never executes pm): absent -> silent skip; present -> 'pm merge install'
fail-loud (a broken CLI surfaces non-zero). Fleet standard, tracked in companion
pm-cli-website-5cx1; validated real-data on canary pm-beads PR #40.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@unbraind, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 8 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 605a7969-76e1-461d-8688-111d62ff3159

📥 Commits

Reviewing files that changed from the base of the PR and between e936353 and 614e0b2.

📒 Files selected for processing (3)
  • README.md
  • package.json
  • scripts/prepare-merge-driver.mjs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/portable-prepare-merge-driver

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.

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review
@greptileai review
/gemini review

Fleet-standard portable prepare-hook rollout (companion pm-cli-website-5cx1). Script is byte-identical to the canary pm-beads#40, which passed full CI + CodeRabbit + Sourcery review — replaces the guarded POSIX if command -v pm; then pm merge install; fi (Greptile P1: unparseable by Windows cmd.exe) with node scripts/prepare-merge-driver.mjs (PATH-scan presence check: absent→skip, present→fail-loud, cross-shell). Please confirm cross-platform correctness.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

@unbraind I’ll perform a full review of #7, focusing on Node/npm shell independence, Windows PATHEXT-aware PATH discovery, POSIX behavior, and the intended absent-versus-broken-pm exit semantics.

✅ Action performed

Full review finished.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 11 minutes.

Address Greptile findings on the fan-out wave — make the PATH-presence scan
match shell command resolution:
- reject non-executable candidates (directories / non-exec files) via
  statSync().isFile() + accessSync(X_OK) on POSIX, so a stray `pm` dir or data
  file no longer makes `execSync` fail the whole install (P2 "Existence Is Not
  Executability");
- treat an empty POSIX PATH entry as the current directory instead of dropping
  it (P1 "Empty PATH Entry Gets Dropped");
- strip surrounding double quotes from Windows PATH entries before join()
  (P2 "Quoted PATH Entry Skips CLI").

Re-validated real-data: present->wire; absent->skip; broken pm->fail-loud;
pm-dir/non-exec-pm on PATH->skip (no fail-loud); empty-entry+pm-in-cwd->runs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@unbraind

Copy link
Copy Markdown
Owner Author

Pushed a PATH-resolution hardening commit (reject non-executable candidates, treat empty POSIX PATH entry as CWD, strip Windows quoted entries) addressing the Greptile findings from the fan-out wave. Re-review please:

@coderabbitai review
@greptileai review
/gemini review

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@unbraind have exceeded the limit for the number of chat messages per hour. Please wait 7 minutes and 26 seconds before sending another message.

@unbraind
unbraind merged commit d688901 into main Jul 22, 2026
5 checks passed
@unbraind
unbraind deleted the chore/portable-prepare-merge-driver branch July 22, 2026 17:38
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.

1 participant