Skip to content

Commit 0d63f2d

Browse files
committed
feat(command-blocker): ✨ Block npx commands for reproducibility
Enhanced command blocking by adding support for `npx` commands. This ensures reproducible builds by advising users to use `bunx` instead. The change includes specific error messages for both direct `npx` commands and those used in piped commands. - Added test cases for blocking `npx` commands. - Updated blocked command messages to include `npx` guidance.
1 parent fa2cc8b commit 0d63f2d

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

command-blocker.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ describe("Command Blocker", () => {
4545
);
4646
});
4747

48+
it("should block npx command", async () => {
49+
const input = { tool: "bash" };
50+
const output = { args: { command: "npx create-react-app my-app" } };
51+
52+
await expect(
53+
plugin["tool.execute.before"](input, output)
54+
).rejects.toThrow(
55+
"`npx` is blocked to ensure reproducible builds. Use `bunx` (faster, more reliable) instead. Examples: `bunx create-react-app my-app` instead of `npx create-react-app my-app`"
56+
);
57+
});
58+
4859
it("should block pip command", async () => {
4960
const input = { tool: "bash" };
5061
const output = { args: { command: "pip install requests" } };
@@ -240,6 +251,20 @@ describe("Command Blocker", () => {
240251
).rejects.toThrow();
241252
});
242253

254+
it("should block npx in piped commands", async () => {
255+
const input1 = { tool: "bash" };
256+
const output1 = { args: { command: 'echo "npx create-react-app" | sh' } };
257+
await expect(
258+
plugin["tool.execute.before"](input1, output1)
259+
).rejects.toThrow();
260+
261+
const input2 = { tool: "bash" };
262+
const output2 = { args: { command: "npx eslint | grep error" } };
263+
await expect(
264+
plugin["tool.execute.before"](input2, output2)
265+
).rejects.toThrow();
266+
});
267+
243268
it("should block pip in piped commands", async () => {
244269
const input1 = { tool: "bash" };
245270
const output1 = {

command-blocker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface ReadOnlyFiles {
1111
const BLOCKED_COMMAND_MESSAGES: BlockedCommandMessages = {
1212
node: "`node` is blocked to ensure reproducible builds. Use `bun` (faster, more reliable) or `bunx` for running scripts. Example: `bun run dev` instead of `node server.js`",
1313
npm: "`npm` is blocked to ensure reproducible builds. Use `bun` (faster, more reliable) instead. Examples: `bun install` instead of `npm install`, `bun run build` instead of `npm run build`",
14+
npx: "`npx` is blocked to ensure reproducible builds. Use `bunx` (faster, more reliable) instead. Examples: `bunx create-react-app my-app` instead of `npx create-react-app my-app`",
1415
pip: "`pip` is blocked to ensure reproducible builds. Use `uv` or `uvx` for dependency management. Example: `uv add requests` instead of `pip install requests`",
1516
python:
1617
"`python` is blocked to ensure environment isolation. Use `uv` for dependency management or `uvx` for running tools. Virtual environment python (e.g., `.venv/bin/python`) is allowed. Example: `uv run python script.py`",

0 commit comments

Comments
 (0)