@@ -60,13 +60,24 @@ function collectInputStrings(input) {
6060 * rather than relying on a later caller to split the command first — a bare path-valued field still matches via
6161 * the whole-value candidate.
6262 */
63+ function normalizePathCandidate ( candidate ) {
64+ const normalized = candidate
65+ . replace ( / \\ / g, "/" )
66+ . replace ( / \/ \. (? = \/ | $ ) / g, "" )
67+ . replace ( / ^ (?: \. \/ ) + / , "" ) ;
68+ return normalized || candidate ;
69+ }
70+
6371function pathCandidates ( value ) {
64- const candidates = [ value ] ;
72+ const candidates = new Set ( [ value , normalizePathCandidate ( value ) ] ) ;
6573 for ( const token of value . split ( / \s + / ) ) {
6674 const trimmed = token . replace ( / ^ [ " ' ] + | [ " ' ] + $ / g, "" ) ;
67- if ( trimmed && trimmed !== value ) candidates . push ( trimmed ) ;
75+ if ( trimmed ) {
76+ candidates . add ( trimmed ) ;
77+ candidates . add ( normalizePathCandidate ( trimmed ) ) ;
78+ }
6879 }
69- return candidates ;
80+ return [ ... candidates ] ;
7081}
7182
7283function matcherMatches ( matcher , toolName ) {
@@ -93,14 +104,15 @@ function ruleMatches(rule, toolName, inputStrings) {
93104/**
94105 * The built-in house-rule deny set — a non-empty starting example a later phase can extend or replace. Mirrors the
95106 * forbidden-path regex in `scripts/check-mcp-package.mjs` (CI workflows, env files, secret-bearing paths, private
96- * key material) and adds a conservative git force-push guard (a command carrying both `push` and `-- force` ).
107+ * key material) and adds conservative git force-push guards (a command carrying `push` plus a force flag ).
97108 */
98109export const DEFAULT_DENY_RULES = [
99110 { matcher : "*" , pathPattern : ".github/workflows/**" , reason : "Never modify CI workflows (.github/workflows/**)." } ,
100111 { matcher : "*" , pathPattern : "**/.env*" , reason : "Never read or write environment files (.env*)." } ,
101112 { matcher : "*" , pathPattern : "**/secret*/**" , reason : "Never touch secret-bearing paths (**/secret*/**)." } ,
102113 { matcher : "*" , pathPattern : "**/*private*key*" , reason : "Never touch private key material (**/*private*key*)." } ,
103114 { matcher : "*" , inputIncludesAll : [ "push" , "--force" ] , reason : "Never force-push (git push --force)." } ,
115+ { matcher : "*" , inputIncludesAll : [ "push" , "-f" ] , reason : "Never force-push (git push -f)." } ,
104116] ;
105117
106118/**
0 commit comments