From 85ce25687ecf1d1f45defd49a04e08214ed5ac4c Mon Sep 17 00:00:00 2001 From: konsisumer Date: Fri, 17 Jul 2026 00:15:34 +0200 Subject: [PATCH] fix(approval): require confirmation for package uninstalls `npm uninstall -g`, pnpm/yarn remove, `pip uninstall` and `brew uninstall` remove software outside the project yet matched no dangerous-command pattern, so the agent ran them without asking (#10199). Add one "package manager uninstall" rule per manager; installs and updates stay unprompted. Hand-ported from PR #64175 (the patterns moved from tools/approval.py to tools/approval_detection.py after it was opened). --- tools/approval_detection.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/approval_detection.py b/tools/approval_detection.py index 6b8d777706..83fbbbb530 100644 --- a/tools/approval_detection.py +++ b/tools/approval_detection.py @@ -393,6 +393,15 @@ DANGEROUS_PATTERNS = [ (r'\bsudo\b[^;|&\n]*?\s+(?:-s\b|--st[a-z]*\b|-a\b|--a[a-z]*\b)', "sudo with privilege flag (stdin/askpass/shell/list)"), # Combined short-flag form (-nS, -sa, -las). (r'\bsudo\b[^;|&\n]*?\s+-[a-z]*[sa][a-z]*\b', "sudo with combined-flag privilege escalation"), + # Package-manager uninstall commands can remove installed software outside + # the current project (notably `npm uninstall -g`). Treat their destructive + # subcommands like other state-removing operations while leaving installs + # and updates alone. + (r'\bnpm\s+(?:-[^\s]+\s+)*(?:uninstall|unlink|remove|rm|r|un)\b', "package manager uninstall"), + (r'\bpnpm\s+(?:-[^\s]+\s+)*(?:uninstall|remove|rm|un)\b', "package manager uninstall"), + (r'\byarn\s+(?:global\s+)?(?:uninstall|remove)\b', "package manager uninstall"), + (r'\bpip(?:3)?\s+(?:-[^\s]+\s+)*uninstall\b', "package manager uninstall"), + (r'\bbrew\s+(?:uninstall|remove|rm)\b', "package manager uninstall"), ]