patchi 0.7.5__py3-none-any.whl

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 (496) hide show
  1. patchi/__init__.py +1 -0
  2. patchi/__main__.py +13 -0
  3. patchi/cli/__init__.py +0 -0
  4. patchi/cli/command_families.py +235 -0
  5. patchi/cli/commands/__init__.py +0 -0
  6. patchi/cli/commands/access_cmd.py +65 -0
  7. patchi/cli/commands/agent_stats_cmd.py +273 -0
  8. patchi/cli/commands/agents_cmd.py +187 -0
  9. patchi/cli/commands/ai_cmd.py +308 -0
  10. patchi/cli/commands/assure_cmd.py +538 -0
  11. patchi/cli/commands/audit_cmd.py +286 -0
  12. patchi/cli/commands/auto_cmd.py +110 -0
  13. patchi/cli/commands/blame_cmd.py +53 -0
  14. patchi/cli/commands/chains_cmd.py +327 -0
  15. patchi/cli/commands/charter_cmd.py +173 -0
  16. patchi/cli/commands/chat_cmd.py +597 -0
  17. patchi/cli/commands/check_cmd.py +232 -0
  18. patchi/cli/commands/cleanup_cmd.py +328 -0
  19. patchi/cli/commands/cockpit_cmd.py +208 -0
  20. patchi/cli/commands/commands_cmd.py +160 -0
  21. patchi/cli/commands/cross_repo_cmd.py +113 -0
  22. patchi/cli/commands/deps_cmd.py +110 -0
  23. patchi/cli/commands/dev_check_cmd.py +342 -0
  24. patchi/cli/commands/dev_cmd.py +445 -0
  25. patchi/cli/commands/doctor_cmd.py +457 -0
  26. patchi/cli/commands/findings_cmd.py +187 -0
  27. patchi/cli/commands/fix_cmd.py +648 -0
  28. patchi/cli/commands/fix_review_cmd.py +273 -0
  29. patchi/cli/commands/heatmap_cmd.py +62 -0
  30. patchi/cli/commands/help_cmd.py +159 -0
  31. patchi/cli/commands/hosted_cmd.py +980 -0
  32. patchi/cli/commands/init.py +456 -0
  33. patchi/cli/commands/key_cmd.py +571 -0
  34. patchi/cli/commands/learn_cmd.py +140 -0
  35. patchi/cli/commands/link_cmd.py +104 -0
  36. patchi/cli/commands/log_cmd.py +57 -0
  37. patchi/cli/commands/memory_cmd.py +215 -0
  38. patchi/cli/commands/model_cmd.py +207 -0
  39. patchi/cli/commands/notify_cmd.py +213 -0
  40. patchi/cli/commands/notify_prompts.py +29 -0
  41. patchi/cli/commands/patch_cmd.py +231 -0
  42. patchi/cli/commands/plan_cmd.py +128 -0
  43. patchi/cli/commands/plugins_cmd.py +307 -0
  44. patchi/cli/commands/queue_cmd.py +152 -0
  45. patchi/cli/commands/quick_cmd.py +159 -0
  46. patchi/cli/commands/ready_cmd.py +292 -0
  47. patchi/cli/commands/report_cmd.py +416 -0
  48. patchi/cli/commands/restrict_cmd.py +127 -0
  49. patchi/cli/commands/review_cmd.py +225 -0
  50. patchi/cli/commands/rules_cmd.py +233 -0
  51. patchi/cli/commands/scan_cmd.py +1908 -0
  52. patchi/cli/commands/settings_cmd.py +45 -0
  53. patchi/cli/commands/status_cmd.py +679 -0
  54. patchi/cli/commands/test_cmd.py +1052 -0
  55. patchi/cli/commands/trend_cmd.py +296 -0
  56. patchi/cli/commands/undo_cmd.py +235 -0
  57. patchi/cli/commands/update_cmd.py +345 -0
  58. patchi/cli/commands/verify_cmd.py +56 -0
  59. patchi/cli/commands/vr_cmd.py +440 -0
  60. patchi/cli/commands/watch_cmd.py +304 -0
  61. patchi/cli/commands/web_cmd.py +114 -0
  62. patchi/cli/console.py +101 -0
  63. patchi/cli/display/__init__.py +1 -0
  64. patchi/cli/display/live_audit.py +269 -0
  65. patchi/cli/display/live_progress.py +169 -0
  66. patchi/cli/framework.py +241 -0
  67. patchi/cli/logo.py +128 -0
  68. patchi/cli/main.py +222 -0
  69. patchi/cli/registry.py +1171 -0
  70. patchi/cli/style.py +68 -0
  71. patchi/cli/themes.py +187 -0
  72. patchi/cli/ux.py +444 -0
  73. patchi/core/__init__.py +0 -0
  74. patchi/core/agents/__init__.py +0 -0
  75. patchi/core/agents/api_fuzzer_agent.py +141 -0
  76. patchi/core/agents/attack_agent.py +242 -0
  77. patchi/core/agents/base.py +1012 -0
  78. patchi/core/agents/bug_predictor_agent.py +58 -0
  79. patchi/core/agents/build_tool_validator.py +150 -0
  80. patchi/core/agents/cache.py +192 -0
  81. patchi/core/agents/chaos_agent.py +133 -0
  82. patchi/core/agents/cicd_generator.py +240 -0
  83. patchi/core/agents/comment_scanner.py +280 -0
  84. patchi/core/agents/console_logging_agent.py +156 -0
  85. patchi/core/agents/coordinator.py +858 -0
  86. patchi/core/agents/core_scanner.py +269 -0
  87. patchi/core/agents/coverage_prioritizer.py +181 -0
  88. patchi/core/agents/dead_code_hygiene.py +296 -0
  89. patchi/core/agents/dead_code_scanner.py +692 -0
  90. patchi/core/agents/dependency_scanner.py +725 -0
  91. patchi/core/agents/doc_claim_agent.py +573 -0
  92. patchi/core/agents/duplicate_scanner.py +568 -0
  93. patchi/core/agents/env_scanner.py +410 -0
  94. patchi/core/agents/feature_flag_agent.py +89 -0
  95. patchi/core/agents/frontend_framework_agent.py +133 -0
  96. patchi/core/agents/goroutine_agent.py +82 -0
  97. patchi/core/agents/governor.py +1972 -0
  98. patchi/core/agents/i18n_agent.py +95 -0
  99. patchi/core/agents/license_compliance.py +247 -0
  100. patchi/core/agents/linking_agent.py +251 -0
  101. patchi/core/agents/memory_profiler_agent.py +102 -0
  102. patchi/core/agents/modernization_agent.py +84 -0
  103. patchi/core/agents/mutation_agent.py +174 -0
  104. patchi/core/agents/nl_query_agent.py +74 -0
  105. patchi/core/agents/promise_rejection_agent.py +100 -0
  106. patchi/core/agents/refactoring_agent.py +286 -0
  107. patchi/core/agents/resource_leak_agent.py +91 -0
  108. patchi/core/agents/route_graph_scanner.py +951 -0
  109. patchi/core/agents/run_agent.py +106 -0
  110. patchi/core/agents/rust_unwrap_agent.py +100 -0
  111. patchi/core/agents/sbom_generator.py +284 -0
  112. patchi/core/agents/scanners.py +67 -0
  113. patchi/core/agents/side/__init__.py +1 -0
  114. patchi/core/agents/side/build_agent.py +65 -0
  115. patchi/core/agents/side/format_agent.py +50 -0
  116. patchi/core/agents/side/install_agent.py +63 -0
  117. patchi/core/agents/side_file_scanner.py +549 -0
  118. patchi/core/agents/snapshot_drift_detector.py +146 -0
  119. patchi/core/agents/spa_route_inventory.py +203 -0
  120. patchi/core/agents/test_scanner.py +442 -0
  121. patchi/core/agents/tool_health.py +109 -0
  122. patchi/core/agents/tool_runner.py +162 -0
  123. patchi/core/agents/type_scanner.py +168 -0
  124. patchi/core/agents/ui_scanner.py +558 -0
  125. patchi/core/ai/__init__.py +20 -0
  126. patchi/core/ai/agent_audit.py +153 -0
  127. patchi/core/ai/agent_profiler.py +277 -0
  128. patchi/core/ai/client.py +499 -0
  129. patchi/core/ai/cost_tracker.py +107 -0
  130. patchi/core/ai/model_router.py +318 -0
  131. patchi/core/ai/orchestrator.py +625 -0
  132. patchi/core/ai/prompts.py +681 -0
  133. patchi/core/ai/smart.py +302 -0
  134. patchi/core/ai/tool_executor.py +24 -0
  135. patchi/core/ai/tools/__init__.py +10 -0
  136. patchi/core/ai/tools/executor.py +621 -0
  137. patchi/core/ai/tools/realize.py +1160 -0
  138. patchi/core/ai/tools/registry.py +1577 -0
  139. patchi/core/assurance/__init__.py +33 -0
  140. patchi/core/assurance/builder.py +211 -0
  141. patchi/core/assurance/graph.py +342 -0
  142. patchi/core/assurance/invariants.py +168 -0
  143. patchi/core/atomic.py +61 -0
  144. patchi/core/attackers/__init__.py +17 -0
  145. patchi/core/attackers/api_abuse.py +89 -0
  146. patchi/core/attackers/auth_bypass.py +73 -0
  147. patchi/core/attackers/base.py +91 -0
  148. patchi/core/attackers/business_logic.py +88 -0
  149. patchi/core/attackers/planner.py +108 -0
  150. patchi/core/attackers/priv_escalation.py +88 -0
  151. patchi/core/attackers/recon.py +87 -0
  152. patchi/core/brain/__init__.py +0 -0
  153. patchi/core/brain/ast_utils/__init__.py +81 -0
  154. patchi/core/brain/ast_utils/assignments.py +219 -0
  155. patchi/core/brain/ast_utils/calls.py +139 -0
  156. patchi/core/brain/ast_utils/config.py +132 -0
  157. patchi/core/brain/ast_utils/control_flow.py +74 -0
  158. patchi/core/brain/ast_utils/dead_symbols.py +205 -0
  159. patchi/core/brain/ast_utils/decorators.py +108 -0
  160. patchi/core/brain/ast_utils/helpers.py +144 -0
  161. patchi/core/brain/ast_utils/imports.py +169 -0
  162. patchi/core/brain/ast_utils/scan.py +143 -0
  163. patchi/core/brain/ast_utils/taint.py +310 -0
  164. patchi/core/brain/audit.py +379 -0
  165. patchi/core/brain/baseline.py +195 -0
  166. patchi/core/brain/blast_radius.py +312 -0
  167. patchi/core/brain/body_tags.py +144 -0
  168. patchi/core/brain/brain.py +1161 -0
  169. patchi/core/brain/brain_context.py +393 -0
  170. patchi/core/brain/brain_watcher.py +340 -0
  171. patchi/core/brain/charter.py +473 -0
  172. patchi/core/brain/classifier.py +214 -0
  173. patchi/core/brain/cockpit.py +350 -0
  174. patchi/core/brain/code_query.py +710 -0
  175. patchi/core/brain/contract.py +889 -0
  176. patchi/core/brain/contract_diff.py +155 -0
  177. patchi/core/brain/council.py +800 -0
  178. patchi/core/brain/cross_repo.py +104 -0
  179. patchi/core/brain/dead_code_tools.py +157 -0
  180. patchi/core/brain/doc_validator.py +197 -0
  181. patchi/core/brain/domain_activator.py +2183 -0
  182. patchi/core/brain/enriched_context.py +220 -0
  183. patchi/core/brain/file_corpus.py +220 -0
  184. patchi/core/brain/framework.py +953 -0
  185. patchi/core/brain/freshness.py +273 -0
  186. patchi/core/brain/git_aware.py +206 -0
  187. patchi/core/brain/heatmap.py +104 -0
  188. patchi/core/brain/ignore_parser.py +153 -0
  189. patchi/core/brain/import_graph.py +486 -0
  190. patchi/core/brain/languages.py +397 -0
  191. patchi/core/brain/layered_brain.py +419 -0
  192. patchi/core/brain/learning.py +229 -0
  193. patchi/core/brain/orphaned_endpoints.py +313 -0
  194. patchi/core/brain/personas/__init__.py +648 -0
  195. patchi/core/brain/personas/bad_user.py +165 -0
  196. patchi/core/brain/personas/base.py +349 -0
  197. patchi/core/brain/proactive.py +807 -0
  198. patchi/core/brain/project_context.py +121 -0
  199. patchi/core/brain/project_reader.py +521 -0
  200. patchi/core/brain/reasoning.py +269 -0
  201. patchi/core/brain/route_detector/__init__.py +15 -0
  202. patchi/core/brain/route_detector/base.py +31 -0
  203. patchi/core/brain/route_detector/csharp.py +209 -0
  204. patchi/core/brain/route_detector/file_based.py +81 -0
  205. patchi/core/brain/route_detector/go.py +152 -0
  206. patchi/core/brain/route_detector/java.py +195 -0
  207. patchi/core/brain/route_detector/javascript.py +197 -0
  208. patchi/core/brain/route_detector/php.py +158 -0
  209. patchi/core/brain/route_detector/python.py +193 -0
  210. patchi/core/brain/route_detector/registry.py +25 -0
  211. patchi/core/brain/route_detector/ruby.py +134 -0
  212. patchi/core/brain/route_detector/rust.py +216 -0
  213. patchi/core/brain/route_detector/swift.py +118 -0
  214. patchi/core/brain/route_mapper.py +265 -0
  215. patchi/core/brain/scanner.py +2136 -0
  216. patchi/core/brain/secrets.py +280 -0
  217. patchi/core/brain/symbol_graph.py +1955 -0
  218. patchi/core/brain/team.py +28 -0
  219. patchi/core/brain/trace_log.py +132 -0
  220. patchi/core/brain/type_checker/__init__.py +65 -0
  221. patchi/core/brain/type_checker/base.py +60 -0
  222. patchi/core/brain/type_checker/csharp.py +59 -0
  223. patchi/core/brain/type_checker/dart.py +59 -0
  224. patchi/core/brain/type_checker/go.py +81 -0
  225. patchi/core/brain/type_checker/java.py +75 -0
  226. patchi/core/brain/type_checker/kotlin.py +75 -0
  227. patchi/core/brain/type_checker/php.py +88 -0
  228. patchi/core/brain/type_checker/python.py +87 -0
  229. patchi/core/brain/type_checker/rust.py +81 -0
  230. patchi/core/brain/type_checker/swift.py +59 -0
  231. patchi/core/brain/type_checker/typescript.py +298 -0
  232. patchi/core/brain/understander.py +130 -0
  233. patchi/core/brain/verify.py +379 -0
  234. patchi/core/campaigns/__init__.py +14 -0
  235. patchi/core/campaigns/base.py +62 -0
  236. patchi/core/campaigns/data_flow_abuse.py +153 -0
  237. patchi/core/campaigns/orchestrator.py +140 -0
  238. patchi/core/campaigns/state_transitions.py +178 -0
  239. patchi/core/ci_bundle.py +104 -0
  240. patchi/core/config.py +311 -0
  241. patchi/core/constants.py +245 -0
  242. patchi/core/debug/__init__.py +25 -0
  243. patchi/core/debug/adapters/__init__.py +11 -0
  244. patchi/core/debug/adapters/codelldb.py +379 -0
  245. patchi/core/debug/adapters/node.py +222 -0
  246. patchi/core/debug/adapters/powershell.py +210 -0
  247. patchi/core/debug/adapters/python.py +244 -0
  248. patchi/core/debug/capture.py +210 -0
  249. patchi/core/debug/dap_client.py +268 -0
  250. patchi/core/detector/__init__.py +0 -0
  251. patchi/core/detector/audit.py +194 -0
  252. patchi/core/detector/bus.py +226 -0
  253. patchi/core/detector/dispatcher.py +275 -0
  254. patchi/core/detector/event.py +254 -0
  255. patchi/core/detector/sigma_engine.py +378 -0
  256. patchi/core/detector/triage.py +289 -0
  257. patchi/core/export/sarif.py +113 -0
  258. patchi/core/fix/__init__.py +17 -0
  259. patchi/core/fix/applier.py +574 -0
  260. patchi/core/fix/base.py +510 -0
  261. patchi/core/fix/code_fixer.py +169 -0
  262. patchi/core/fix/dead_code_remover.py +131 -0
  263. patchi/core/fix/fix_agents.py +775 -0
  264. patchi/core/fix/patch.py +444 -0
  265. patchi/core/fix/risk_gate.py +383 -0
  266. patchi/core/fix/security_fixer.py +93 -0
  267. patchi/core/fix/verify_loop.py +204 -0
  268. patchi/core/fuzz/__init__.py +8 -0
  269. patchi/core/fuzz/corpus.py +137 -0
  270. patchi/core/fuzz/input_fuzzer.py +256 -0
  271. patchi/core/fuzz/sequence_fuzzer.py +162 -0
  272. patchi/core/fuzz/state_fuzzer.py +236 -0
  273. patchi/core/health.py +407 -0
  274. patchi/core/hosted/__init__.py +1 -0
  275. patchi/core/hosted/anomaly.py +298 -0
  276. patchi/core/hosted/audit_log.py +102 -0
  277. patchi/core/hosted/compliance_report.py +148 -0
  278. patchi/core/hosted/ip_reputation.py +169 -0
  279. patchi/core/hosted/log_parsers.py +251 -0
  280. patchi/core/hosted/tokens.py +127 -0
  281. patchi/core/hosted/watchlist.py +164 -0
  282. patchi/core/hosted/webhooks.py +156 -0
  283. patchi/core/memory.py +437 -0
  284. patchi/core/notifications/__init__.py +18 -0
  285. patchi/core/notifications/channels.py +192 -0
  286. patchi/core/notifications/digest.py +141 -0
  287. patchi/core/notifications/escalation.py +158 -0
  288. patchi/core/notifications/notifier.py +182 -0
  289. patchi/core/notifications/quiet_hours.py +69 -0
  290. patchi/core/plugins/__init__.py +48 -0
  291. patchi/core/plugins/analyzer.py +326 -0
  292. patchi/core/plugins/analyzers/__init__.py +6 -0
  293. patchi/core/plugins/analyzers/dead_code_analyzer.py +120 -0
  294. patchi/core/plugins/analyzers/secret_scanner.py +158 -0
  295. patchi/core/plugins/analyzers/todo_scanner.py +115 -0
  296. patchi/core/plugins/registry.py +335 -0
  297. patchi/core/queue.py +375 -0
  298. patchi/core/reliability/__init__.py +13 -0
  299. patchi/core/reliability/chaos.py +163 -0
  300. patchi/core/reliability/fault_injector.py +172 -0
  301. patchi/core/reliability/idempotency.py +128 -0
  302. patchi/core/reliability/recovery.py +147 -0
  303. patchi/core/runtime/__init__.py +5 -0
  304. patchi/core/runtime/tracer.py +230 -0
  305. patchi/core/scan_bus.py +156 -0
  306. patchi/core/security/__init__.py +1 -0
  307. patchi/core/security/ai_validator.py +462 -0
  308. patchi/core/security/app_mapper.py +216 -0
  309. patchi/core/security/app_profile.py +464 -0
  310. patchi/core/security/attack_feedback.py +141 -0
  311. patchi/core/security/attack_scenarios/__init__.py +1 -0
  312. patchi/core/security/attack_tree.py +176 -0
  313. patchi/core/security/auth_audit_agent.py +344 -0
  314. patchi/core/security/authz_agent.py +602 -0
  315. patchi/core/security/auto_fix_proactive.py +620 -0
  316. patchi/core/security/auto_fixer.py +660 -0
  317. patchi/core/security/auto_ticket.py +53 -0
  318. patchi/core/security/bandit_agent.py +152 -0
  319. patchi/core/security/blast_radius.py +226 -0
  320. patchi/core/security/browser_tester.py +333 -0
  321. patchi/core/security/business_logic_agent.py +263 -0
  322. patchi/core/security/catch_block_auditor.py +395 -0
  323. patchi/core/security/cdn_cache_agent.py +357 -0
  324. patchi/core/security/chain_analyzer.py +321 -0
  325. patchi/core/security/chain_to_assurance.py +168 -0
  326. patchi/core/security/charter.py +510 -0
  327. patchi/core/security/cloud_waf_detector.py +295 -0
  328. patchi/core/security/codeql_agent.py +233 -0
  329. patchi/core/security/compliance_agent.py +348 -0
  330. patchi/core/security/confidence_gate.py +423 -0
  331. patchi/core/security/container_scanner.py +282 -0
  332. patchi/core/security/crypto_agent.py +378 -0
  333. patchi/core/security/cve_monitor.py +262 -0
  334. patchi/core/security/dast_agent.py +865 -0
  335. patchi/core/security/defectdojo.py +238 -0
  336. patchi/core/security/defenders/__init__.py +75 -0
  337. patchi/core/security/defenders/auth_middleware.py +115 -0
  338. patchi/core/security/defenders/base.py +97 -0
  339. patchi/core/security/defenders/block_ip.py +71 -0
  340. patchi/core/security/defenders/block_ws_origin.py +36 -0
  341. patchi/core/security/defenders/crypto_fix.py +118 -0
  342. patchi/core/security/defenders/enforce_rate_limit.py +108 -0
  343. patchi/core/security/defenders/fix_code.py +93 -0
  344. patchi/core/security/defenders/invalidate_session.py +40 -0
  345. patchi/core/security/defenders/patch_config.py +70 -0
  346. patchi/core/security/defenders/rotate_secret.py +54 -0
  347. patchi/core/security/defenders/suspend_account.py +41 -0
  348. patchi/core/security/defenders/update_dependency.py +160 -0
  349. patchi/core/security/defense_layer.py +217 -0
  350. patchi/core/security/dependency_vulnerability_agent.py +616 -0
  351. patchi/core/security/detection_pipeline.py +289 -0
  352. patchi/core/security/dns_security_agent.py +497 -0
  353. patchi/core/security/domain_activator_v2.py +913 -0
  354. patchi/core/security/domain_loader.py +1004 -0
  355. patchi/core/security/domains/__init__.py +0 -0
  356. patchi/core/security/email_authentication_agent.py +417 -0
  357. patchi/core/security/env_var_validator.py +304 -0
  358. patchi/core/security/evidence.py +100 -0
  359. patchi/core/security/falco_runtime_agent.py +387 -0
  360. patchi/core/security/fix-playbooks/__init__.py +0 -0
  361. patchi/core/security/gated_finding.py +85 -0
  362. patchi/core/security/git_diff_activator.py +367 -0
  363. patchi/core/security/governance.py +208 -0
  364. patchi/core/security/gradual_gate.py +34 -0
  365. patchi/core/security/history.py +315 -0
  366. patchi/core/security/iac_scanner.py +250 -0
  367. patchi/core/security/ignore_expiry.py +111 -0
  368. patchi/core/security/ignore_learner.py +416 -0
  369. patchi/core/security/injection_agent.py +319 -0
  370. patchi/core/security/insecure_randomness_agent.py +288 -0
  371. patchi/core/security/intent_analyzer.py +326 -0
  372. patchi/core/security/jwt_agent.py +453 -0
  373. patchi/core/security/kubernetes_agent.py +638 -0
  374. patchi/core/security/layer2_orchestrator.py +341 -0
  375. patchi/core/security/llm_security_agent.py +252 -0
  376. patchi/core/security/misconfig_agent.py +600 -0
  377. patchi/core/security/mobile_security_agent.py +474 -0
  378. patchi/core/security/network_agent.py +376 -0
  379. patchi/core/security/noise_filter.py +274 -0
  380. patchi/core/security/orchestrator.py +313 -0
  381. patchi/core/security/pattern_context.py +125 -0
  382. patchi/core/security/pattern_loader.py +101 -0
  383. patchi/core/security/pentest/__init__.py +4 -0
  384. patchi/core/security/pentest/base.py +58 -0
  385. patchi/core/security/pentest/dalfox_adapter.py +40 -0
  386. patchi/core/security/pentest/ffuf_adapter.py +48 -0
  387. patchi/core/security/pentest/nuclei_adapter.py +50 -0
  388. patchi/core/security/pentest/registry.py +80 -0
  389. patchi/core/security/pentest/shannon_adapter.py +107 -0
  390. patchi/core/security/pentest/sqlmap_adapter.py +56 -0
  391. patchi/core/security/pentest/zap_adapter.py +52 -0
  392. patchi/core/security/plan_auditor.py +276 -0
  393. patchi/core/security/policy_engine.py +272 -0
  394. patchi/core/security/prechecks.py +172 -0
  395. patchi/core/security/precommit_hook.py +247 -0
  396. patchi/core/security/privacy_agent.py +361 -0
  397. patchi/core/security/push_notification_agent.py +417 -0
  398. patchi/core/security/pysa_agent.py +143 -0
  399. patchi/core/security/reasoning.py +442 -0
  400. patchi/core/security/red_team_agent.py +184 -0
  401. patchi/core/security/red_team_engine.py +1142 -0
  402. patchi/core/security/remediation.py +360 -0
  403. patchi/core/security/request_interceptor.py +294 -0
  404. patchi/core/security/runtime_validator.py +245 -0
  405. patchi/core/security/saml_sso_agent.py +401 -0
  406. patchi/core/security/sast_agent.py +213 -0
  407. patchi/core/security/sast_gate.py +95 -0
  408. patchi/core/security/scheduler.py +287 -0
  409. patchi/core/security/secrets_runtime_agent.py +476 -0
  410. patchi/core/security/security_agents.py +175 -0
  411. patchi/core/security/security_config.py +551 -0
  412. patchi/core/security/security_probe.py +762 -0
  413. patchi/core/security/security_taint.py +1005 -0
  414. patchi/core/security/sensitive_data_agent.py +271 -0
  415. patchi/core/security/service_mesh_agent.py +412 -0
  416. patchi/core/security/session_management_agent.py +245 -0
  417. patchi/core/security/ssrf_agent.py +422 -0
  418. patchi/core/security/supply_chain.py +449 -0
  419. patchi/core/security/threat_model_generator.py +378 -0
  420. patchi/core/security/threat_model_updater.py +196 -0
  421. patchi/core/security/tool_adapters.py +135 -0
  422. patchi/core/security/tool_verify.py +173 -0
  423. patchi/core/security/websocket_security_agent.py +188 -0
  424. patchi/core/snapshot.py +242 -0
  425. patchi/core/tenant.py +386 -0
  426. patchi/core/testing/__init__.py +17 -0
  427. patchi/core/testing/_browser.py +147 -0
  428. patchi/core/testing/ads_agent.py +141 -0
  429. patchi/core/testing/api_contract_agent.py +450 -0
  430. patchi/core/testing/app_discovery_agent.py +641 -0
  431. patchi/core/testing/app_launcher.py +184 -0
  432. patchi/core/testing/browser_test_agent.py +516 -0
  433. patchi/core/testing/e2e_flow_agent.py +354 -0
  434. patchi/core/testing/flake_detector_agent.py +292 -0
  435. patchi/core/testing/gate.py +31 -0
  436. patchi/core/testing/live_test_runner.py +304 -0
  437. patchi/core/testing/live_v2/__init__.py +1 -0
  438. patchi/core/testing/live_v2/browser_pool.py +349 -0
  439. patchi/core/testing/live_v2/browser_test_runner.py +313 -0
  440. patchi/core/testing/live_v2/runner.py +626 -0
  441. patchi/core/testing/live_v2/screenshot_manager.py +474 -0
  442. patchi/core/testing/live_v2/stress_orchestrator.py +523 -0
  443. patchi/core/testing/live_v2/video_recorder.py +303 -0
  444. patchi/core/testing/regression_agent.py +302 -0
  445. patchi/core/testing/security_test_agent.py +253 -0
  446. patchi/core/testing/stress_test_agent.py +203 -0
  447. patchi/core/testing/test_agents.py +50 -0
  448. patchi/core/testing/test_config.py +194 -0
  449. patchi/core/testing/ui_accessibility_agent.py +324 -0
  450. patchi/core/testing/ui_button_agent.py +294 -0
  451. patchi/core/testing/ui_layout_agent.py +330 -0
  452. patchi/core/testing/unit_test_agent.py +1149 -0
  453. patchi/core/testing/visual_regression_agent.py +260 -0
  454. patchi/web/__init__.py +1 -0
  455. patchi/web/api/__init__.py +1 -0
  456. patchi/web/api/brain_map.py +114 -0
  457. patchi/web/api/charts.py +47 -0
  458. patchi/web/api/chat.py +224 -0
  459. patchi/web/api/cicd.py +576 -0
  460. patchi/web/api/dast_evidence.py +49 -0
  461. patchi/web/api/dev_check.py +320 -0
  462. patchi/web/api/fix.py +134 -0
  463. patchi/web/api/guard.py +65 -0
  464. patchi/web/api/hosted.py +128 -0
  465. patchi/web/api/hosted_v2.py +234 -0
  466. patchi/web/api/live_testing.py +699 -0
  467. patchi/web/api/scan.py +582 -0
  468. patchi/web/api/smart.py +111 -0
  469. patchi/web/api/tenant.py +117 -0
  470. patchi/web/api/tools.py +85 -0
  471. patchi/web/api_legacy.py +2401 -0
  472. patchi/web/app.py +310 -0
  473. patchi/web/events.py +483 -0
  474. patchi/web/routes/__init__.py +1 -0
  475. patchi/web/routes/assurance.py +541 -0
  476. patchi/web/routes/brain.py +36 -0
  477. patchi/web/routes/charter.py +227 -0
  478. patchi/web/routes/chat.py +23 -0
  479. patchi/web/routes/dashboard.py +558 -0
  480. patchi/web/routes/dashboard_v2.py +402 -0
  481. patchi/web/routes/findings.py +330 -0
  482. patchi/web/routes/guard.py +35 -0
  483. patchi/web/routes/history.py +126 -0
  484. patchi/web/routes/landing.py +52 -0
  485. patchi/web/routes/live_testing.py +24 -0
  486. patchi/web/routes/review.py +57 -0
  487. patchi/web/routes/self_improvement.py +110 -0
  488. patchi/web/routes/settings.py +49 -0
  489. patchi/web/routes/tokens.py +29 -0
  490. patchi/web/spawn.py +139 -0
  491. patchi/web/ws.py +141 -0
  492. patchi-0.7.5.dist-info/METADATA +315 -0
  493. patchi-0.7.5.dist-info/RECORD +496 -0
  494. patchi-0.7.5.dist-info/WHEEL +5 -0
  495. patchi-0.7.5.dist-info/licenses/LICENSE +60 -0
  496. patchi-0.7.5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,141 @@
1
+ """
2
+ ApiFuzzerAgent §5.3.1 — EvoMaster-style REST/GraphQL fuzz generation.
3
+
4
+ From RouteMapper 18fw routes → generates malformed JSON, massive payloads,
5
+ wrong Content-Types, injection strings via InputFuzzer. Optionally shells out
6
+ to EvoMaster (WebFuzzing/EvoMaster) if `evomaster.jar` or docker is available,
7
+ else falls back to local InputFuzzer + in-process HTTP smoke.
8
+
9
+ Does NOT require a running server for generation; fuzz payloads are persisted
10
+ to .patchi/fuzz/<route>.json for DAST replay via --with-fuzz.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import json
16
+ import logging
17
+ import shutil
18
+ import subprocess
19
+ from pathlib import Path
20
+
21
+ from patchi.core.agents.base import (
22
+ AgentGroup,
23
+ AgentInput,
24
+ AgentResult,
25
+ AgentStatus,
26
+ BaseAgent,
27
+ Severity,
28
+ make_finding,
29
+ register,
30
+ )
31
+ from patchi.core.brain.route_mapper import RouteInfo
32
+ from patchi.core.fuzz.input_fuzzer import InputFuzzer
33
+
34
+ _log = logging.getLogger("patchi.agents.api_fuzzer")
35
+
36
+ _EVO_DOCKER = "evomaster/evomaster:latest"
37
+
38
+
39
+ def _try_evomaster(routes: list[RouteInfo], out_dir: Path) -> int:
40
+ """Try EvoMaster jar/docker — returns count or 0 if not available."""
41
+ jar = shutil.which("evomaster.jar") or shutil.which("java")
42
+ docker = shutil.which("docker")
43
+ if not jar and not docker:
44
+ return 0
45
+ # Probe only if OpenAPI spec exists
46
+ if not (out_dir.parent / "openapi.json").exists() and not (out_dir.parent / "swagger.json").exists():
47
+ return 0
48
+ try:
49
+ # Use docker EvoMaster in blackbox mode against openapi.json if present
50
+ spec = out_dir.parent / "openapi.json"
51
+ if not spec.exists():
52
+ spec = out_dir.parent / "swagger.json"
53
+ cmd = ["docker", "run", "--rm", "-v", f"{spec}:/tmp/spec.json", _EVO_DOCKER, "--blackBox", "true", "--bbSwaggerUrl", "file:///tmp/spec.json", "--outputFolder", "/tmp/out", "--maxTime", "30s"] if docker else None
54
+ if not cmd:
55
+ return 0
56
+ proc = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
57
+ return 1 if proc.returncode in (0, 1) else 0
58
+ except Exception as exc: # noqa: BLE001
59
+ _log.debug("evomaster probe failed: %s", exc)
60
+ return 0
61
+
62
+
63
+ @register
64
+ class ApiFuzzerAgent(BaseAgent):
65
+ group = AgentGroup.SECURITY
66
+ name = "ApiFuzzerAgent"
67
+ description = "EvoMaster-style API fuzz payloads from RouteMapper routes (REST/GraphQL) → .patchi/fuzz/"
68
+ timeout = 90
69
+
70
+ def _run(self, inp: AgentInput, result: AgentResult) -> None:
71
+ # Routes from brain (RouteMapper) or live scan
72
+ routes: list[RouteInfo] = []
73
+ try:
74
+ from patchi.core.brain.file_corpus import FileCorpus
75
+ from patchi.core.brain.framework import FrameworkDetector
76
+ from patchi.core.brain.route_mapper import RouteMapper
77
+
78
+ corpus = FileCorpus(inp.root)
79
+ stack = FrameworkDetector(inp.root, corpus=corpus).detect()
80
+ mapper = RouteMapper(inp.root, stack)
81
+ # Use inp.brain routes if present to avoid re-parse
82
+ if inp.brain.get("routes"):
83
+ routes = [RouteInfo(**r) if isinstance(r, dict) else r for r in inp.brain.get("routes", [])]
84
+ else:
85
+ from patchi.core.brain.scanner import FileScanner
86
+ routes = mapper.extract(FileScanner(inp.root).scan())
87
+ except Exception as exc: # noqa: BLE001
88
+ _log.debug("route extract failed: %s", exc)
89
+ routes = []
90
+
91
+ if not routes:
92
+ result.status = AgentStatus.SUCCEEDED
93
+ result.data["fuzz_count"] = 0
94
+ return
95
+
96
+ fuzzer = InputFuzzer(seed=0xF22A)
97
+ out_dir = inp.root / ".patchi" / "fuzz"
98
+ out_dir.mkdir(parents=True, exist_ok=True)
99
+
100
+ # Try EvoMaster first
101
+ evo = _try_evomaster(routes, out_dir)
102
+
103
+ fuzz_count = 0
104
+ for r in routes[:50]: # cap 50 routes
105
+ # Skip health/static
106
+ if r.path in ("/health", "/healthz", "/metrics") or r.path.startswith("/static/"):
107
+ continue
108
+ payloads = []
109
+ # 1. Boundary JSON
110
+ payloads.extend([f.to_dict() for f in fuzzer.fuzz_dict({"id": 1, "name": "test"}, count=5)])
111
+ # 2. Injection strings as query/body values
112
+ for fi in fuzzer.fuzz_string(r.path, count=6):
113
+ payloads.append({"strategy": fi.strategy, "value": fi.value, "label": fi.label})
114
+ # 3. Method fuzz: wrong method
115
+ payloads.append({"strategy": "method", "value": "WRONG_METHOD", "label": "method_fuzz"})
116
+ # Persist
117
+ fname = f"{r.method.lower()}_{r.path.strip('/').replace('/','_') or 'root'}.json"
118
+ fname = "".join(c if c.isalnum() or c in "._-" else "_" for c in fname)[:120]
119
+ try:
120
+ (out_dir / fname).write_text(json.dumps({"route": r.to_dict(), "payloads": payloads[:12]}, indent=2), encoding="utf-8")
121
+ fuzz_count += 1
122
+ except OSError as exc:
123
+ _log.warning("ApiFuzzer write failed: %s", exc)
124
+
125
+ # Finding per route with high-risk payload count
126
+ result.findings.append(
127
+ make_finding(
128
+ severity=Severity.INFO,
129
+ file=r.file,
130
+ line_start=r.line,
131
+ title=f"Fuzz payloads for {r.method} {r.path}",
132
+ description=f"Generated {len(payloads[:12])} EvoMaster/InputFuzzer payloads (boundary/injection/encoding) for DAST replay --with-fuzz. EvoMaster: {'yes' if evo else 'local'}",
133
+ evidence=r.path,
134
+ finding_type="fuzz_payload",
135
+ )
136
+ )
137
+
138
+ result.status = AgentStatus.SUCCEEDED
139
+ result.data["fuzz_count"] = fuzz_count
140
+ result.data["evomaster"] = bool(evo)
141
+ result.files_scanned = len(routes)
@@ -0,0 +1,242 @@
1
+ """
2
+ AttackAgent — Metasploit auxiliary/scanner probe integration.
3
+
4
+ Uses pymetasploit3 bridge to msfrpcd to run auxiliary/scanner modules
5
+ against the local project. Never targets external hosts — localhost only.
6
+
7
+ Flow:
8
+ 1. Read project brain data (framework, ports, routes)
9
+ 2. Pick relevant auxiliary/scanner modules based on framework
10
+ 3. Connect to msfrpcd on localhost:55553
11
+ 4. Run each module against 127.0.0.1
12
+ 5. Return findings as structured JSON
13
+
14
+ Optional dependency: pymetasploit3 (pip install patchi[msf])
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import json
20
+ from concurrent.futures import ThreadPoolExecutor
21
+ from concurrent.futures import TimeoutError as FutureTimeout
22
+
23
+ from .base import (
24
+ AgentGroup,
25
+ AgentInput,
26
+ AgentResult,
27
+ BaseAgent,
28
+ Finding,
29
+ Severity,
30
+ register,
31
+ )
32
+
33
+ # ── Framework → auxiliary/scanner module mapping ──────────────────────────────
34
+
35
+ # Shared module groups to avoid duplication
36
+ _HTTP_COMMON = [
37
+ "scanner/http/http_header_xss",
38
+ "scanner/http/http_version",
39
+ "scanner/http/options",
40
+ ]
41
+
42
+ _FRAMEWORK_MODULES: dict[str, list[str]] = {
43
+ "flask": [*_HTTP_COMMON, "scanner/http/http_methods"],
44
+ "django": [*_HTTP_COMMON, "scanner/http/http_methods"],
45
+ "fastapi": _HTTP_COMMON,
46
+ "express": _HTTP_COMMON,
47
+ "react": [
48
+ "scanner/http/http_header_xss",
49
+ "scanner/http/http_version",
50
+ ],
51
+ "spring": [*_HTTP_COMMON, "scanner/http/http_methods"],
52
+ }
53
+
54
+ _FALLBACK_MODULES = _HTTP_COMMON
55
+
56
+ _DEFAULT_PORT = 8000
57
+
58
+
59
+ @register
60
+ class AttackAgent(BaseAgent):
61
+ """Metasploit auxiliary/scanner probe integration (localhost only)."""
62
+
63
+ group = AgentGroup.TEST
64
+ name = "AttackAgent"
65
+ timeout = 120 # Metasploit modules can take a while
66
+
67
+ def _run(self, inp: AgentInput, result: AgentResult) -> None:
68
+ # ── 1. Check if pymetasploit3 is available ────────────────────────────
69
+ try:
70
+ import pymetasploit3 # noqa: F401
71
+ except ImportError:
72
+ # Optional dependency — skip cleanly, never FAIL the agent run.
73
+ self.skip(result, "pymetasploit3 not installed. Run: pip install patchi[msf]")
74
+ return
75
+
76
+ # ── 2. Read brain data for framework / port hints ─────────────────────
77
+ brain = inp.brain
78
+ frameworks = _get_frameworks(brain)
79
+ routes = brain.get("routes", [])
80
+
81
+ # Determine target port from config, routes, or default
82
+ target_port = _pick_port(brain, routes)
83
+ target_ip = "127.0.0.1"
84
+ result.data["target"] = f"{target_ip}:{target_port}"
85
+ result.data["frameworks"] = frameworks
86
+
87
+ # ── 3. Pick modules ──────────────────────────────────────────────────
88
+ modules = _pick_modules(frameworks)
89
+
90
+ result.data["modules_selected"] = modules
91
+
92
+ # ── 4. Connect to msfrpcd and run modules ────────────────────────────
93
+ from pymetasploit3.msfrpc import MsfRpcClient
94
+
95
+ password = inp.extra.get("msf_password", "")
96
+ msf_port = inp.extra.get("msf_port", 55553)
97
+ msf_ssl = inp.extra.get("msf_ssl", True)
98
+ msf_module_timeout = inp.extra.get("msf_module_timeout", 30)
99
+
100
+ try:
101
+ client = MsfRpcClient(password, port=msf_port, ssl=msf_ssl)
102
+ except Exception as exc:
103
+ result.add_error(
104
+ f"Cannot connect to msfrpcd at 127.0.0.1:{msf_port} — {exc}. "
105
+ f"Make sure msfrpcd is running (msfrpcd -P your_password -S -a 127.0.0.1 -p {msf_port})"
106
+ )
107
+ return
108
+
109
+ with ThreadPoolExecutor(max_workers=1) as pool:
110
+ for module_name in modules:
111
+ future = pool.submit(
112
+ self._run_module, client, module_name, target_ip, target_port, modules, result
113
+ )
114
+ try:
115
+ finding = future.result(timeout=msf_module_timeout)
116
+ if finding:
117
+ result.findings.append(finding)
118
+ except FutureTimeout:
119
+ result.errors.append(f"{module_name}: timed out after {msf_module_timeout}s")
120
+ except Exception as exc:
121
+ result.errors.append(f"{module_name}: {exc}")
122
+
123
+ def _run_module(
124
+ self,
125
+ client,
126
+ module_name: str,
127
+ target_ip: str,
128
+ target_port: int,
129
+ modules: list[str],
130
+ result: AgentResult,
131
+ ) -> Finding | None:
132
+ """Run a single auxiliary/scanner module and return a Finding."""
133
+ try:
134
+ aux = client.modules.use("auxiliary", module_name)
135
+ aux["RHOSTS"] = target_ip
136
+ aux["RPORT"] = target_port
137
+ raw = aux.execute()
138
+ except Exception as exc:
139
+ result.errors.append(f"{module_name}: {exc}")
140
+ return None
141
+
142
+ if not raw:
143
+ return None
144
+
145
+ # Normalise result to dict
146
+ if isinstance(raw, str):
147
+ try:
148
+ parsed = json.loads(raw)
149
+ except (json.JSONDecodeError, ValueError):
150
+ parsed = {"raw_output": raw[:500]}
151
+ else:
152
+ parsed = raw if isinstance(raw, dict) else {"data": str(raw)}
153
+
154
+ # Determine severity based on module output
155
+ severity = _classify_severity(module_name, parsed)
156
+
157
+ # Store full result in data
158
+ result.data.setdefault("module_results", {})[module_name] = parsed
159
+
160
+ # Build a Finding for display
161
+ message = f"{module_name} — {severity.value}"
162
+ detail_lines = []
163
+ if isinstance(parsed, dict):
164
+ for k, v in list(parsed.items())[:5]:
165
+ detail_lines.append(f"{k}: {v}")
166
+ detail = "\n".join(detail_lines)
167
+
168
+ return Finding(
169
+ agent=self.name,
170
+ type="metasploit_aux",
171
+ severity=severity,
172
+ file="metasploit",
173
+ line=0,
174
+ message=message[:120],
175
+ detail=detail[:1000] or "No detail returned",
176
+ extra={
177
+ "module": module_name,
178
+ "target": f"{target_ip}:{target_port}",
179
+ "raw": parsed if isinstance(parsed, dict) else {"output": str(parsed)[:500]},
180
+ },
181
+ )
182
+
183
+
184
+ # ── Helpers ───────────────────────────────────────────────────────────────────
185
+
186
+
187
+ def _get_frameworks(brain: dict) -> list[str]:
188
+ """Extract framework names from brain data."""
189
+ frameworks = []
190
+ fw_raw = brain.get("framework", "")
191
+ if fw_raw and fw_raw != "Unknown":
192
+ frameworks.append(fw_raw.lower())
193
+
194
+ fws_raw = brain.get("frameworks", [])
195
+ for fw in fws_raw:
196
+ name = ""
197
+ if isinstance(fw, dict):
198
+ name = fw.get("name", "")
199
+ elif isinstance(fw, str):
200
+ name = fw
201
+ if name and name.lower() not in frameworks:
202
+ frameworks.append(name.lower())
203
+ return frameworks
204
+
205
+
206
+ def _pick_port(brain: dict, routes: list) -> int:
207
+ """Pick the most likely target port from brain/routes data."""
208
+ config_fallback = brain.get("config", {}).get("port", None)
209
+ if config_fallback:
210
+ return int(config_fallback)
211
+ return _DEFAULT_PORT
212
+
213
+
214
+ def _pick_modules(frameworks: list[str]) -> list[str]:
215
+ """Select relevant auxiliary/scanner modules based on detected frameworks."""
216
+ selected: list[str] = []
217
+ seen: set[str] = set()
218
+ for fw in frameworks:
219
+ for mod in _FRAMEWORK_MODULES.get(fw, []):
220
+ if mod not in seen:
221
+ selected.append(mod)
222
+ seen.add(mod)
223
+ if not selected:
224
+ selected = list(_FALLBACK_MODULES)
225
+ return selected
226
+
227
+
228
+ def _classify_severity(module_name: str, result: dict) -> Severity:
229
+ """Heuristic to map module results to a severity level."""
230
+ job_id = result.get("job_id")
231
+ if job_id is not None:
232
+ return Severity.INFO
233
+
234
+ raw_out = str(result).lower()
235
+ vuln_keywords = ["vulnerable", "found", "detected", "xss", "cve", "open", "leaked"]
236
+ if any(kw in raw_out for kw in vuln_keywords):
237
+ return Severity.MEDIUM
238
+
239
+ if result.get("error"):
240
+ return Severity.LOW
241
+
242
+ return Severity.INFO