@@ -2865,6 +2865,7 @@ function normalizePathForComparison(p) {
28652865}
28662866var REASON_RM_RF = "rm -rf outside cwd is blocked. Use explicit paths within the current directory, or delete manually." ;
28672867var REASON_RM_RF_ROOT_HOME = "rm -rf targeting root or home directory is extremely dangerous and always blocked." ;
2868+ var REASON_RM_HOME_CWD = "rm -rf in home directory is dangerous. Change to a project directory first." ;
28682869function analyzeRm ( tokens , options = { } ) {
28692870 const {
28702871 cwd,
@@ -2921,18 +2922,16 @@ function classifyTarget(target, ctx) {
29212922 if ( isDangerousRootOrHomeTarget ( target ) ) {
29222923 return { kind : "root_or_home_target" } ;
29232924 }
2924- const anchoredCwd = ctx . anchoredCwd ;
2925- if ( anchoredCwd ) {
2926- if ( isCwdSelfTarget ( target , anchoredCwd ) ) {
2927- return { kind : "cwd_self_target" } ;
2928- }
2929- }
29302925 if ( isTempTarget ( target , ctx . trustTmpdirVar ) ) {
29312926 return { kind : "temp_target" } ;
29322927 }
2928+ const anchoredCwd = ctx . anchoredCwd ;
29332929 if ( anchoredCwd ) {
29342930 if ( isCwdHomeForRmPolicy ( anchoredCwd , ctx . homeDir ) ) {
2935- return { kind : "root_or_home_target" } ;
2931+ return { kind : "home_cwd_target" } ;
2932+ }
2933+ if ( isCwdSelfTarget ( target , anchoredCwd ) ) {
2934+ return { kind : "cwd_self_target" } ;
29362935 }
29372936 if ( isTargetWithinCwd ( target , anchoredCwd , ctx . resolvedCwd ?? anchoredCwd ) ) {
29382937 return { kind : "within_anchored_cwd" } ;
@@ -2944,10 +2943,12 @@ function reasonForClassification(classification, ctx) {
29442943 switch ( classification . kind ) {
29452944 case "root_or_home_target" :
29462945 return REASON_RM_RF_ROOT_HOME ;
2947- case "cwd_self_target" :
2948- return REASON_RM_RF ;
29492946 case "temp_target" :
29502947 return null ;
2948+ case "home_cwd_target" :
2949+ return REASON_RM_HOME_CWD ;
2950+ case "cwd_self_target" :
2951+ return REASON_RM_RF ;
29512952 case "within_anchored_cwd" :
29522953 if ( ctx . paranoid ) {
29532954 return `${ REASON_RM_RF } (SAFETY_NET_PARANOID_RM enabled)` ;
@@ -3069,14 +3070,6 @@ function isTargetWithinCwd(target, originalCwd, effectiveCwd) {
30693070 return false ;
30703071 }
30713072}
3072- function isHomeDirectory ( cwd ) {
3073- const home = process . env . HOME ?? homedir3 ( ) ;
3074- try {
3075- return normalizePathForComparison ( cwd ) === normalizePathForComparison ( home ) ;
3076- } catch {
3077- return false ;
3078- }
3079- }
30803073
30813074// src/core/analyze/parallel.ts
30823075var REASON_PARALLEL_RM = "parallel rm -rf with dynamic input is dangerous. Use explicit file list instead." ;
@@ -3497,7 +3490,6 @@ function matchesBlockArgs(tokens, blockArgs, shortOpts) {
34973490// src/core/analyze/segment.ts
34983491var REASON_INTERPRETER_DANGEROUS = "Detected potentially dangerous command in interpreter code." ;
34993492var REASON_INTERPRETER_BLOCKED = "Interpreter one-liners are blocked in paranoid mode." ;
3500- var REASON_RM_HOME_CWD = "rm -rf in home directory is dangerous. Change to a project directory first." ;
35013493function deriveCwdContext ( options ) {
35023494 const cwdUnknown = options . effectiveCwd === null ;
35033495 const cwdForRm = cwdUnknown ? undefined : options . effectiveCwd ?? options . cwd ;
@@ -3561,11 +3553,6 @@ function analyzeSegment(tokens, depth, options) {
35613553 }
35623554 }
35633555 if ( isRm ) {
3564- if ( cwdForRm && isHomeDirectory ( cwdForRm ) ) {
3565- if ( hasRecursiveForceFlags ( stripped ) ) {
3566- return REASON_RM_HOME_CWD ;
3567- }
3568- }
35693556 const rmResult = analyzeRm ( stripped , {
35703557 cwd : cwdForRm ,
35713558 originalCwd,
@@ -4682,19 +4669,9 @@ function explainSegment(tokens, depth, options, steps) {
46824669 return { reason } ;
46834670 }
46844671 if ( isRm ) {
4685- if ( effectiveCwd && isHomeDirectory ( effectiveCwd ) && hasRecursiveForceFlags ( strippedTokens ) ) {
4686- const reason2 = "rm -rf in home directory is dangerous. Change to a project directory first." ;
4687- steps . push ( {
4688- type : "rule-check" ,
4689- ruleModule : "rules-rm.ts" ,
4690- ruleFunction : "isHomeDirectory" ,
4691- matched : true ,
4692- reason : reason2
4693- } ) ;
4694- return { reason : reason2 } ;
4695- }
46964672 const reason = analyzeRm ( strippedTokens , {
4697- cwd : effectiveCwd ?? undefined ,
4673+ cwd : cwdForRm ,
4674+ originalCwd,
46984675 paranoid : options . paranoidRm ,
46994676 allowTmpdirVar
47004677 } ) ;
0 commit comments