feat: add prefer-package-manager builtin policy#126
Conversation
Adds a new builtin policy that enforces allowed package managers by blocking non-preferred ones (e.g., pip when uv is preferred). Users configure an allowlist via policyParams and any detected manager not in the list is denied with a message naming the allowed alternatives. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 12 minutes and 49 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThis pull request introduces a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 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 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.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/built-in-policies.mdx (1)
1-7:⚠️ Potential issue | 🟡 MinorUpdate the policy counts at the top of the page.
Line 24 adds the 31st policy, but the frontmatter and intro still say “30 built-in policies”; the parameterized-policy count also needs recomputing because this PR adds another policy with
allowed.Also applies to: 24-24
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/built-in-policies.mdx` around lines 1 - 7, Update the counts in the docs intro and frontmatter: change any occurrence of "30 built-in policies" (frontmatter description and the opening paragraph) to "31 built-in policies", and update the parameterized-policy count from "Nine policies accept parameters" to "Ten policies accept parameters" because the new policy introduces an `allowed` parameter; ensure the line mentioning "Four workflow policies" remains correct and adjust any other numeric summaries to match the new total.
🧹 Nitpick comments (1)
__tests__/hooks/builtin-policies.test.ts (1)
1330-1474: Cover every advertised detector and mixed-command regressions.The new suite is strong, but it does not exercise several newly supported detectors (
yarn,pnpm,pnpx,bunx,pipenv,conda,cargo). Please add table-driven cases for each advertised manager/alias, plus chained-command regressions likeuv --version && pip install flask.As per coding guidelines,
**/__tests__/**/*.{ts,tsx,js,jsx}: Always add unit tests for new behaviour.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@__tests__/hooks/builtin-policies.test.ts` around lines 1330 - 1474, The "prefer-package-manager" test suite (the describe block using policy = BUILTIN_POLICIES.find(...)) is missing cases for several advertised detectors and mixed-command regressions; add table-driven tests within that describe: iterate over managers/aliases ["yarn","pnpm","pnpx","bunx","pipenv","conda","cargo"] (and any existing aliases like pip3/python -m pip) to assert deny for forbidden manager invocations and allow when the allowed list includes the manager, and add regression tests for chained commands such as "uv --version && pip install flask" to ensure the policy still denies the pip segment when uv is preferred; keep tests following the existing makeCtx pattern and assertions on policy.fn(ctx).decision and result.reason where appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CHANGELOG.md`:
- Line 6: Update the CHANGELOG.md line that reads "Add `prefer-package-manager`
builtin policy to enforce allowed package managers (e.g., uv instead of pip)" by
appending the PR number "(`#126`)" to the end of that single-line entry in the "##
Unreleased" section so it follows the required format; ensure spacing and
punctuation match other entries.
In `@src/hooks/builtin-policies.ts`:
- Around line 141-153: The current manager detection (PKG_MANAGER_DETECTORS) is
applied to the entire command string, which allows bypasses; change the check to
evaluate each shell command segment independently by splitting the input on
common separators (&&, ||, ;, |, newline) and for each segment only consider the
launcher/first token as authoritative; update the detection logic that uses
PKG_MANAGER_DETECTORS so it anchors patterns to the start of the segment (or
match against the first token) and ignores mentions in arguments (so "echo pip"
or "uv --version && pip install" won't falsely authorize), and apply the same
per-segment approach to the corresponding checks referenced around the other
usages noted (lines ~884-898).
---
Outside diff comments:
In `@docs/built-in-policies.mdx`:
- Around line 1-7: Update the counts in the docs intro and frontmatter: change
any occurrence of "30 built-in policies" (frontmatter description and the
opening paragraph) to "31 built-in policies", and update the
parameterized-policy count from "Nine policies accept parameters" to "Ten
policies accept parameters" because the new policy introduces an `allowed`
parameter; ensure the line mentioning "Four workflow policies" remains correct
and adjust any other numeric summaries to match the new total.
---
Nitpick comments:
In `@__tests__/hooks/builtin-policies.test.ts`:
- Around line 1330-1474: The "prefer-package-manager" test suite (the describe
block using policy = BUILTIN_POLICIES.find(...)) is missing cases for several
advertised detectors and mixed-command regressions; add table-driven tests
within that describe: iterate over managers/aliases
["yarn","pnpm","pnpx","bunx","pipenv","conda","cargo"] (and any existing aliases
like pip3/python -m pip) to assert deny for forbidden manager invocations and
allow when the allowed list includes the manager, and add regression tests for
chained commands such as "uv --version && pip install flask" to ensure the
policy still denies the pip segment when uv is preferred; keep tests following
the existing makeCtx pattern and assertions on policy.fn(ctx).decision and
result.reason where appropriate.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6b1bc649-6936-4ee7-8e5f-c4e199d8f44d
📒 Files selected for processing (5)
CHANGELOG.md__tests__/e2e/hooks/policy-params.e2e.test.ts__tests__/hooks/builtin-policies.test.tsdocs/built-in-policies.mdxsrc/hooks/builtin-policies.ts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Users can now append additional manager names beyond the built-in list via the blocked param (e.g., pdm, pipx). Entries in blocked are skipped if they also appear in allowed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update getting-started, custom-policies, examples, and README to highlight the .failproofai/policies/ convention workflow: commit to git, share across the team, keep improving as new failure modes are discovered. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split compound commands on &&, ||, |, ; and check each segment separately. Fixes bypass where an allowed manager in one segment (e.g., uv --version) would incorrectly allow a blocked manager in another segment (e.g., pip install flask). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds review-policies.mjs to .failproofai/policies/ that prevents stopping if there are unresolved bot review threads (e.g. CodeRabbit) on the PR. Runs after builtin workflow policies since convention policies evaluate after builtins. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
prefer-package-managerbuiltin policy that enforces allowed package managers via an allowlistallowedlist (e.g.,pipwhen onlyuvis allowed) and tells Claude to rewrite the commandblockedparam (e.g.,pdm,pipx)uv pip installcorrectly), then blocked onesConfiguration
{ "enabledPolicies": ["prefer-package-manager"], "policyParams": { "prefer-package-manager": { "allowed": ["uv", "bun"], "blocked": ["pdm", "pipx"] } } }Test plan