chainwall 0.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 (348) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -0
  3. package/commands/security-scan.md +35 -0
  4. package/dist/auditor/access-mapper.d.ts +3 -0
  5. package/dist/auditor/access-mapper.d.ts.map +1 -0
  6. package/dist/auditor/access-mapper.js +15 -0
  7. package/dist/auditor/access-mapper.js.map +1 -0
  8. package/dist/auditor/cli-detector.d.ts +7 -0
  9. package/dist/auditor/cli-detector.d.ts.map +1 -0
  10. package/dist/auditor/cli-detector.js +63 -0
  11. package/dist/auditor/cli-detector.js.map +1 -0
  12. package/dist/auditor/cross-reference.d.ts +4 -0
  13. package/dist/auditor/cross-reference.d.ts.map +1 -0
  14. package/dist/auditor/cross-reference.js +16 -0
  15. package/dist/auditor/cross-reference.js.map +1 -0
  16. package/dist/auditor/env-auditor.d.ts +9 -0
  17. package/dist/auditor/env-auditor.d.ts.map +1 -0
  18. package/dist/auditor/env-auditor.js +83 -0
  19. package/dist/auditor/env-auditor.js.map +1 -0
  20. package/dist/auditor/mcp-analyzer.d.ts +11 -0
  21. package/dist/auditor/mcp-analyzer.d.ts.map +1 -0
  22. package/dist/auditor/mcp-analyzer.js +145 -0
  23. package/dist/auditor/mcp-analyzer.js.map +1 -0
  24. package/dist/auditor/mcp-detector.d.ts +17 -0
  25. package/dist/auditor/mcp-detector.d.ts.map +1 -0
  26. package/dist/auditor/mcp-detector.js +86 -0
  27. package/dist/auditor/mcp-detector.js.map +1 -0
  28. package/dist/auditor/remediation.d.ts +26 -0
  29. package/dist/auditor/remediation.d.ts.map +1 -0
  30. package/dist/auditor/remediation.js +222 -0
  31. package/dist/auditor/remediation.js.map +1 -0
  32. package/dist/auditor/tool-detector.d.ts +15 -0
  33. package/dist/auditor/tool-detector.d.ts.map +1 -0
  34. package/dist/auditor/tool-detector.js +241 -0
  35. package/dist/auditor/tool-detector.js.map +1 -0
  36. package/dist/auditor/types.d.ts +31 -0
  37. package/dist/auditor/types.d.ts.map +1 -0
  38. package/dist/auditor/types.js +2 -0
  39. package/dist/auditor/types.js.map +1 -0
  40. package/dist/auditor/vscode-extension-scanner.d.ts +8 -0
  41. package/dist/auditor/vscode-extension-scanner.d.ts.map +1 -0
  42. package/dist/auditor/vscode-extension-scanner.js +51 -0
  43. package/dist/auditor/vscode-extension-scanner.js.map +1 -0
  44. package/dist/cli.d.ts +3 -0
  45. package/dist/cli.d.ts.map +1 -0
  46. package/dist/cli.js +159 -0
  47. package/dist/cli.js.map +1 -0
  48. package/dist/commands/audit.d.ts +8 -0
  49. package/dist/commands/audit.d.ts.map +1 -0
  50. package/dist/commands/audit.js +151 -0
  51. package/dist/commands/audit.js.map +1 -0
  52. package/dist/commands/init.d.ts +2 -0
  53. package/dist/commands/init.d.ts.map +1 -0
  54. package/dist/commands/init.js +34 -0
  55. package/dist/commands/init.js.map +1 -0
  56. package/dist/commands/remediate-cli.d.ts +3 -0
  57. package/dist/commands/remediate-cli.d.ts.map +1 -0
  58. package/dist/commands/remediate-cli.js +96 -0
  59. package/dist/commands/remediate-cli.js.map +1 -0
  60. package/dist/commands/scan.d.ts +11 -0
  61. package/dist/commands/scan.d.ts.map +1 -0
  62. package/dist/commands/scan.js +138 -0
  63. package/dist/commands/scan.js.map +1 -0
  64. package/dist/commands/watch.d.ts +6 -0
  65. package/dist/commands/watch.d.ts.map +1 -0
  66. package/dist/commands/watch.js +203 -0
  67. package/dist/commands/watch.js.map +1 -0
  68. package/dist/config.d.ts +19 -0
  69. package/dist/config.d.ts.map +1 -0
  70. package/dist/config.js +235 -0
  71. package/dist/config.js.map +1 -0
  72. package/dist/mcp-server/index.d.ts +3 -0
  73. package/dist/mcp-server/index.d.ts.map +1 -0
  74. package/dist/mcp-server/index.js +69 -0
  75. package/dist/mcp-server/index.js.map +1 -0
  76. package/dist/mcp-server/schemas.d.ts +13 -0
  77. package/dist/mcp-server/schemas.d.ts.map +1 -0
  78. package/dist/mcp-server/schemas.js +13 -0
  79. package/dist/mcp-server/schemas.js.map +1 -0
  80. package/dist/mcp-server/tools/audit-status.d.ts +3 -0
  81. package/dist/mcp-server/tools/audit-status.d.ts.map +1 -0
  82. package/dist/mcp-server/tools/audit-status.js +46 -0
  83. package/dist/mcp-server/tools/audit-status.js.map +1 -0
  84. package/dist/mcp-server/tools/check-command.d.ts +4 -0
  85. package/dist/mcp-server/tools/check-command.d.ts.map +1 -0
  86. package/dist/mcp-server/tools/check-command.js +30 -0
  87. package/dist/mcp-server/tools/check-command.js.map +1 -0
  88. package/dist/mcp-server/tools/scan-content.d.ts +4 -0
  89. package/dist/mcp-server/tools/scan-content.d.ts.map +1 -0
  90. package/dist/mcp-server/tools/scan-content.js +18 -0
  91. package/dist/mcp-server/tools/scan-content.js.map +1 -0
  92. package/dist/mcp-server/tools/scan-file.d.ts +4 -0
  93. package/dist/mcp-server/tools/scan-file.d.ts.map +1 -0
  94. package/dist/mcp-server/tools/scan-file.js +48 -0
  95. package/dist/mcp-server/tools/scan-file.js.map +1 -0
  96. package/dist/mcp-server/types.d.ts +15 -0
  97. package/dist/mcp-server/types.d.ts.map +1 -0
  98. package/dist/mcp-server/types.js +2 -0
  99. package/dist/mcp-server/types.js.map +1 -0
  100. package/dist/reporter/audit-report.d.ts +4 -0
  101. package/dist/reporter/audit-report.d.ts.map +1 -0
  102. package/dist/reporter/audit-report.js +186 -0
  103. package/dist/reporter/audit-report.js.map +1 -0
  104. package/dist/reporter/json-report.d.ts +3 -0
  105. package/dist/reporter/json-report.d.ts.map +1 -0
  106. package/dist/reporter/json-report.js +4 -0
  107. package/dist/reporter/json-report.js.map +1 -0
  108. package/dist/reporter/remediation-text.d.ts +3 -0
  109. package/dist/reporter/remediation-text.d.ts.map +1 -0
  110. package/dist/reporter/remediation-text.js +12 -0
  111. package/dist/reporter/remediation-text.js.map +1 -0
  112. package/dist/reporter/risk-scorer.d.ts +8 -0
  113. package/dist/reporter/risk-scorer.d.ts.map +1 -0
  114. package/dist/reporter/risk-scorer.js +40 -0
  115. package/dist/reporter/risk-scorer.js.map +1 -0
  116. package/dist/reporter/sarif-report.d.ts +3 -0
  117. package/dist/reporter/sarif-report.d.ts.map +1 -0
  118. package/dist/reporter/sarif-report.js +80 -0
  119. package/dist/reporter/sarif-report.js.map +1 -0
  120. package/dist/reporter/shared.d.ts +11 -0
  121. package/dist/reporter/shared.d.ts.map +1 -0
  122. package/dist/reporter/shared.js +85 -0
  123. package/dist/reporter/shared.js.map +1 -0
  124. package/dist/reporter/summary-generator.d.ts +16 -0
  125. package/dist/reporter/summary-generator.d.ts.map +1 -0
  126. package/dist/reporter/summary-generator.js +89 -0
  127. package/dist/reporter/summary-generator.js.map +1 -0
  128. package/dist/reporter/terminal-report.d.ts +4 -0
  129. package/dist/reporter/terminal-report.d.ts.map +1 -0
  130. package/dist/reporter/terminal-report.js +135 -0
  131. package/dist/reporter/terminal-report.js.map +1 -0
  132. package/dist/rules/crypto-rules.d.ts +3 -0
  133. package/dist/rules/crypto-rules.d.ts.map +1 -0
  134. package/dist/rules/crypto-rules.js +252 -0
  135. package/dist/rules/crypto-rules.js.map +1 -0
  136. package/dist/rules/default-rules.d.ts +9 -0
  137. package/dist/rules/default-rules.d.ts.map +1 -0
  138. package/dist/rules/default-rules.js +1319 -0
  139. package/dist/rules/default-rules.js.map +1 -0
  140. package/dist/rules/index.d.ts +7 -0
  141. package/dist/rules/index.d.ts.map +1 -0
  142. package/dist/rules/index.js +7 -0
  143. package/dist/rules/index.js.map +1 -0
  144. package/dist/rules/injection-rules.d.ts +8 -0
  145. package/dist/rules/injection-rules.d.ts.map +1 -0
  146. package/dist/rules/injection-rules.js +108 -0
  147. package/dist/rules/injection-rules.js.map +1 -0
  148. package/dist/rules/types.d.ts +52 -0
  149. package/dist/rules/types.d.ts.map +1 -0
  150. package/dist/rules/types.js +2 -0
  151. package/dist/rules/types.js.map +1 -0
  152. package/dist/scanner/filesystem-scanner.d.ts +26 -0
  153. package/dist/scanner/filesystem-scanner.d.ts.map +1 -0
  154. package/dist/scanner/filesystem-scanner.js +369 -0
  155. package/dist/scanner/filesystem-scanner.js.map +1 -0
  156. package/dist/scanner/injection-scanner.d.ts +12 -0
  157. package/dist/scanner/injection-scanner.d.ts.map +1 -0
  158. package/dist/scanner/injection-scanner.js +136 -0
  159. package/dist/scanner/injection-scanner.js.map +1 -0
  160. package/dist/scanner/permission-checker.d.ts +4 -0
  161. package/dist/scanner/permission-checker.d.ts.map +1 -0
  162. package/dist/scanner/permission-checker.js +37 -0
  163. package/dist/scanner/permission-checker.js.map +1 -0
  164. package/dist/scanner/redact.d.ts +3 -0
  165. package/dist/scanner/redact.d.ts.map +1 -0
  166. package/dist/scanner/redact.js +17 -0
  167. package/dist/scanner/redact.js.map +1 -0
  168. package/dist/scanner/rule-engine.d.ts +9 -0
  169. package/dist/scanner/rule-engine.d.ts.map +1 -0
  170. package/dist/scanner/rule-engine.js +129 -0
  171. package/dist/scanner/rule-engine.js.map +1 -0
  172. package/dist/scanner/system-targets.d.ts +17 -0
  173. package/dist/scanner/system-targets.d.ts.map +1 -0
  174. package/dist/scanner/system-targets.js +81 -0
  175. package/dist/scanner/system-targets.js.map +1 -0
  176. package/dist/tui/App.d.ts +6 -0
  177. package/dist/tui/App.d.ts.map +1 -0
  178. package/dist/tui/App.js +224 -0
  179. package/dist/tui/App.js.map +1 -0
  180. package/dist/tui/components/BootSequence.d.ts +6 -0
  181. package/dist/tui/components/BootSequence.d.ts.map +1 -0
  182. package/dist/tui/components/BootSequence.js +40 -0
  183. package/dist/tui/components/BootSequence.js.map +1 -0
  184. package/dist/tui/components/BorderedSection.d.ts +12 -0
  185. package/dist/tui/components/BorderedSection.d.ts.map +1 -0
  186. package/dist/tui/components/BorderedSection.js +7 -0
  187. package/dist/tui/components/BorderedSection.js.map +1 -0
  188. package/dist/tui/components/ErrorBoundary.d.ts +18 -0
  189. package/dist/tui/components/ErrorBoundary.d.ts.map +1 -0
  190. package/dist/tui/components/ErrorBoundary.js +36 -0
  191. package/dist/tui/components/ErrorBoundary.js.map +1 -0
  192. package/dist/tui/components/FirstUseHint.d.ts +7 -0
  193. package/dist/tui/components/FirstUseHint.d.ts.map +1 -0
  194. package/dist/tui/components/FirstUseHint.js +20 -0
  195. package/dist/tui/components/FirstUseHint.js.map +1 -0
  196. package/dist/tui/components/Footer.d.ts +10 -0
  197. package/dist/tui/components/Footer.d.ts.map +1 -0
  198. package/dist/tui/components/Footer.js +51 -0
  199. package/dist/tui/components/Footer.js.map +1 -0
  200. package/dist/tui/components/MetricCard.d.ts +11 -0
  201. package/dist/tui/components/MetricCard.d.ts.map +1 -0
  202. package/dist/tui/components/MetricCard.js +8 -0
  203. package/dist/tui/components/MetricCard.js.map +1 -0
  204. package/dist/tui/components/Panel.d.ts +15 -0
  205. package/dist/tui/components/Panel.d.ts.map +1 -0
  206. package/dist/tui/components/Panel.js +25 -0
  207. package/dist/tui/components/Panel.js.map +1 -0
  208. package/dist/tui/components/RemediationMenu.d.ts +10 -0
  209. package/dist/tui/components/RemediationMenu.d.ts.map +1 -0
  210. package/dist/tui/components/RemediationMenu.js +84 -0
  211. package/dist/tui/components/RemediationMenu.js.map +1 -0
  212. package/dist/tui/components/RiskGauge.d.ts +7 -0
  213. package/dist/tui/components/RiskGauge.d.ts.map +1 -0
  214. package/dist/tui/components/RiskGauge.js +55 -0
  215. package/dist/tui/components/RiskGauge.js.map +1 -0
  216. package/dist/tui/components/ScrollableList.d.ts +11 -0
  217. package/dist/tui/components/ScrollableList.d.ts.map +1 -0
  218. package/dist/tui/components/ScrollableList.js +14 -0
  219. package/dist/tui/components/ScrollableList.js.map +1 -0
  220. package/dist/tui/components/Section.d.ts +9 -0
  221. package/dist/tui/components/Section.d.ts.map +1 -0
  222. package/dist/tui/components/Section.js +7 -0
  223. package/dist/tui/components/Section.js.map +1 -0
  224. package/dist/tui/components/SectionHeader.d.ts +8 -0
  225. package/dist/tui/components/SectionHeader.d.ts.map +1 -0
  226. package/dist/tui/components/SectionHeader.js +15 -0
  227. package/dist/tui/components/SectionHeader.js.map +1 -0
  228. package/dist/tui/components/SeverityBadge.d.ts +5 -0
  229. package/dist/tui/components/SeverityBadge.d.ts.map +1 -0
  230. package/dist/tui/components/SeverityBadge.js +7 -0
  231. package/dist/tui/components/SeverityBadge.js.map +1 -0
  232. package/dist/tui/components/Sidebar.d.ts +2 -0
  233. package/dist/tui/components/Sidebar.d.ts.map +1 -0
  234. package/dist/tui/components/Sidebar.js +40 -0
  235. package/dist/tui/components/Sidebar.js.map +1 -0
  236. package/dist/tui/components/StatusIndicator.d.ts +8 -0
  237. package/dist/tui/components/StatusIndicator.d.ts.map +1 -0
  238. package/dist/tui/components/StatusIndicator.js +15 -0
  239. package/dist/tui/components/StatusIndicator.js.map +1 -0
  240. package/dist/tui/components/Table.d.ts +21 -0
  241. package/dist/tui/components/Table.d.ts.map +1 -0
  242. package/dist/tui/components/Table.js +38 -0
  243. package/dist/tui/components/Table.js.map +1 -0
  244. package/dist/tui/components/Transition.d.ts +8 -0
  245. package/dist/tui/components/Transition.d.ts.map +1 -0
  246. package/dist/tui/components/Transition.js +38 -0
  247. package/dist/tui/components/Transition.js.map +1 -0
  248. package/dist/tui/components/WelcomeScreen.d.ts +6 -0
  249. package/dist/tui/components/WelcomeScreen.d.ts.map +1 -0
  250. package/dist/tui/components/WelcomeScreen.js +14 -0
  251. package/dist/tui/components/WelcomeScreen.js.map +1 -0
  252. package/dist/tui/educational.d.ts +32 -0
  253. package/dist/tui/educational.d.ts.map +1 -0
  254. package/dist/tui/educational.js +117 -0
  255. package/dist/tui/educational.js.map +1 -0
  256. package/dist/tui/hooks/useAudit.d.ts +24 -0
  257. package/dist/tui/hooks/useAudit.d.ts.map +1 -0
  258. package/dist/tui/hooks/useAudit.js +263 -0
  259. package/dist/tui/hooks/useAudit.js.map +1 -0
  260. package/dist/tui/hooks/useConfig.d.ts +18 -0
  261. package/dist/tui/hooks/useConfig.d.ts.map +1 -0
  262. package/dist/tui/hooks/useConfig.js +85 -0
  263. package/dist/tui/hooks/useConfig.js.map +1 -0
  264. package/dist/tui/hooks/useHookStatus.d.ts +10 -0
  265. package/dist/tui/hooks/useHookStatus.d.ts.map +1 -0
  266. package/dist/tui/hooks/useHookStatus.js +59 -0
  267. package/dist/tui/hooks/useHookStatus.js.map +1 -0
  268. package/dist/tui/hooks/useLogs.d.ts +42 -0
  269. package/dist/tui/hooks/useLogs.d.ts.map +1 -0
  270. package/dist/tui/hooks/useLogs.js +105 -0
  271. package/dist/tui/hooks/useLogs.js.map +1 -0
  272. package/dist/tui/hooks/useScan.d.ts +39 -0
  273. package/dist/tui/hooks/useScan.d.ts.map +1 -0
  274. package/dist/tui/hooks/useScan.js +255 -0
  275. package/dist/tui/hooks/useScan.js.map +1 -0
  276. package/dist/tui/hooks/useTerminalSize.d.ts +10 -0
  277. package/dist/tui/hooks/useTerminalSize.d.ts.map +1 -0
  278. package/dist/tui/hooks/useTerminalSize.js +27 -0
  279. package/dist/tui/hooks/useTerminalSize.js.map +1 -0
  280. package/dist/tui/index.d.ts +2 -0
  281. package/dist/tui/index.d.ts.map +1 -0
  282. package/dist/tui/index.js +8 -0
  283. package/dist/tui/index.js.map +1 -0
  284. package/dist/tui/screens/AuditPanel.d.ts +7 -0
  285. package/dist/tui/screens/AuditPanel.d.ts.map +1 -0
  286. package/dist/tui/screens/AuditPanel.js +467 -0
  287. package/dist/tui/screens/AuditPanel.js.map +1 -0
  288. package/dist/tui/screens/LogsPanel.d.ts +2 -0
  289. package/dist/tui/screens/LogsPanel.d.ts.map +1 -0
  290. package/dist/tui/screens/LogsPanel.js +127 -0
  291. package/dist/tui/screens/LogsPanel.js.map +1 -0
  292. package/dist/tui/screens/OverviewPanel.d.ts +2 -0
  293. package/dist/tui/screens/OverviewPanel.d.ts.map +1 -0
  294. package/dist/tui/screens/OverviewPanel.js +84 -0
  295. package/dist/tui/screens/OverviewPanel.js.map +1 -0
  296. package/dist/tui/screens/ScanPanel.d.ts +2 -0
  297. package/dist/tui/screens/ScanPanel.d.ts.map +1 -0
  298. package/dist/tui/screens/ScanPanel.js +188 -0
  299. package/dist/tui/screens/ScanPanel.js.map +1 -0
  300. package/dist/tui/screens/ScanResultsPanel.d.ts +2 -0
  301. package/dist/tui/screens/ScanResultsPanel.d.ts.map +1 -0
  302. package/dist/tui/screens/ScanResultsPanel.js +394 -0
  303. package/dist/tui/screens/ScanResultsPanel.js.map +1 -0
  304. package/dist/tui/screens/SettingsPanel.d.ts +2 -0
  305. package/dist/tui/screens/SettingsPanel.d.ts.map +1 -0
  306. package/dist/tui/screens/SettingsPanel.js +353 -0
  307. package/dist/tui/screens/SettingsPanel.js.map +1 -0
  308. package/dist/tui/state.d.ts +35 -0
  309. package/dist/tui/state.d.ts.map +1 -0
  310. package/dist/tui/state.js +13 -0
  311. package/dist/tui/state.js.map +1 -0
  312. package/dist/tui/theme.d.ts +58 -0
  313. package/dist/tui/theme.d.ts.map +1 -0
  314. package/dist/tui/theme.js +80 -0
  315. package/dist/tui/theme.js.map +1 -0
  316. package/dist/version.d.ts +2 -0
  317. package/dist/version.d.ts.map +1 -0
  318. package/dist/version.js +5 -0
  319. package/dist/version.js.map +1 -0
  320. package/hooks/audit-logger.sh +74 -0
  321. package/hooks/detection-lib.sh +301 -0
  322. package/hooks/git-pre-commit.sh +195 -0
  323. package/hooks/git-pre-push.sh +125 -0
  324. package/hooks/git-safety.sh +152 -0
  325. package/hooks/security-scanner.sh +527 -0
  326. package/install.sh +543 -0
  327. package/package.json +67 -0
  328. package/patterns/credentials.yaml +317 -0
  329. package/patterns/dangerous-commands.yaml +167 -0
  330. package/patterns/pii.yaml +95 -0
  331. package/patterns/prompt-injection.yaml +131 -0
  332. package/patterns/supply-chain.yaml +119 -0
  333. package/rules/AGENTS.md +60 -0
  334. package/rules/SECURITY-RULES.md +177 -0
  335. package/rules/claude.md +9 -0
  336. package/rules/clinerules +29 -0
  337. package/rules/continuerules +29 -0
  338. package/rules/copilot-instructions.md +9 -0
  339. package/rules/cursor-security.mdc +14 -0
  340. package/rules/gemini.md +9 -0
  341. package/rules/kiro-security.md +29 -0
  342. package/rules/roocode-security.md +29 -0
  343. package/rules/trae-security.md +29 -0
  344. package/rules/windsurfrules +9 -0
  345. package/skill/llm-antivirus/SKILL.md +73 -0
  346. package/skill/llm-antivirus/references/threat-patterns.yaml +82 -0
  347. package/skill/llm-antivirus/scripts/security-audit.sh +244 -0
  348. package/uninstall.sh +215 -0
@@ -0,0 +1,29 @@
1
+ # Security Rules — Trae IDE
2
+
3
+ These rules are enforced by ChainWall and apply to all Trae IDE operations.
4
+
5
+ ## NEVER
6
+
7
+ - Write credentials, API keys, tokens, or passwords in code or commands
8
+ - Access .env, credentials.json, secrets.json, SSH keys, .npmrc, or .pypirc
9
+ - Run rm -rf, mkfs, dd to devices, chmod 777, or redirect to block devices
10
+ - Pipe downloads to shell (curl|bash, wget|sh)
11
+ - Expose SSNs, credit card numbers, or other PII in outputs
12
+ - Write PEM private keys (RSA, DSA, EC, OpenSSH, PGP) to any file
13
+ - Force-push to main/master or hard-reset shared branches
14
+ - Install packages from arbitrary URLs or override registries
15
+
16
+ ## ALWAYS
17
+
18
+ - Use environment variables for secrets
19
+ - Validate inputs at system boundaries
20
+ - Use parameterized queries — never concatenate user input into SQL or shell
21
+ - Pin dependency versions and preserve lock files
22
+ - Check file paths to prevent path traversal
23
+ - Use HTTPS for API calls and package downloads
24
+
25
+ ## Configuration
26
+
27
+ Override: ~/.llm-av/config.json (global), .llm-av/config.json (project)
28
+ Bypass: LLMAV_SKIP=1 (logged)
29
+ Audit: .llm-av/audit.jsonl
@@ -0,0 +1,9 @@
1
+ # Windsurf Security Rules
2
+
3
+ This project uses ChainWall for security enforcement.
4
+
5
+ Read and follow ALL rules in AGENTS.md (in the project root)
6
+ before performing any file operations, shell commands, or code generation.
7
+
8
+ Do not write credentials, access sensitive files, run destructive commands,
9
+ or expose PII. See AGENTS.md for the complete rule set.
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: llm-antivirus
3
+ description: Security auditing skill for AI coding agents — scans for credentials, dangerous commands, PII, and prompt injection
4
+ version: 2.0.0
5
+ author: Laurenz
6
+ tags: [security, audit, credentials, pii, owasp]
7
+ ---
8
+
9
+ # ChainWall Security Skill
10
+
11
+ You are a security auditing assistant. When invoked, perform a comprehensive
12
+ security scan of the project using the patterns and scripts provided.
13
+
14
+ ## Quick Reference
15
+
16
+ **What this skill does:**
17
+ - Scans project files for leaked credentials, API keys, and tokens
18
+ - Detects dangerous shell commands in scripts and configs
19
+ - Identifies PII (SSN, credit cards, medical records)
20
+ - Checks for prompt injection patterns in AI-facing files
21
+ - Validates .gitignore for sensitive file exclusions
22
+ - Reports findings with severity levels and remediation guidance
23
+
24
+ ## How to Use
25
+
26
+ Run the security audit script:
27
+ ```bash
28
+ ./skill/llm-antivirus/scripts/security-audit.sh
29
+ ```
30
+
31
+ Or perform a targeted scan:
32
+ ```bash
33
+ # Scan specific directory
34
+ ./skill/llm-antivirus/scripts/security-audit.sh src/
35
+
36
+ # Scan specific file
37
+ ./skill/llm-antivirus/scripts/security-audit.sh path/to/file.ts
38
+ ```
39
+
40
+ ## Detection Categories
41
+
42
+ | Category | Severity | Patterns |
43
+ |----------|----------|----------|
44
+ | Credentials | Critical/High | 55 patterns (AWS, GitHub, OpenAI, etc.) |
45
+ | Dangerous Commands | Critical/High | 26 patterns (rm -rf, curl\|bash, etc.) |
46
+ | PII | Critical/High | 15 patterns (SSN, credit card, medical) |
47
+ | Prompt Injection | Medium | 18 patterns (jailbreak, role confusion) |
48
+ | Supply Chain | High/Medium | 16 patterns (typosquatting, lock files) |
49
+
50
+ ## When to Invoke This Skill
51
+
52
+ - Before committing code to a repository
53
+ - When reviewing pull requests for security issues
54
+ - After adding new dependencies or configuration files
55
+ - When onboarding a new project to verify security posture
56
+ - Periodically as part of security maintenance
57
+
58
+ ## Pattern Reference
59
+
60
+ See `patterns/*.yaml` in the repository root for the complete pattern database
61
+ with regex expressions, severity levels, and descriptions.
62
+
63
+ ## OWASP LLM Top 10 Coverage
64
+
65
+ | ID | Vulnerability | Covered |
66
+ |----|---------------|---------|
67
+ | LLM01 | Prompt Injection | Yes — Layer 6 |
68
+ | LLM02 | Insecure Output | Yes — Layers 2-3, 5 |
69
+ | LLM06 | Sensitive Info Disclosure | Yes — Layers 1-3, 5 |
70
+ | LLM07 | System Prompt Leakage | Yes — Layer 6 |
71
+ | LLM08 | Excessive Agency | Yes — Layer 4 |
72
+ | LLM09 | Overreliance | Partial — instruction files |
73
+ | LLM10 | Model Supply Chain | Yes — supply-chain patterns |
@@ -0,0 +1,82 @@
1
+ # ChainWall — Threat Pattern Reference for Skill
2
+ #
3
+ # Consolidated pattern reference used by the security audit skill.
4
+ # This file provides a high-level summary; full patterns are in /patterns/*.yaml.
5
+
6
+ categories:
7
+
8
+ credentials:
9
+ count: 55
10
+ source: patterns/credentials.yaml
11
+ providers:
12
+ - AWS (Access Key, Secret, Session Token)
13
+ - GCP/Google (API Key, Service Account, OAuth Secret)
14
+ - Azure (Storage Key, AD Secret, Connection String)
15
+ - GitHub (PAT classic, fine-grained, OAuth, App, Refresh)
16
+ - GitLab (PAT, Pipeline, Runner)
17
+ - Slack (Bot/User Token, Webhook URL)
18
+ - Stripe (Secret Key, Restricted Key, Webhook Secret)
19
+ - OpenAI (API Key, Project Key)
20
+ - Anthropic (API Key)
21
+ - Twilio (API Key, Account SID)
22
+ - SendGrid (API Key)
23
+ - Supabase (Service Role, Anon Key)
24
+ - Firebase (Server Key)
25
+ - Databricks (Access Token)
26
+ - npm (Access Token)
27
+ - PyPI (API Token)
28
+ - Docker Hub (Access Token)
29
+ - Hashicorp Vault (Service Token, Batch Token)
30
+ - Datadog (API Key)
31
+ - Mailgun (API Key)
32
+ - Heroku (API Key)
33
+ - Shopify (Access Token, Custom App, Private App)
34
+ - Linear (API Key)
35
+ - Vercel (Access Token)
36
+ - JWT, Bearer, SSH/PGP keys
37
+ - Generic (API key assignments, passwords, private key vars)
38
+
39
+ dangerous_commands:
40
+ count: 24
41
+ source: patterns/dangerous-commands.yaml
42
+ categories:
43
+ - Destructive (rm -rf, shred)
44
+ - Remote Code Execution (curl|bash, eval, base64 decode)
45
+ - Permissions (chmod 777, SUID)
46
+ - Disk/Device (dd, mkfs, device write)
47
+ - Network Exfiltration (netcat, reverse shell, SSH tunnel)
48
+ - System Modification (crontab, hosts, sudoers, systemd)
49
+ - Container Escape (Docker socket, privileged)
50
+ - Environment (LD_PRELOAD, PATH manipulation)
51
+ - Anti-forensics (history deletion, log tampering)
52
+
53
+ pii:
54
+ count: 15
55
+ source: patterns/pii.yaml
56
+ types:
57
+ - Government IDs (SSN, EIN)
58
+ - Financial (credit card, bank account, routing, IBAN)
59
+ - Personal Contact (email/phone in PII context)
60
+ - Medical (MRN, DEA number)
61
+ - Identity Documents (passport, driver license, DOB)
62
+
63
+ prompt_injection:
64
+ count: 18
65
+ source: patterns/prompt-injection.yaml
66
+ vectors:
67
+ - Instruction Override (ignore previous, disregard, forget)
68
+ - Role Confusion (authority claims, admin override)
69
+ - System Prompt Extraction (reveal, show, reflect)
70
+ - Jailbreak (DAN, developer mode, no restrictions)
71
+ - Encoded Injection (base64, code blocks)
72
+ - Output Manipulation (suppress, format attacks)
73
+
74
+ supply_chain:
75
+ count: 17
76
+ source: patterns/supply-chain.yaml
77
+ vectors:
78
+ - Package Installation (pip from URL, registry override)
79
+ - Post-Install Scripts (curl in lifecycle, eval)
80
+ - Dependency Manipulation (git deps, private registry)
81
+ - Lock File (deletion, checkout)
82
+ - Container Image (untagged, unknown registry)
@@ -0,0 +1,244 @@
1
+ #!/bin/bash
2
+ #
3
+ # ChainWall — Security Audit Script
4
+ # Full project security scan using pattern databases
5
+ #
6
+ # Usage:
7
+ # ./security-audit.sh # Scan entire project
8
+ # ./security-audit.sh src/ # Scan specific directory
9
+ # ./security-audit.sh file.ts # Scan specific file
10
+ #
11
+ # Exit codes:
12
+ # 0 = No findings
13
+ # 1 = Findings detected
14
+ #
15
+ # Dependencies: bash 3.2+, grep
16
+ #
17
+
18
+ set -o pipefail
19
+
20
+ # ═══════════════════════════════════════════════════════════════════════
21
+ # Configuration
22
+ # ═══════════════════════════════════════════════════════════════════════
23
+
24
+ # Resolve script and repo root
25
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
26
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
27
+ PATTERNS_DIR="${REPO_ROOT}/patterns"
28
+
29
+ # Colors
30
+ RED_BOLD=$'\e[1;31m'
31
+ RED=$'\e[31m'
32
+ YELLOW=$'\e[33m'
33
+ GREEN=$'\e[32m'
34
+ CYAN=$'\e[36m'
35
+ BOLD=$'\e[1m'
36
+ RESET=$'\e[0m'
37
+
38
+ # Scan target (default: current directory)
39
+ SCAN_TARGET="${1:-.}"
40
+
41
+ # Counters
42
+ CRITICAL_COUNT=0
43
+ HIGH_COUNT=0
44
+ MEDIUM_COUNT=0
45
+ LOW_COUNT=0
46
+ FILES_SCANNED=0
47
+
48
+ # ═══════════════════════════════════════════════════════════════════════
49
+ # Pattern Loading
50
+ # ═══════════════════════════════════════════════════════════════════════
51
+
52
+ # Extract regex patterns from a YAML file
53
+ # Returns one pattern per line
54
+ extract_patterns() {
55
+ local yaml_file="$1"
56
+ [[ ! -f "$yaml_file" ]] && return
57
+ grep '^\s*regex:' "$yaml_file" 2>/dev/null \
58
+ | sed 's/.*regex: *"//' \
59
+ | sed 's/"$//'
60
+ }
61
+
62
+ # Extract pattern names from a YAML file
63
+ extract_names() {
64
+ local yaml_file="$1"
65
+ [[ ! -f "$yaml_file" ]] && return
66
+ grep '^\s*- name:' "$yaml_file" 2>/dev/null \
67
+ | sed 's/.*- name: *//'
68
+ }
69
+
70
+ # ═══════════════════════════════════════════════════════════════════════
71
+ # Scanning Functions
72
+ # ═══════════════════════════════════════════════════════════════════════
73
+
74
+ scan_with_patterns() {
75
+ local yaml_file="$1"
76
+ local category="$2"
77
+ local severity="$3"
78
+
79
+ [[ ! -f "$yaml_file" ]] && return
80
+
81
+ # Read patterns and names into arrays
82
+ local patterns=()
83
+ local names=()
84
+ while IFS= read -r line; do
85
+ patterns+=("$line")
86
+ done < <(extract_patterns "$yaml_file")
87
+
88
+ while IFS= read -r line; do
89
+ names+=("$line")
90
+ done < <(extract_names "$yaml_file")
91
+
92
+ local idx=0
93
+ for pattern in "${patterns[@]}"; do
94
+ local name="${names[$idx]:-Pattern $idx}"
95
+ idx=$((idx + 1))
96
+
97
+ # Skip patterns with (?i) — grep -E doesn't support inline flags
98
+ # Use -i flag instead for case-insensitive patterns
99
+ local grep_flags="-rn"
100
+ local clean_pattern="$pattern"
101
+ if [[ "$pattern" == "(?i)"* ]]; then
102
+ grep_flags="-rni"
103
+ clean_pattern="${pattern#\(\?i\)}"
104
+ fi
105
+
106
+ # Run grep and collect results
107
+ local all_results
108
+ all_results=$(grep $grep_flags -E "$clean_pattern" "$SCAN_TARGET" \
109
+ --include='*.ts' --include='*.js' --include='*.py' --include='*.rb' \
110
+ --include='*.go' --include='*.rs' --include='*.java' --include='*.sh' \
111
+ --include='*.yaml' --include='*.yml' --include='*.json' --include='*.toml' \
112
+ --include='*.env' --include='*.env.*' --include='*.cfg' --include='*.ini' \
113
+ --include='*.conf' --include='*.config' --include='*.xml' --include='*.md' \
114
+ --exclude-dir='.git' --exclude-dir='node_modules' --exclude-dir='.llm-av' \
115
+ --exclude-dir='dist' --exclude-dir='build' --exclude-dir='__pycache__' \
116
+ --exclude-dir='tests' --exclude-dir='test' --exclude-dir='fixtures' \
117
+ --exclude='*.test.*' --exclude='*.spec.*' --exclude='security-audit.sh' \
118
+ 2>/dev/null)
119
+ local results
120
+ results=$(echo "$all_results" | head -20)
121
+
122
+ if [[ -n "$results" ]]; then
123
+ local match_count
124
+ match_count=$(echo "$all_results" | wc -l | tr -d ' ')
125
+
126
+ # Set color based on severity
127
+ local color="$YELLOW"
128
+ case "$severity" in
129
+ critical) color="$RED_BOLD"; CRITICAL_COUNT=$((CRITICAL_COUNT + match_count)) ;;
130
+ high) color="$RED"; HIGH_COUNT=$((HIGH_COUNT + match_count)) ;;
131
+ medium) color="$YELLOW"; MEDIUM_COUNT=$((MEDIUM_COUNT + match_count)) ;;
132
+ low) color="$CYAN"; LOW_COUNT=$((LOW_COUNT + match_count)) ;;
133
+ esac
134
+
135
+ local severity_upper
136
+ severity_upper=$(echo "$severity" | tr '[:lower:]' '[:upper:]')
137
+ echo -e "\n${color}[${severity_upper}] ${name}${RESET}"
138
+ echo -e "${color}Pattern: ${clean_pattern}${RESET}"
139
+ echo "$results" | while IFS= read -r line; do
140
+ echo -e " ${line}"
141
+ done
142
+ if [[ "$match_count" -gt 20 ]]; then
143
+ echo -e " ... and $((match_count - 20)) more matches"
144
+ fi
145
+ fi
146
+ done
147
+ }
148
+
149
+ # ═══════════════════════════════════════════════════════════════════════
150
+ # .gitignore Check
151
+ # ═══════════════════════════════════════════════════════════════════════
152
+
153
+ check_gitignore() {
154
+ echo -e "\n${BOLD}=== .gitignore Check ===${RESET}"
155
+
156
+ if [[ ! -f ".gitignore" ]]; then
157
+ echo -e "${RED_BOLD}[CRITICAL] No .gitignore found${RESET}"
158
+ echo -e " Create a .gitignore to prevent committing sensitive files"
159
+ CRITICAL_COUNT=$((CRITICAL_COUNT + 1))
160
+ return
161
+ fi
162
+
163
+ local missing=()
164
+ for pattern in ".env" "*.pem" "id_rsa" ".npmrc" ".pypirc"; do
165
+ if ! grep -q "$pattern" .gitignore 2>/dev/null; then
166
+ missing+=("$pattern")
167
+ fi
168
+ done
169
+
170
+ if [[ ${#missing[@]} -gt 0 ]]; then
171
+ echo -e "${YELLOW}[MEDIUM] .gitignore missing sensitive patterns:${RESET}"
172
+ for m in "${missing[@]}"; do
173
+ echo -e " - $m"
174
+ MEDIUM_COUNT=$((MEDIUM_COUNT + 1))
175
+ done
176
+ else
177
+ echo -e "${GREEN} .gitignore includes standard sensitive patterns${RESET}"
178
+ fi
179
+ }
180
+
181
+ # ═══════════════════════════════════════════════════════════════════════
182
+ # Main
183
+ # ═══════════════════════════════════════════════════════════════════════
184
+
185
+ echo -e "${BOLD}╔══════════════════════════════════════════════╗${RESET}"
186
+ echo -e "${BOLD}║ ChainWall — Security Audit v2.0 ║${RESET}"
187
+ echo -e "${BOLD}╚══════════════════════════════════════════════╝${RESET}"
188
+ echo -e "Scanning: ${CYAN}${SCAN_TARGET}${RESET}"
189
+ echo -e "Patterns: ${CYAN}${PATTERNS_DIR}${RESET}"
190
+ echo ""
191
+
192
+ # Count files to scan
193
+ if [[ -d "$SCAN_TARGET" ]]; then
194
+ FILES_SCANNED=$(find "$SCAN_TARGET" -type f \
195
+ \( -name '*.ts' -o -name '*.js' -o -name '*.py' -o -name '*.sh' \
196
+ -o -name '*.yaml' -o -name '*.yml' -o -name '*.json' -o -name '*.env' \
197
+ -o -name '*.go' -o -name '*.rs' -o -name '*.java' \) \
198
+ -not -path '*/.git/*' -not -path '*/node_modules/*' \
199
+ -not -path '*/dist/*' -not -path '*/.llm-av/*' \
200
+ 2>/dev/null | wc -l | tr -d ' ')
201
+ elif [[ -f "$SCAN_TARGET" ]]; then
202
+ FILES_SCANNED=1
203
+ fi
204
+ echo -e "Files: ${CYAN}${FILES_SCANNED}${RESET}"
205
+
206
+ # Run scans
207
+ echo -e "\n${BOLD}=== Credential Scan ===${RESET}"
208
+ scan_with_patterns "$PATTERNS_DIR/credentials.yaml" "credentials" "critical"
209
+
210
+ echo -e "\n${BOLD}=== Dangerous Command Scan ===${RESET}"
211
+ scan_with_patterns "$PATTERNS_DIR/dangerous-commands.yaml" "commands" "high"
212
+
213
+ echo -e "\n${BOLD}=== PII Scan ===${RESET}"
214
+ scan_with_patterns "$PATTERNS_DIR/pii.yaml" "pii" "high"
215
+
216
+ echo -e "\n${BOLD}=== Prompt Injection Scan ===${RESET}"
217
+ scan_with_patterns "$PATTERNS_DIR/prompt-injection.yaml" "injection" "medium"
218
+
219
+ echo -e "\n${BOLD}=== Supply Chain Scan ===${RESET}"
220
+ scan_with_patterns "$PATTERNS_DIR/supply-chain.yaml" "supply_chain" "medium"
221
+
222
+ # .gitignore check
223
+ check_gitignore
224
+
225
+ # ═══════════════════════════════════════════════════════════════════════
226
+ # Summary
227
+ # ═══════════════════════════════════════════════════════════════════════
228
+
229
+ TOTAL=$((CRITICAL_COUNT + HIGH_COUNT + MEDIUM_COUNT + LOW_COUNT))
230
+
231
+ echo -e "\n${BOLD}=== Summary ===${RESET}"
232
+ echo -e " Critical: ${RED_BOLD}${CRITICAL_COUNT}${RESET}"
233
+ echo -e " High: ${RED}${HIGH_COUNT}${RESET}"
234
+ echo -e " Medium: ${YELLOW}${MEDIUM_COUNT}${RESET}"
235
+ echo -e " Low: ${CYAN}${LOW_COUNT}${RESET}"
236
+ echo -e " ${BOLD}Total: ${TOTAL}${RESET}"
237
+
238
+ if [[ "$TOTAL" -eq 0 ]]; then
239
+ echo -e "\n${GREEN}No security findings detected.${RESET}"
240
+ exit 0
241
+ else
242
+ echo -e "\n${YELLOW}Review findings above and remediate before committing.${RESET}"
243
+ exit 1
244
+ fi
package/uninstall.sh ADDED
@@ -0,0 +1,215 @@
1
+ #!/bin/bash
2
+ #
3
+ # ChainWall — Uninstaller
4
+ #
5
+ # Removes ChainWall components from a project.
6
+ # Non-destructive: only removes what was installed, preserves user files.
7
+ #
8
+ # Usage:
9
+ # ./uninstall.sh # Uninstall from current directory
10
+ # ./uninstall.sh /path/to/project # Uninstall from specific project
11
+ #
12
+ # Requirements: bash 3.2+, jq
13
+ #
14
+
15
+ set -euo pipefail
16
+
17
+ # ═══════════════════════════════════════════════════════════════════════
18
+ # Configuration
19
+ # ═══════════════════════════════════════════════════════════════════════
20
+
21
+ PROJECT_DIR="${1:-$(pwd)}"
22
+
23
+ # Colors
24
+ RED=$'\e[31m'
25
+ GREEN=$'\e[32m'
26
+ YELLOW=$'\e[33m'
27
+ CYAN=$'\e[36m'
28
+ BOLD=$'\e[1m'
29
+ RESET=$'\e[0m'
30
+
31
+ REMOVED=()
32
+ SKIPPED=()
33
+
34
+ # ═══════════════════════════════════════════════════════════════════════
35
+ # Helpers
36
+ # ═══════════════════════════════════════════════════════════════════════
37
+
38
+ info() { echo -e "${CYAN}[info]${RESET} $1"; }
39
+ ok() { echo -e "${GREEN}[removed]${RESET} $1"; REMOVED+=("$1"); }
40
+ skip() { echo -e "${YELLOW}[skip]${RESET} $1"; SKIPPED+=("$1"); }
41
+
42
+ remove_file() {
43
+ local path="$1"
44
+ local label="$2"
45
+
46
+ if [[ -f "$path" ]]; then
47
+ rm "$path"
48
+ ok "$label"
49
+ else
50
+ skip "$label (not found)"
51
+ fi
52
+ }
53
+
54
+ remove_dir() {
55
+ local path="$1"
56
+ local label="$2"
57
+
58
+ if [[ -d "$path" ]]; then
59
+ rm -rf "$path"
60
+ ok "$label"
61
+ else
62
+ skip "$label (not found)"
63
+ fi
64
+ }
65
+
66
+ # ═══════════════════════════════════════════════════════════════════════
67
+ # Uninstallation
68
+ # ═══════════════════════════════════════════════════════════════════════
69
+
70
+ echo -e "${BOLD}╔══════════════════════════════════════════════╗${RESET}"
71
+ echo -e "${BOLD}║ ChainWall — Uninstaller ║${RESET}"
72
+ echo -e "${BOLD}╚══════════════════════════════════════════════╝${RESET}"
73
+ echo ""
74
+ info "Project: ${PROJECT_DIR}"
75
+ echo ""
76
+
77
+ # ─── Remove Claude Code hooks from settings.local.json ─────────────────
78
+ SETTINGS_FILE="${PROJECT_DIR}/.claude/settings.local.json"
79
+ if [[ -f "$SETTINGS_FILE" ]] && command -v jq &> /dev/null; then
80
+ if jq -e '.hooks' "$SETTINGS_FILE" &>/dev/null; then
81
+ # Remove entries containing security-scanner.sh, git-safety.sh, or audit-logger.sh
82
+ UPDATED=$(jq '
83
+ .hooks.PreToolUse = [.hooks.PreToolUse[]? | select(.hooks | all(.command | contains("security-scanner.sh") | not) and all(.command | contains("git-safety.sh") | not))] |
84
+ .hooks.PostToolUse = [.hooks.PostToolUse[]? | select(.hooks | all(.command | contains("audit-logger.sh") | not))] |
85
+ if (.hooks.PreToolUse | length) == 0 and (.hooks.PostToolUse | length) == 0 then del(.hooks) else . end
86
+ ' "$SETTINGS_FILE")
87
+ echo "$UPDATED" | jq '.' > "${SETTINGS_FILE}.tmp.$$"
88
+ mv "${SETTINGS_FILE}.tmp.$$" "$SETTINGS_FILE"
89
+ ok "Claude Code hooks (settings.local.json)"
90
+ else
91
+ skip "Claude Code hooks (no hooks in settings)"
92
+ fi
93
+ else
94
+ skip "Claude Code hooks (settings.local.json not found)"
95
+ fi
96
+
97
+ # ─── Remove installed files ────────────────────────────────────────────
98
+ MANIFEST_FILE="${PROJECT_DIR}/.llm-av/manifest.txt"
99
+ if [[ -f "$MANIFEST_FILE" ]]; then
100
+ info "Using install manifest for safe removal"
101
+ while IFS= read -r entry; do
102
+ [[ -z "$entry" ]] && continue
103
+ if [[ -d "$entry" ]]; then
104
+ remove_dir "$entry" "$(basename "$entry") (from manifest)"
105
+ elif [[ -f "$entry" ]]; then
106
+ remove_file "$entry" "$(basename "$entry") (from manifest)"
107
+ else
108
+ skip "$(basename "$entry") (not found)"
109
+ fi
110
+ done < "$MANIFEST_FILE"
111
+ else
112
+ info "No install manifest found — using default file list"
113
+ fi
114
+
115
+ # Always attempt these removals (fallback for pre-manifest installs)
116
+ remove_file "${PROJECT_DIR}/AGENTS.md" "AGENTS.md"
117
+ remove_dir "${PROJECT_DIR}/.claude/skill/llm-antivirus" "Claude Code skill"
118
+ remove_file "${PROJECT_DIR}/.claude/commands/security-scan.md" "Claude Code /security-scan command"
119
+ remove_file "${PROJECT_DIR}/.cursor/rules/security.mdc" "Cursor security rules"
120
+ remove_file "${PROJECT_DIR}/.github/copilot-instructions.md" "Copilot instructions"
121
+
122
+ # Windsurf: only remove if we appended (check for our marker)
123
+ if [[ -f "${PROJECT_DIR}/.windsurfrules" ]]; then
124
+ if grep -q "ChainWall" "${PROJECT_DIR}/.windsurfrules" 2>/dev/null; then
125
+ # Try to remove only our appended section
126
+ # If the whole file is ours, remove it
127
+ FIRST_LINE=$(head -1 "${PROJECT_DIR}/.windsurfrules" 2>/dev/null)
128
+ if [[ "$FIRST_LINE" == *"Windsurf Security Rules"* ]]; then
129
+ rm "${PROJECT_DIR}/.windsurfrules"
130
+ ok "Windsurf security rules (.windsurfrules)"
131
+ else
132
+ info "Windsurf: .windsurfrules contains mixed content — manual cleanup needed"
133
+ SKIPPED+=("Windsurf rules (manual cleanup)")
134
+ fi
135
+ fi
136
+ fi
137
+
138
+ remove_file "${PROJECT_DIR}/GEMINI.md" "Gemini security rules"
139
+ remove_file "${PROJECT_DIR}/.clinerules" "Cline security rules"
140
+ remove_dir "${PROJECT_DIR}/.roo/rules" "RooCode security rules"
141
+ remove_file "${PROJECT_DIR}/.continuerules" "Continue.dev security rules"
142
+ remove_dir "${PROJECT_DIR}/.trae/rules" "Trae IDE security rules"
143
+ remove_dir "${PROJECT_DIR}/.kiro/rules" "Kiro security rules"
144
+ remove_file "${PROJECT_DIR}/.cursorrules" "Cursor fallback rules"
145
+ remove_file "${PROJECT_DIR}/.gemini/styleguide.md" "Gemini styleguide"
146
+
147
+ # ─── Remove git hooks ────────────────────────────────────────────────
148
+ if [[ -d "${PROJECT_DIR}/.git/hooks" ]]; then
149
+ for hook_name in pre-commit pre-push; do
150
+ hook_file="${PROJECT_DIR}/.git/hooks/${hook_name}"
151
+ if [[ -f "$hook_file" ]] && grep -q "ChainWall" "$hook_file" 2>/dev/null; then
152
+ if [[ -f "${hook_file}.existing" ]]; then
153
+ mv "${hook_file}.existing" "$hook_file"
154
+ ok "Git ${hook_name} hook (restored original)"
155
+ else
156
+ rm "$hook_file"
157
+ ok "Git ${hook_name} hook"
158
+ fi
159
+ fi
160
+ done
161
+ fi
162
+
163
+ # ─── Remove MCP server config ────────────────────────────────────────
164
+ if command -v jq &> /dev/null; then
165
+ CLAUDE_DESKTOP_CONFIG="${HOME}/Library/Application Support/Claude/claude_desktop_config.json"
166
+ if [[ -f "$CLAUDE_DESKTOP_CONFIG" ]] && jq -e '.mcpServers."llm-antivirus"' "$CLAUDE_DESKTOP_CONFIG" &>/dev/null; then
167
+ UPDATED=$(jq 'del(.mcpServers."llm-antivirus")' "$CLAUDE_DESKTOP_CONFIG")
168
+ echo "$UPDATED" | jq '.' > "${CLAUDE_DESKTOP_CONFIG}.tmp.$$"
169
+ mv "${CLAUDE_DESKTOP_CONFIG}.tmp.$$" "$CLAUDE_DESKTOP_CONFIG"
170
+ ok "MCP server config (Claude Desktop)"
171
+ fi
172
+
173
+ CURSOR_MCP_CONFIG="${HOME}/.cursor/mcp.json"
174
+ if [[ -f "$CURSOR_MCP_CONFIG" ]] && jq -e '.mcpServers."llm-antivirus"' "$CURSOR_MCP_CONFIG" &>/dev/null; then
175
+ UPDATED=$(jq 'del(.mcpServers."llm-antivirus")' "$CURSOR_MCP_CONFIG")
176
+ echo "$UPDATED" | jq '.' > "${CURSOR_MCP_CONFIG}.tmp.$$"
177
+ mv "${CURSOR_MCP_CONFIG}.tmp.$$" "$CURSOR_MCP_CONFIG"
178
+ ok "MCP server config (Cursor)"
179
+ fi
180
+ fi
181
+
182
+ # ─── Remove .llm-av directory ──────────────────────────────────────────
183
+ if [[ -d "${PROJECT_DIR}/.llm-av" ]]; then
184
+ echo ""
185
+ echo -e "${YELLOW}Found .llm-av/ directory with audit logs and config.${RESET}"
186
+ echo -e "${YELLOW}Remove it? This will delete audit history. [y/N]${RESET}"
187
+ read -r REPLY
188
+ if [[ "$REPLY" =~ ^[Yy]$ ]]; then
189
+ rm -rf "${PROJECT_DIR}/.llm-av"
190
+ ok ".llm-av/ directory (audit logs and config)"
191
+ else
192
+ skip ".llm-av/ directory (preserved by user)"
193
+ fi
194
+ fi
195
+
196
+ # ═══════════════════════════════════════════════════════════════════════
197
+ # Summary
198
+ # ═══════════════════════════════════════════════════════════════════════
199
+
200
+ echo ""
201
+ echo -e "${BOLD}=== Uninstall Summary ===${RESET}"
202
+ echo -e "${GREEN}Removed: ${#REMOVED[@]}${RESET}"
203
+ for item in "${REMOVED[@]}"; do
204
+ echo -e " ${RED}-${RESET} $item"
205
+ done
206
+
207
+ if [[ ${#SKIPPED[@]} -gt 0 ]]; then
208
+ echo -e "${YELLOW}Skipped: ${#SKIPPED[@]}${RESET}"
209
+ for item in "${SKIPPED[@]}"; do
210
+ echo -e " ${YELLOW}~${RESET} $item"
211
+ done
212
+ fi
213
+
214
+ echo ""
215
+ echo -e "${GREEN}${BOLD}ChainWall uninstalled.${RESET}"