chainwall 0.1.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +411 -105
  2. package/dist/auditor/mcp-detector.d.ts +1 -0
  3. package/dist/auditor/mcp-detector.d.ts.map +1 -1
  4. package/dist/auditor/mcp-detector.js +5 -3
  5. package/dist/auditor/mcp-detector.js.map +1 -1
  6. package/dist/auditor/mcp-poison-detector.d.ts +19 -0
  7. package/dist/auditor/mcp-poison-detector.d.ts.map +1 -0
  8. package/dist/auditor/mcp-poison-detector.js +295 -0
  9. package/dist/auditor/mcp-poison-detector.js.map +1 -0
  10. package/dist/auditor/miner-detector.d.ts +20 -0
  11. package/dist/auditor/miner-detector.d.ts.map +1 -0
  12. package/dist/auditor/miner-detector.js +100 -0
  13. package/dist/auditor/miner-detector.js.map +1 -0
  14. package/dist/auditor/remediation.d.ts +4 -0
  15. package/dist/auditor/remediation.d.ts.map +1 -1
  16. package/dist/auditor/remediation.js +42 -0
  17. package/dist/auditor/remediation.js.map +1 -1
  18. package/dist/auditor/types.d.ts +4 -0
  19. package/dist/auditor/types.d.ts.map +1 -1
  20. package/dist/commands/audit.d.ts.map +1 -1
  21. package/dist/commands/audit.js +20 -0
  22. package/dist/commands/audit.js.map +1 -1
  23. package/dist/commands/scan.d.ts.map +1 -1
  24. package/dist/commands/scan.js +7 -0
  25. package/dist/commands/scan.js.map +1 -1
  26. package/dist/mcp-server/index.js +0 -0
  27. package/dist/reporter/audit-report.d.ts.map +1 -1
  28. package/dist/reporter/audit-report.js +50 -0
  29. package/dist/reporter/audit-report.js.map +1 -1
  30. package/dist/reporter/risk-scorer.d.ts.map +1 -1
  31. package/dist/reporter/risk-scorer.js +8 -0
  32. package/dist/reporter/risk-scorer.js.map +1 -1
  33. package/dist/reporter/shared.d.ts.map +1 -1
  34. package/dist/reporter/shared.js +10 -6
  35. package/dist/reporter/shared.js.map +1 -1
  36. package/dist/rules/index.d.ts +1 -0
  37. package/dist/rules/index.d.ts.map +1 -1
  38. package/dist/rules/index.js +3 -1
  39. package/dist/rules/index.js.map +1 -1
  40. package/dist/rules/mining-rules.d.ts +7 -0
  41. package/dist/rules/mining-rules.d.ts.map +1 -0
  42. package/dist/rules/mining-rules.js +239 -0
  43. package/dist/rules/mining-rules.js.map +1 -0
  44. package/dist/rules/skill-rules.d.ts +10 -0
  45. package/dist/rules/skill-rules.d.ts.map +1 -0
  46. package/dist/rules/skill-rules.js +293 -0
  47. package/dist/rules/skill-rules.js.map +1 -0
  48. package/dist/rules/types.d.ts +1 -1
  49. package/dist/rules/types.d.ts.map +1 -1
  50. package/dist/scanner/filesystem-scanner.d.ts.map +1 -1
  51. package/dist/scanner/filesystem-scanner.js +21 -1
  52. package/dist/scanner/filesystem-scanner.js.map +1 -1
  53. package/dist/scanner/injection-scanner.d.ts +1 -0
  54. package/dist/scanner/injection-scanner.d.ts.map +1 -1
  55. package/dist/scanner/injection-scanner.js +1 -1
  56. package/dist/scanner/injection-scanner.js.map +1 -1
  57. package/dist/scanner/skill-scanner.d.ts +18 -0
  58. package/dist/scanner/skill-scanner.d.ts.map +1 -0
  59. package/dist/scanner/skill-scanner.js +244 -0
  60. package/dist/scanner/skill-scanner.js.map +1 -0
  61. package/dist/tui/components/FileLink.d.ts +12 -0
  62. package/dist/tui/components/FileLink.d.ts.map +1 -0
  63. package/dist/tui/components/FileLink.js +13 -0
  64. package/dist/tui/components/FileLink.js.map +1 -0
  65. package/dist/tui/components/Footer.d.ts.map +1 -1
  66. package/dist/tui/components/Footer.js +45 -30
  67. package/dist/tui/components/Footer.js.map +1 -1
  68. package/dist/tui/components/RemediationMenu.d.ts.map +1 -1
  69. package/dist/tui/components/RemediationMenu.js +2 -1
  70. package/dist/tui/components/RemediationMenu.js.map +1 -1
  71. package/dist/tui/components/Table.d.ts +1 -1
  72. package/dist/tui/components/Table.d.ts.map +1 -1
  73. package/dist/tui/components/Table.js +3 -9
  74. package/dist/tui/components/Table.js.map +1 -1
  75. package/dist/tui/educational.d.ts.map +1 -1
  76. package/dist/tui/educational.js +10 -0
  77. package/dist/tui/educational.js.map +1 -1
  78. package/dist/tui/hooks/useAudit.d.ts.map +1 -1
  79. package/dist/tui/hooks/useAudit.js +17 -0
  80. package/dist/tui/hooks/useAudit.js.map +1 -1
  81. package/dist/tui/hooks/useHookStatus.d.ts.map +1 -1
  82. package/dist/tui/hooks/useHookStatus.js +24 -3
  83. package/dist/tui/hooks/useHookStatus.js.map +1 -1
  84. package/dist/tui/hooks/useScan.d.ts +2 -2
  85. package/dist/tui/hooks/useScan.d.ts.map +1 -1
  86. package/dist/tui/hooks/useScan.js +12 -2
  87. package/dist/tui/hooks/useScan.js.map +1 -1
  88. package/dist/tui/screens/AuditPanel.d.ts.map +1 -1
  89. package/dist/tui/screens/AuditPanel.js +75 -7
  90. package/dist/tui/screens/AuditPanel.js.map +1 -1
  91. package/dist/tui/screens/LogsPanel.d.ts.map +1 -1
  92. package/dist/tui/screens/LogsPanel.js +27 -21
  93. package/dist/tui/screens/LogsPanel.js.map +1 -1
  94. package/dist/tui/screens/OverviewPanel.js +1 -1
  95. package/dist/tui/screens/OverviewPanel.js.map +1 -1
  96. package/dist/tui/screens/ScanPanel.d.ts.map +1 -1
  97. package/dist/tui/screens/ScanPanel.js +4 -4
  98. package/dist/tui/screens/ScanPanel.js.map +1 -1
  99. package/dist/tui/screens/ScanResultsPanel.d.ts.map +1 -1
  100. package/dist/tui/screens/ScanResultsPanel.js +70 -25
  101. package/dist/tui/screens/ScanResultsPanel.js.map +1 -1
  102. package/dist/tui/screens/SettingsPanel.d.ts.map +1 -1
  103. package/dist/tui/screens/SettingsPanel.js +3 -2
  104. package/dist/tui/screens/SettingsPanel.js.map +1 -1
  105. package/dist/tui/theme.d.ts +2 -1
  106. package/dist/tui/theme.d.ts.map +1 -1
  107. package/dist/tui/theme.js +2 -1
  108. package/dist/tui/theme.js.map +1 -1
  109. package/install.sh +3 -2
  110. package/package.json +15 -5
  111. package/patterns/cryptojacking.yaml +198 -0
  112. package/patterns/skill-threats.yaml +183 -0
  113. package/rules/SECURITY-RULES.md +50 -3
  114. package/skill/llm-antivirus/SKILL.md +4 -0
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Validate that a match appears in a code/config context, not documentation.
3
+ * Returns true if this looks like actual mining code/config, false for docs.
4
+ */
5
+ function notDocContext(_match, line) {
6
+ const trimmed = line.trim();
7
+ if (/^\s*(?:#|\/\/|\*|<!--|-->)/.test(trimmed))
8
+ return false;
9
+ if (/\b(?:README|EXAMPLE|DOCUMENTATION|CHANGELOG)\b/i.test(line))
10
+ return false;
11
+ return true;
12
+ }
13
+ /**
14
+ * Validate that algo name appears in JSON/config context (has : or = nearby).
15
+ */
16
+ function inConfigContext(_match, line) {
17
+ if (!notDocContext(_match, line))
18
+ return false;
19
+ return /[=:]/.test(line);
20
+ }
21
+ /**
22
+ * Rules for detecting cryptocurrency mining activity.
23
+ * These are added to allRules and run against ALL scanned files.
24
+ */
25
+ export const miningRules = [
26
+ // ── CRITICAL: Mining Pool URLs ────────────────────────────────────────
27
+ {
28
+ id: 'mine-stratum-tcp',
29
+ name: 'Mining Pool URL (stratum+tcp)',
30
+ regex: /stratum\+tcp:\/\/\S+/i,
31
+ severity: 'critical',
32
+ category: 'cryptojacking',
33
+ description: 'Stratum mining pool connection URL — active mining configuration',
34
+ tags: ['mining-pool', 'stratum'],
35
+ validate: notDocContext,
36
+ },
37
+ {
38
+ id: 'mine-stratum-ssl',
39
+ name: 'Mining Pool URL (stratum+ssl)',
40
+ regex: /stratum\+ssl:\/\/\S+/i,
41
+ severity: 'critical',
42
+ category: 'cryptojacking',
43
+ description: 'Stratum SSL mining pool connection URL — active mining configuration',
44
+ tags: ['mining-pool', 'stratum'],
45
+ validate: notDocContext,
46
+ },
47
+ {
48
+ id: 'mine-known-pool-domain',
49
+ name: 'Known Mining Pool Domain',
50
+ regex: /(?:pool\.minergate\.com|(?:xmr|eth|btc)\.(?:nanopool|f2pool|2miners|herominers)\.org|(?:monero|mining)pool\.\S+|(?:nicehash|ethermine|flexpool|hiveon)\.(?:com|org|io))/i,
51
+ severity: 'critical',
52
+ category: 'cryptojacking',
53
+ description: 'Connection to known cryptocurrency mining pool',
54
+ tags: ['mining-pool'],
55
+ validate: notDocContext,
56
+ },
57
+ // ── HIGH: Mining Pool Ports ───────────────────────────────────────────
58
+ {
59
+ id: 'mine-pool-port',
60
+ name: 'Mining Pool Port in Connection',
61
+ regex: /(?::\s*(?:3333|4444|5555|8888|9999|14444|14433|45700)\b)/,
62
+ severity: 'high',
63
+ category: 'cryptojacking',
64
+ description: 'Common mining pool port in connection configuration',
65
+ tags: ['mining-pool', 'port'],
66
+ validate(match, line) {
67
+ if (!notDocContext(match, line))
68
+ return false;
69
+ // Require pool/stratum/mining context
70
+ return /(?:pool|stratum|miner|mining|worker|hashrate)/i.test(line);
71
+ },
72
+ },
73
+ // ── HIGH: Miner Binaries ──────────────────────────────────────────────
74
+ {
75
+ id: 'mine-xmrig-binary',
76
+ name: 'XMRig Miner Reference',
77
+ regex: /\bxmrig(?:\.exe|\.json|\.config|\.log)?\b/i,
78
+ severity: 'high',
79
+ category: 'cryptojacking',
80
+ description: 'Reference to XMRig cryptocurrency miner',
81
+ tags: ['miner-binary', 'xmrig'],
82
+ validate: notDocContext,
83
+ },
84
+ {
85
+ id: 'mine-known-miner-binary',
86
+ name: 'Known Miner Binary',
87
+ regex: /\b(?:ethminer|cgminer|bfgminer|phoenixminer|cpuminer|minerd|claymore|t-rex|lolminer|nbminer|gminer)\b/i,
88
+ severity: 'high',
89
+ category: 'cryptojacking',
90
+ description: 'Reference to known cryptocurrency mining software',
91
+ tags: ['miner-binary'],
92
+ validate: notDocContext,
93
+ },
94
+ // ── HIGH: Mining Algorithm Config ─────────────────────────────────────
95
+ {
96
+ id: 'mine-algo-config',
97
+ name: 'Mining Algorithm in Config',
98
+ regex: /\b(?:randomx|ethash|kawpow|cryptonight(?:[-_]?(?:lite|heavy|pico|r|v[12]))?|equihash|scrypt|sha256d|blake2[sb]?|lyra2re[v2]*|x11|x13|x16[rs])\b/i,
99
+ severity: 'high',
100
+ category: 'cryptojacking',
101
+ description: 'Mining algorithm specification in configuration context',
102
+ tags: ['mining-algo'],
103
+ validate: inConfigContext,
104
+ },
105
+ // ── CRITICAL: WebAssembly Mining (Browser Miners) ─────────────────────
106
+ {
107
+ id: 'mine-coinhive',
108
+ name: 'CoinHive/Web Miner',
109
+ regex: /\b(?:CoinHive|coinhive|AuthedMine|authedmine)\b/,
110
+ severity: 'critical',
111
+ category: 'cryptojacking',
112
+ description: 'CoinHive browser-based cryptocurrency miner',
113
+ tags: ['web-mining', 'coinhive'],
114
+ validate: notDocContext,
115
+ },
116
+ {
117
+ id: 'mine-cryptoloot',
118
+ name: 'CryptoLoot Web Miner',
119
+ regex: /\b(?:cryptoloot|CryptoLoot|crypto-loot)\b/i,
120
+ severity: 'critical',
121
+ category: 'cryptojacking',
122
+ description: 'CryptoLoot browser-based cryptocurrency miner',
123
+ tags: ['web-mining'],
124
+ validate: notDocContext,
125
+ },
126
+ {
127
+ id: 'mine-wasm-miner',
128
+ name: 'WebAssembly Mining Module',
129
+ regex: /cryptonight\.wasm|(?:miner|mining)\.wasm/i,
130
+ severity: 'critical',
131
+ category: 'cryptojacking',
132
+ description: 'WebAssembly cryptocurrency mining module',
133
+ tags: ['web-mining', 'wasm'],
134
+ validate: notDocContext,
135
+ },
136
+ // ── MEDIUM: Mining Library Imports ────────────────────────────────────
137
+ {
138
+ id: 'mine-js-import',
139
+ name: 'Mining Library Import (JS)',
140
+ regex: /(?:require|import)\s*\(\s*['"](?:coinhive|xmr-miner|cryptonight-(?:wasm|asmjs)|monero-miner|webmine)/i,
141
+ severity: 'medium',
142
+ category: 'cryptojacking',
143
+ description: 'JavaScript import of cryptocurrency mining library',
144
+ tags: ['mining-lib', 'javascript'],
145
+ },
146
+ {
147
+ id: 'mine-python-import',
148
+ name: 'Mining Library Import (Python)',
149
+ regex: /(?:^|\s)(?:import|from)\s+(?:pyxmrig|minerlib|coinhive|cpuminer)/,
150
+ severity: 'medium',
151
+ category: 'cryptojacking',
152
+ description: 'Python import of cryptocurrency mining library',
153
+ tags: ['mining-lib', 'python'],
154
+ },
155
+ // ── HIGH: Monero Wallet in Config ─────────────────────────────────────
156
+ {
157
+ id: 'mine-monero-wallet',
158
+ name: 'Monero Wallet Address in Config',
159
+ regex: /(?:wallet|address|user)\s*[=:"']\s*4[0-9A-Za-z]{94}/,
160
+ severity: 'high',
161
+ category: 'cryptojacking',
162
+ description: 'Monero wallet address in mining configuration context',
163
+ tags: ['wallet', 'monero'],
164
+ validate: notDocContext,
165
+ },
166
+ // ── HIGH: Mining Environment Variables ────────────────────────────────
167
+ {
168
+ id: 'mine-env-vars',
169
+ name: 'Mining Environment Variables',
170
+ regex: /\b(?:MINING_WALLET|MINER_WALLET|POOL_WALLET|MINING_POOL|MINER_POOL|WORKER_NAME|MINING_THREADS|HASHRATE_TARGET)\s*=/i,
171
+ severity: 'high',
172
+ category: 'cryptojacking',
173
+ description: 'Environment variable associated with mining configuration',
174
+ tags: ['mining-env'],
175
+ },
176
+ // ── HIGH: Miner Config Files (filename scope) ─────────────────────────
177
+ {
178
+ id: 'mine-config-file-xmrig',
179
+ name: 'XMRig Config File',
180
+ regex: /\bxmrig\.json\b/i,
181
+ severity: 'high',
182
+ category: 'cryptojacking',
183
+ description: 'XMRig miner configuration file',
184
+ tags: ['miner-config'],
185
+ scope: 'filename',
186
+ },
187
+ {
188
+ id: 'mine-config-file-pools',
189
+ name: 'Mining Pools Config File',
190
+ regex: /\bpools\.txt\b/i,
191
+ severity: 'high',
192
+ category: 'cryptojacking',
193
+ description: 'Mining pool configuration file',
194
+ tags: ['miner-config'],
195
+ scope: 'filename',
196
+ validate(match, line) {
197
+ // Only flag if in a mining context
198
+ return /(?:miner|mining|xmrig|stratum)/i.test(line);
199
+ },
200
+ },
201
+ {
202
+ id: 'mine-config-file-generic',
203
+ name: 'Miner Config File',
204
+ regex: /\bminer\.conf\b/i,
205
+ severity: 'high',
206
+ category: 'cryptojacking',
207
+ description: 'Generic miner configuration file',
208
+ tags: ['miner-config'],
209
+ scope: 'filename',
210
+ },
211
+ // ── HIGH: Mining Hashrate/Worker Config ───────────────────────────────
212
+ {
213
+ id: 'mine-hashrate-config',
214
+ name: 'Mining Hashrate Configuration',
215
+ regex: /(?:hashrate|hash_rate|threads|max-threads-hint)\s*[=:"']\s*\d+/i,
216
+ severity: 'high',
217
+ category: 'cryptojacking',
218
+ description: 'Mining hashrate or thread configuration',
219
+ tags: ['mining-config'],
220
+ validate(match, line) {
221
+ if (!notDocContext(match, line))
222
+ return false;
223
+ // Require mining context to avoid false positives on generic thread configs
224
+ return /(?:miner|mining|pool|stratum|worker|xmrig|hashrate|coin)/i.test(line);
225
+ },
226
+ },
227
+ // ── CRITICAL: Mining Process Launch ───────────────────────────────────
228
+ {
229
+ id: 'mine-process-launch',
230
+ name: 'Mining Process Launch',
231
+ regex: /(?:\.\/|\/usr\/(?:local\/)?bin\/)(?:xmrig|minerd|cpuminer|ethminer|cgminer|bfgminer)\b/,
232
+ severity: 'critical',
233
+ category: 'cryptojacking',
234
+ description: 'Direct launch of cryptocurrency mining binary',
235
+ tags: ['miner-launch'],
236
+ validate: notDocContext,
237
+ },
238
+ ];
239
+ //# sourceMappingURL=mining-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mining-rules.js","sourceRoot":"","sources":["../../src/rules/mining-rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { Rule } from './types.js';
2
+ /**
3
+ * Rules for detecting malicious patterns in AI skill/instruction files.
4
+ * These target shell payloads, exfiltration, credential harvesting, and
5
+ * obfuscated code hidden in SKILL.md, CLAUDE.md, AGENTS.md, etc.
6
+ *
7
+ * Separate from allRules — only run against skill/instruction files.
8
+ */
9
+ export declare const skillFileRules: Rule[];
10
+ //# sourceMappingURL=skill-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-rules.d.ts","sourceRoot":"","sources":["../../src/rules/skill-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAcvC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,IAAI,EAuRhC,CAAC"}
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Validate that the match is NOT inside a documentation/comment context.
3
+ * Returns true if this looks like a real threat, false for docs/examples.
4
+ */
5
+ function notDocContext(_match, line) {
6
+ const trimmed = line.trim();
7
+ // Skip documentation lines
8
+ if (/^\s*(?:#|\/\/|\*|<!--|-->)/.test(trimmed))
9
+ return false;
10
+ if (/\b(?:README|EXAMPLE|DOCUMENTATION|CHANGELOG)\b/i.test(line))
11
+ return false;
12
+ return true;
13
+ }
14
+ /**
15
+ * Rules for detecting malicious patterns in AI skill/instruction files.
16
+ * These target shell payloads, exfiltration, credential harvesting, and
17
+ * obfuscated code hidden in SKILL.md, CLAUDE.md, AGENTS.md, etc.
18
+ *
19
+ * Separate from allRules — only run against skill/instruction files.
20
+ */
21
+ export const skillFileRules = [
22
+ // ── CRITICAL: Shell Code in Markdown ──────────────────────────────────
23
+ {
24
+ id: 'skill-curl-pipe-shell',
25
+ name: 'Curl Pipe to Shell',
26
+ regex: /curl\s+(?:-[sSfLk]+\s+)*https?:\/\/\S+\s*\|\s*(?:bash|sh|zsh)/i,
27
+ severity: 'critical',
28
+ category: 'skill_threat',
29
+ description: 'Downloads and executes remote script via curl pipe to shell',
30
+ tags: ['shell', 'download-execute'],
31
+ validate: notDocContext,
32
+ },
33
+ {
34
+ id: 'skill-wget-pipe-shell',
35
+ name: 'Wget Pipe to Shell',
36
+ regex: /wget\s+(?:-[qO-]+\s+)*https?:\/\/\S+\s*(?:\|\s*(?:bash|sh|zsh)|;\s*(?:bash|sh|zsh))/i,
37
+ severity: 'critical',
38
+ category: 'skill_threat',
39
+ description: 'Downloads and executes remote script via wget',
40
+ tags: ['shell', 'download-execute'],
41
+ validate: notDocContext,
42
+ },
43
+ {
44
+ id: 'skill-reverse-shell',
45
+ name: 'Reverse Shell Payload',
46
+ regex: /(?:\/dev\/tcp\/|nc\s+-[elp]+|ncat\s|mkfifo\s+\/tmp\/|bash\s+-i\s+>&\s*\/dev\/tcp)/i,
47
+ severity: 'critical',
48
+ category: 'skill_threat',
49
+ description: 'Reverse shell pattern that connects back to an attacker',
50
+ tags: ['shell', 'reverse-shell'],
51
+ validate: notDocContext,
52
+ },
53
+ {
54
+ id: 'skill-rm-rf',
55
+ name: 'Destructive rm Command',
56
+ regex: /rm\s+-[rfR]{2,}\s+(?:\/|~|\$HOME|\$\{HOME\}|\.\.)/,
57
+ severity: 'critical',
58
+ category: 'skill_threat',
59
+ description: 'Destructive recursive delete targeting important directories',
60
+ tags: ['shell', 'destructive'],
61
+ validate: notDocContext,
62
+ },
63
+ {
64
+ id: 'skill-chmod-777',
65
+ name: 'chmod 777 (World Writable)',
66
+ regex: /chmod\s+(?:-R\s+)?777\s/,
67
+ severity: 'high',
68
+ category: 'skill_threat',
69
+ description: 'Sets world-writable permissions, enabling unauthorized modification',
70
+ tags: ['shell', 'permissions'],
71
+ validate: notDocContext,
72
+ },
73
+ // ── CRITICAL: Data Exfiltration ──────────────────────────────────────
74
+ {
75
+ id: 'skill-curl-post-data',
76
+ name: 'curl POST Exfiltration',
77
+ regex: /curl\s+(?:.*\s)?-(?:X\s+POST|d\s|--data)\s.*(?:\.env|\$\(|`cat\b|process\.env|credentials|secret|token|password)/i,
78
+ severity: 'critical',
79
+ category: 'skill_threat',
80
+ description: 'Exfiltrates sensitive data via HTTP POST request',
81
+ tags: ['exfiltration', 'curl'],
82
+ validate: notDocContext,
83
+ },
84
+ {
85
+ id: 'skill-webhook-send',
86
+ name: 'Webhook Data Send',
87
+ regex: /(?:webhook|hook|callback)\S*\s*[=:]\s*["']?https?:\/\/\S+/i,
88
+ severity: 'high',
89
+ category: 'skill_threat',
90
+ description: 'Sends data to an external webhook endpoint',
91
+ tags: ['exfiltration', 'webhook'],
92
+ validate: notDocContext,
93
+ },
94
+ {
95
+ id: 'skill-encoded-url-exfil',
96
+ name: 'Encoded URL Exfiltration',
97
+ regex: /https?:\/\/\S+\?[^"'\s]*(?:data|token|key|secret|password|env)=[^"'\s]*\$\(/i,
98
+ severity: 'critical',
99
+ category: 'skill_threat',
100
+ description: 'Exfiltrates data via encoded URL parameters with command substitution',
101
+ tags: ['exfiltration', 'url-params'],
102
+ validate: notDocContext,
103
+ },
104
+ // ── HIGH: External URL Fetches / Install ─────────────────────────────
105
+ {
106
+ id: 'skill-url-pip-install',
107
+ name: 'pip Install from URL',
108
+ regex: /pip3?\s+install\s+(?:--[a-z-]+\s+)*https?:\/\/\S+/i,
109
+ severity: 'high',
110
+ category: 'skill_threat',
111
+ description: 'Installs Python package from arbitrary URL instead of PyPI',
112
+ tags: ['supply-chain', 'pip'],
113
+ validate: notDocContext,
114
+ },
115
+ {
116
+ id: 'skill-npm-install-url',
117
+ name: 'npm Install from URL/Git',
118
+ regex: /npm\s+install\s+(?:--[a-z-]+\s+)*(?:https?:\/\/|git\+|github:)\S+/i,
119
+ severity: 'high',
120
+ category: 'skill_threat',
121
+ description: 'Installs npm package from arbitrary URL or git repo',
122
+ tags: ['supply-chain', 'npm'],
123
+ validate: notDocContext,
124
+ },
125
+ // ── HIGH/CRITICAL: Obfuscated Payloads ───────────────────────────────
126
+ {
127
+ id: 'skill-hex-escape-sequence',
128
+ name: 'Long Hex Escape Sequence',
129
+ regex: /(?:\\x[0-9a-fA-F]{2}){8,}/,
130
+ severity: 'high',
131
+ category: 'skill_threat',
132
+ description: 'Long hex escape sequence that may hide executable commands',
133
+ tags: ['obfuscation', 'hex'],
134
+ },
135
+ {
136
+ id: 'skill-long-base64',
137
+ name: 'Long Base64 String',
138
+ regex: /(?:base64\s+(?:-d|--decode)|atob|Buffer\.from)\s*[("'`]\s*[A-Za-z0-9+/=]{100,}/,
139
+ severity: 'high',
140
+ category: 'skill_threat',
141
+ description: 'Decoding a long base64 string — may contain hidden payload',
142
+ tags: ['obfuscation', 'base64'],
143
+ validate: notDocContext,
144
+ },
145
+ {
146
+ id: 'skill-eval-string-concat',
147
+ name: 'Eval with String Concatenation',
148
+ regex: /eval\s*\(\s*(?:["'][^"']*["']\s*\+\s*){2,}/,
149
+ severity: 'high',
150
+ category: 'skill_threat',
151
+ description: 'Eval with concatenated strings — obfuscation technique',
152
+ tags: ['obfuscation', 'eval'],
153
+ },
154
+ // ── HIGH: Hidden Instructions ────────────────────────────────────────
155
+ {
156
+ id: 'skill-html-comment-action',
157
+ name: 'HTML Comment with Action Keywords',
158
+ regex: /<!--\s*(?:curl|wget|fetch|exec|run|send|post|download|install|eval)\b[^>]{5,}-->/i,
159
+ severity: 'high',
160
+ category: 'skill_threat',
161
+ description: 'HTML comment containing executable action keywords',
162
+ tags: ['hidden', 'html-comment'],
163
+ },
164
+ {
165
+ id: 'skill-unicode-bidi',
166
+ name: 'Unicode Bidirectional Override',
167
+ regex: /[\u200F\u200E\u202A-\u202E\u2066-\u2069]/,
168
+ severity: 'high',
169
+ category: 'skill_threat',
170
+ description: 'Unicode bidirectional override character can hide malicious text',
171
+ tags: ['hidden', 'unicode'],
172
+ },
173
+ {
174
+ id: 'skill-script-iframe-tag',
175
+ name: 'Script/Iframe Tag in Instruction',
176
+ regex: /<\s*(?:script|iframe)\b[^>]*>/i,
177
+ severity: 'high',
178
+ category: 'skill_threat',
179
+ description: 'Script or iframe tag in an instruction file',
180
+ tags: ['hidden', 'html'],
181
+ },
182
+ {
183
+ id: 'skill-zero-width-chars',
184
+ name: 'Zero-Width Characters',
185
+ regex: /[\u200B\u200C\u200D\uFEFF]{3,}/,
186
+ severity: 'medium',
187
+ category: 'skill_threat',
188
+ description: 'Cluster of zero-width characters may hide invisible instructions',
189
+ tags: ['hidden', 'unicode'],
190
+ },
191
+ // ── CRITICAL: Credential Harvesting ──────────────────────────────────
192
+ {
193
+ id: 'skill-read-ssh-key',
194
+ name: 'SSH Key Read Instruction',
195
+ regex: /(?:read|cat|open|display|print|output|show)\s+(?:the\s+)?(?:contents?\s+(?:of\s+)?)?~?\/?(?:\.ssh\/id_(?:rsa|ed25519|ecdsa)|\.ssh\/(?:config|known_hosts|authorized_keys))/i,
196
+ severity: 'critical',
197
+ category: 'skill_threat',
198
+ description: 'Instruction to read SSH private keys or config',
199
+ tags: ['credential-harvest', 'ssh'],
200
+ },
201
+ {
202
+ id: 'skill-read-aws-creds',
203
+ name: 'AWS Credentials Read Instruction',
204
+ regex: /(?:read|cat|open|display|print|output|show)\s+(?:the\s+)?(?:contents?\s+(?:of\s+)?)?~?\/?\.aws\/(?:credentials|config)/i,
205
+ severity: 'critical',
206
+ category: 'skill_threat',
207
+ description: 'Instruction to read AWS credentials file',
208
+ tags: ['credential-harvest', 'aws'],
209
+ },
210
+ {
211
+ id: 'skill-read-env-file',
212
+ name: '.env File Read Instruction',
213
+ regex: /(?:read|cat|open|display|print|output|show)\s+(?:the\s+)?(?:contents?\s+(?:of\s+)?)?(?:\.env|\.env\.local|\.env\.production)/i,
214
+ severity: 'critical',
215
+ category: 'skill_threat',
216
+ description: 'Instruction to read .env file containing secrets',
217
+ tags: ['credential-harvest', 'env'],
218
+ validate: notDocContext,
219
+ },
220
+ {
221
+ id: 'skill-dump-env-vars',
222
+ name: 'Environment Variable Dump',
223
+ regex: /(?:print|echo|output|dump|list|show)\s+(?:all\s+)?(?:the\s+)?(?:env(?:ironment)?\s*(?:variables?|vars?))/i,
224
+ severity: 'high',
225
+ category: 'skill_threat',
226
+ description: 'Instruction to dump all environment variables',
227
+ tags: ['credential-harvest', 'env'],
228
+ validate: notDocContext,
229
+ },
230
+ // ── CRITICAL: System Modification ────────────────────────────────────
231
+ {
232
+ id: 'skill-modify-bashrc',
233
+ name: 'Shell Profile Modification',
234
+ regex: /(?:add|append|write|insert|modify|edit)\s+(?:to\s+)?(?:the\s+)?(?:~\/?)?\.(?:bashrc|zshrc|profile|bash_profile|zprofile)/i,
235
+ severity: 'critical',
236
+ category: 'skill_threat',
237
+ description: 'Instruction to modify shell profile for persistent access',
238
+ tags: ['system-mod', 'persistence'],
239
+ validate: notDocContext,
240
+ },
241
+ {
242
+ id: 'skill-crontab-add',
243
+ name: 'Crontab Modification',
244
+ regex: /(?:crontab|cron)\s+(?:-[elr]\s+)?.*(?:add|write|install|create)/i,
245
+ severity: 'critical',
246
+ category: 'skill_threat',
247
+ description: 'Instruction to add crontab entry for persistent execution',
248
+ tags: ['system-mod', 'persistence'],
249
+ validate: notDocContext,
250
+ },
251
+ {
252
+ id: 'skill-write-etc',
253
+ name: 'Write to /etc/ Directory',
254
+ regex: /(?:write|echo|cat|tee)\s+.*(?:>|>>)\s*\/etc\//,
255
+ severity: 'critical',
256
+ category: 'skill_threat',
257
+ description: 'Writing to system configuration directory',
258
+ tags: ['system-mod', 'system-config'],
259
+ validate: notDocContext,
260
+ },
261
+ // ── HIGH: Security Bypass ────────────────────────────────────────────
262
+ {
263
+ id: 'skill-disable-security-tool',
264
+ name: 'Security Tool Disable Instruction',
265
+ regex: /(?:disable|remove|uninstall|stop|kill|bypass)\s+(?:the\s+)?(?:chainwall|security|antivirus|firewall|gatekeeper|sip)/i,
266
+ severity: 'critical',
267
+ category: 'skill_threat',
268
+ description: 'Instruction to disable security tools including ChainWall',
269
+ tags: ['security-bypass'],
270
+ validate: notDocContext,
271
+ },
272
+ {
273
+ id: 'skill-disable-ssl',
274
+ name: 'SSL/TLS Verification Disable',
275
+ regex: /(?:--(?:no-check-certificate|insecure)|NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*["']?0|verify\s*=\s*False|SSL_VERIFY\s*=\s*(?:false|0))/i,
276
+ severity: 'high',
277
+ category: 'skill_threat',
278
+ description: 'Disabling SSL/TLS certificate verification',
279
+ tags: ['security-bypass', 'ssl'],
280
+ },
281
+ // ── HIGH: Password-Protected Archives ────────────────────────────────
282
+ {
283
+ id: 'skill-password-archive',
284
+ name: 'Password-Protected Archive Extraction',
285
+ regex: /(?:unzip|7z|7za)\s+(?:.*\s)?-[pP]\s*\S+/,
286
+ severity: 'high',
287
+ category: 'skill_threat',
288
+ description: 'Extracting password-protected archive — may contain hidden payloads',
289
+ tags: ['archive', 'password'],
290
+ validate: notDocContext,
291
+ },
292
+ ];
293
+ //# sourceMappingURL=skill-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-rules.js","sourceRoot":"","sources":["../../src/rules/skill-rules.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export type Severity = 'critical' | 'high' | 'medium' | 'low';
2
- export type Category = 'credential' | 'private_key' | 'dangerous_command' | 'pii' | 'injection' | 'prompt_injection' | 'supply_chain' | 'crypto' | 'permission';
2
+ export type Category = 'credential' | 'private_key' | 'dangerous_command' | 'pii' | 'injection' | 'prompt_injection' | 'supply_chain' | 'crypto' | 'skill_threat' | 'cryptojacking' | 'permission';
3
3
  export type RuleScope = 'content' | 'filename';
4
4
  export type RuleAction = 'block' | 'warn';
5
5
  export interface Rule {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9D,MAAM,MAAM,QAAQ,GAChB,YAAY,GACZ,aAAa,GACb,mBAAmB,GACnB,KAAK,GACL,WAAW,GACX,kBAAkB,GAClB,cAAc,GACd,QAAQ,GACR,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAC/C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9D,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE9D,MAAM,MAAM,QAAQ,GAChB,YAAY,GACZ,aAAa,GACb,mBAAmB,GACnB,KAAK,GACL,WAAW,GACX,kBAAkB,GAClB,cAAc,GACd,QAAQ,GACR,cAAc,GACd,eAAe,GACf,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAC/C,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9D,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"filesystem-scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/filesystem-scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,eAAO,MAAM,SAAS,aAmFpB,CAAC;AAEH,eAAO,MAAM,SAAS,aAGpB,CAAC;AAEH,eAAO,MAAM,eAAe,aAQ1B,CAAC;AAEH,eAAO,MAAM,aAAa,UAAY,CAAC;AAqBvC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIjD;AAED,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAejE;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAOD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAU/D;AAoCD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAuB,SAAS,CAC9B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,WAAW,GACpB,cAAc,CAAC,WAAW,CAAC,CAoD7B;AAID,wBAAuB,iBAAiB,CACtC,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,CAAC,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,WAAW,CAAC,CAiF7B"}
1
+ {"version":3,"file":"filesystem-scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/filesystem-scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,eAAO,MAAM,SAAS,aAmFpB,CAAC;AAEH,eAAO,MAAM,SAAS,aAGpB,CAAC;AAEH,eAAO,MAAM,eAAe,aAQ1B,CAAC;AAaH,eAAO,MAAM,aAAa,UAAY,CAAC;AAqBvC,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIjD;AAED,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAejE;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAOD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAU/D;AAoCD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAuB,SAAS,CAC9B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,WAAW,GACpB,cAAc,CAAC,WAAW,CAAC,CA4D7B;AAID,wBAAuB,iBAAiB,CACtC,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,CAAC,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,WAAW,CAAC,CAiF7B"}
@@ -1,4 +1,5 @@
1
1
  import { opendir, lstat, open, readFile } from 'node:fs/promises';
2
+ import { readFileSync } from 'node:fs';
2
3
  import { join, basename } from 'node:path';
3
4
  export const SKIP_DIRS = new Set([
4
5
  'node_modules',
@@ -97,6 +98,18 @@ export const SKIP_EXTENSIONS = new Set([
97
98
  '.mp3', '.mp4', '.wav', '.avi', '.mov',
98
99
  '.lock',
99
100
  ]);
101
+ // Directories containing rule/pattern definitions that trigger false positives
102
+ // when scanning the chainwall project itself
103
+ const CHAINWALL_SOURCE_DIRS = ['hooks', 'patterns', 'skill', 'commands', 'rules'];
104
+ function isChainwallProject(rootDir) {
105
+ try {
106
+ const pkg = JSON.parse(readFileSync(join(rootDir, 'package.json'), 'utf-8'));
107
+ return pkg.name === 'chainwall';
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
100
113
  export const MAX_FILE_SIZE = 1_048_576; // 1MB
101
114
  const DEFAULT_MAX_DEPTH = 50;
102
115
  const HOME_MAX_DEPTH = 10;
@@ -197,9 +210,16 @@ export async function* walkFiles(rootDir, stats, signal, options) {
197
210
  const maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
198
211
  const maxFiles = options?.maxFiles ?? DEFAULT_MAX_FILES;
199
212
  const skipSet = buildSkipSet(options);
213
+ // Skip chainwall's own rule/pattern directories to avoid false positives
214
+ let effectiveSkipSet = skipSet;
215
+ if (isChainwallProject(rootDir)) {
216
+ effectiveSkipSet = new Set(skipSet);
217
+ for (const d of CHAINWALL_SOURCE_DIRS)
218
+ effectiveSkipSet.add(d);
219
+ }
200
220
  let count = 0;
201
221
  let yielded = 0;
202
- for await (const fullPath of streamWalk(rootDir, maxDepth, skipSet)) {
222
+ for await (const fullPath of streamWalk(rootDir, maxDepth, effectiveSkipSet)) {
203
223
  if (++count % 50 === 0 && signal?.aborted)
204
224
  return;
205
225
  if (yielded >= maxFiles)