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,345 @@
1
+ """
2
+ `p update` — Check for and apply updates to Patchi.
3
+
4
+ Usage:
5
+ p update — check for updates, prompt to install if newer available
6
+ p update --check — check only, no install prompt
7
+ p update --force — force reinstall/refresh current version
8
+ p update --auto — auto-install without prompting (for CI/scripts)
9
+
10
+ Auto-update check:
11
+ On startup, Patchi checks for updates silently once per week.
12
+ A notification is shown on the next command if a newer version exists.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ import logging
18
+
19
+ # ── Config ────────────────────────────────────────────────────────────────────
20
+ import os
21
+ import sys
22
+ import time
23
+ from pathlib import Path
24
+
25
+ from rich.prompt import Confirm
26
+
27
+ from patchi import __version__
28
+ from patchi.cli.console import con
29
+
30
+ UPDATE_SOURCE: dict[str, str] = {
31
+ "type": "github",
32
+ "owner": os.environ.get("PATCHI_UPDATE_OWNER", ""),
33
+ "repo": os.environ.get("PATCHI_UPDATE_REPO", "patchi"),
34
+ "pip_name": os.environ.get("PATCHI_PIP_NAME", "patchi"),
35
+ }
36
+
37
+ CHECK_FILE = ".patchi/update_check.json"
38
+ CHECK_INTERVAL_DAYS = 7
39
+
40
+
41
+ # ── Public entry points ───────────────────────────────────────────────────────
42
+
43
+
44
+ _log = logging.getLogger("patchi.cli.update_cmd")
45
+
46
+
47
+ def run(
48
+ check: bool = False,
49
+ force: bool = False,
50
+ auto: bool = False,
51
+ root: Path | None = None,
52
+ ) -> None:
53
+ """Entry point for `p update`."""
54
+ from patchi.core.config import require_project_root
55
+
56
+ try:
57
+ r = root or require_project_root()
58
+ except RuntimeError:
59
+ r = Path.cwd()
60
+
61
+ if force:
62
+ _force_reinstall(r)
63
+ return
64
+
65
+ if check:
66
+ _check_only(r)
67
+ return
68
+
69
+ # Full check + prompt to install
70
+ info = _fetch_latest(r)
71
+ if info is None:
72
+ return
73
+
74
+ latest = info.get("version", "")
75
+ if not latest or not _is_newer(latest, __version__):
76
+ con.print(f"[#4ADE80]Already up to date:[/#4ADE80] v{__version__}")
77
+ return
78
+
79
+ _print_release_info(info)
80
+ if auto:
81
+ _do_install(r, info)
82
+ else:
83
+ if Confirm.ask(f"Update to v{latest}?", default=True):
84
+ _do_install(r, info)
85
+
86
+
87
+ def run_check(root: Path | None = None) -> dict | None:
88
+ """Silent check — called from background thread. Returns update info or None."""
89
+ from patchi.core.config import require_project_root
90
+
91
+ try:
92
+ r = root or require_project_root()
93
+ except RuntimeError:
94
+ r = Path.cwd()
95
+ try:
96
+ return _fetch_latest(r, silent=True)
97
+ except Exception as e:
98
+ _log.warning("run_check failed: %s", e)
99
+ return None
100
+
101
+
102
+ # ── Auto-update check (called from main.py on startup) ────────────────────────
103
+
104
+
105
+ def auto_check_background(root: Path | None = None) -> None:
106
+ """
107
+ Background thread target: checks for updates once per week.
108
+ Stores result in .patchi/update_check.json for display on next command.
109
+ """
110
+ from patchi.core.config import require_project_root
111
+
112
+ try:
113
+ r = root or require_project_root()
114
+ except RuntimeError:
115
+ r = Path.cwd()
116
+
117
+ check_path = r / CHECK_FILE
118
+ try:
119
+ if check_path.exists():
120
+ data = json.loads(check_path.read_text(encoding="utf-8"))
121
+ last = data.get("last_check", 0)
122
+ if time.time() - last < CHECK_INTERVAL_DAYS * 86400:
123
+ return # too soon
124
+ except Exception as e:
125
+ _log.warning("auto_check_background failed: %s", e)
126
+
127
+ try:
128
+ info = _fetch_latest(r, silent=True)
129
+ if info:
130
+ check_path.parent.mkdir(parents=True, exist_ok=True)
131
+ check_path.write_text(json.dumps({**info, "last_check": time.time()}), encoding="utf-8")
132
+ except Exception as e:
133
+ _log.warning("auto_check_background failed: %s", e)
134
+
135
+
136
+ def print_update_available_if_needed(root: Path | None = None) -> None:
137
+ """Called by main.py after command dispatch — shows notification if update available."""
138
+ from patchi.core.config import require_project_root
139
+
140
+ try:
141
+ r = root or require_project_root()
142
+ except RuntimeError:
143
+ r = Path.cwd()
144
+
145
+ check_path = r / CHECK_FILE
146
+ if not check_path.exists():
147
+ return
148
+ try:
149
+ data = json.loads(check_path.read_text(encoding="utf-8"))
150
+ latest = data.get("version", "")
151
+ if latest and _is_newer(latest, __version__):
152
+ con.print(
153
+ f" [dim]Update available:[/dim] [#A78BFA]v{latest}[/#A78BFA] "
154
+ f"[dim](run 'p update')[/dim]"
155
+ )
156
+ except Exception as e:
157
+ _log.warning("print_update_available_if_needed failed: %s", e)
158
+
159
+
160
+ # ── Core logic ────────────────────────────────────────────────────────────────
161
+
162
+
163
+ def _fetch_latest(root: Path, silent: bool = False) -> dict | None:
164
+ """Fetch latest version info from GitHub releases."""
165
+ import httpx
166
+
167
+ owner = UPDATE_SOURCE.get("owner", "")
168
+ repo = UPDATE_SOURCE.get("repo", "patchi")
169
+ api_url = f"https://api.github.com/repos/{owner}/{repo}/releases/latest"
170
+
171
+ if not owner:
172
+ if not silent:
173
+ con.print("[yellow]Update source not configured yet.[/yellow]")
174
+ con.print("[dim]Set the PATCHI_UPDATE_OWNER environment variable.[/dim]")
175
+ return None
176
+
177
+ try:
178
+ resp = httpx.get(api_url, timeout=10, follow_redirects=True)
179
+ resp.raise_for_status()
180
+ data = resp.json()
181
+ tag = data.get("tag_name", "").lstrip("v")
182
+ return {
183
+ "version": tag,
184
+ "tag_name": data.get("tag_name", ""),
185
+ "release_url": data.get("html_url", ""),
186
+ "body": (data.get("body", "") or "")[:500],
187
+ "assets": data.get("assets", []),
188
+ }
189
+ except httpx.HTTPStatusError as e:
190
+ if e.response.status_code == 403:
191
+ if not silent:
192
+ con.print("[yellow]GitHub API rate limit hit. Try again later.[/yellow]")
193
+ elif e.response.status_code == 404:
194
+ if not silent:
195
+ con.print("[yellow]No releases found yet.[/yellow]")
196
+ else:
197
+ if not silent:
198
+ con.print(f"[red]Failed to check updates: {e}[/red]")
199
+ except httpx.RequestError as e:
200
+ if not silent:
201
+ con.print(f"[yellow]Could not reach GitHub: {e}[/yellow]")
202
+ except Exception as e:
203
+ if not silent:
204
+ con.print(f"[red]Update check failed: {e}[/red]")
205
+ return None
206
+
207
+
208
+ def _is_newer(latest: str, current: str) -> bool:
209
+ """Return True if latest > current (semver comparison)."""
210
+ try:
211
+ l_parts = [int(x) for x in latest.split(".")]
212
+ c_parts = [int(x) for x in current.split(".")]
213
+ # Pad to same length
214
+ while len(l_parts) < 3:
215
+ l_parts.append(0)
216
+ while len(c_parts) < 3:
217
+ c_parts.append(0)
218
+ return l_parts > c_parts
219
+ except (ValueError, AttributeError):
220
+ # Fall back to string comparison
221
+ return latest > current
222
+
223
+
224
+ # ── UI helpers ────────────────────────────────────────────────────────────────
225
+
226
+
227
+ def _print_release_info(info: dict) -> None:
228
+ """Print release details."""
229
+ version = info.get("version", "?")
230
+ body = (info.get("body") or "")[:300]
231
+ url = info.get("release_url", "")
232
+
233
+ con.print()
234
+ con.print(
235
+ f"[bold #A78BFA]Update available:[/bold #A78BFA] v{__version__} [dim]→[/dim] [bold]v{version}[/bold]"
236
+ )
237
+ if body:
238
+ con.print()
239
+ for line in body.splitlines()[:8]:
240
+ con.print(f" [dim]{line}[/dim]")
241
+ if url:
242
+ con.print()
243
+ con.print(f" [link={url}]{url}[/link]")
244
+ con.print()
245
+
246
+
247
+ def _check_only(root: Path) -> None:
248
+ """Just check, no install."""
249
+ info = _fetch_latest(root)
250
+ if info is None:
251
+ return
252
+
253
+ latest = info.get("version", "")
254
+ if not latest or _is_newer(latest, __version__):
255
+ con.print(f"[#4ADE80]Already up to date:[/#4ADE80] v{__version__}")
256
+ else:
257
+ _print_release_info(info)
258
+
259
+
260
+ # ── Install logic ─────────────────────────────────────────────────────────────
261
+
262
+
263
+ def _do_install(root: Path, info: dict) -> None:
264
+ """Download and install the latest version."""
265
+ from patchi.cli.display.live_progress import LiveProgress
266
+
267
+ pip_name = UPDATE_SOURCE.get("pip_name", "patchi")
268
+ version = info.get("version", "")
269
+
270
+ lp = LiveProgress(con, title="Updating")
271
+ lp.start()
272
+ lp.log(f" Updating to v{version} via pip…")
273
+ lp.update()
274
+
275
+ try:
276
+ import subprocess
277
+
278
+ result = subprocess.run(
279
+ [sys.executable, "-m", "pip", "install", "--upgrade", pip_name],
280
+ capture_output=True,
281
+ text=True,
282
+ timeout=120,
283
+ )
284
+ if result.returncode == 0:
285
+ lp.log(" [#4ADE80]Update complete![/#4ADE80]")
286
+ lp.update()
287
+ lp.stop(summary=f"Updated to v{version}")
288
+
289
+ # Clear cached check so next run re-verifies
290
+ check_path = root / CHECK_FILE
291
+ if check_path.exists():
292
+ check_path.unlink()
293
+
294
+ con.print()
295
+ con.print(
296
+ f"[#4ADE80]✓[/#4ADE80] Patchi updated to [bold]v{version}[/bold]. "
297
+ "[dim]Restart your shell to use the new version.[/dim]"
298
+ )
299
+ else:
300
+ lp.log(f" [red]pip install failed: {result.stderr[:200]}[/red]")
301
+ lp.stop(summary="Update failed")
302
+ con.print(f"[red]Update failed:[/red] {result.stderr[:300]}")
303
+ except FileNotFoundError:
304
+ lp.stop(summary="pip not found")
305
+ con.print("[red]pip not found. Install pip first, then run:[/red]")
306
+ con.print(f" [bold]pip install --upgrade {pip_name}[/bold]")
307
+ except subprocess.TimeoutExpired:
308
+ lp.stop(summary="pip timed out")
309
+ con.print("[red]pip install timed out after 120s.[/red]")
310
+ except Exception as e:
311
+ lp.stop(summary=f"Update failed: {e}")
312
+ con.print(f"[red]Update failed: {e}[/red]")
313
+
314
+
315
+ def _force_reinstall(root: Path) -> None:
316
+ """Force reinstall current version (--force)."""
317
+ pip_name = UPDATE_SOURCE.get("pip_name", "patchi")
318
+ from patchi.cli.display.live_progress import LiveProgress
319
+
320
+ lp = LiveProgress(con, title="Reinstalling")
321
+ lp.start()
322
+ lp.log(f" Reinstalling {pip_name} v{__version__}…")
323
+ lp.update()
324
+
325
+ try:
326
+ import subprocess
327
+
328
+ result = subprocess.run(
329
+ [sys.executable, "-m", "pip", "install", "--force-reinstall", pip_name],
330
+ capture_output=True,
331
+ text=True,
332
+ timeout=120,
333
+ )
334
+ if result.returncode == 0:
335
+ lp.stop(summary=f"Reinstalled v{__version__}")
336
+ con.print(f"[#4ADE80]✓[/#4ADE80] Patchi v{__version__} reinstalled.")
337
+ else:
338
+ lp.stop(summary="Reinstall failed")
339
+ con.print(f"[red]Reinstall failed:[/red] {result.stderr[:300]}")
340
+ except FileNotFoundError:
341
+ lp.stop(summary="pip not found")
342
+ con.print("[red]pip not found.[/red]")
343
+ except Exception as e:
344
+ lp.stop(summary=f"Reinstall failed: {e}")
345
+ con.print(f"[red]Reinstall failed: {e}[/red]")
@@ -0,0 +1,56 @@
1
+ """
2
+ `p verify` — Self-Report Verifier (Dream Assistant spec, priority #1).
3
+
4
+ Independently re-runs the project's real tests (+ scan) and reports the truth
5
+ instead of trusting a "tests pass" claim. Flags regressions vs the last baseline.
6
+
7
+ p verify — re-run tests + scan, diff vs baseline, report
8
+ p verify --no-scan — only re-run tests
9
+ p verify --claim "tests pass" — assert a specific claim against actual truth
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from pathlib import Path
15
+
16
+ from rich.panel import Panel
17
+
18
+ from patchi.cli.console import con
19
+ from patchi.core.brain.verify import claim_holds, verify_project
20
+ from patchi.core.config import require_project_root
21
+
22
+
23
+ def run(
24
+ no_scan: bool = False,
25
+ claim: str | None = None,
26
+ root: Path | None = None,
27
+ ) -> None:
28
+ try:
29
+ r = root or require_project_root()
30
+ except RuntimeError as e:
31
+ con.print(f"[red]{e}[/red]")
32
+ return
33
+
34
+ con.print()
35
+ con.print("[dim]Independently re-running tests (ignoring any self-report)…[/dim]")
36
+ report = verify_project(r, run_scan=not no_scan)
37
+
38
+ title = "[bold #C8621A]Verification[/bold #C8621A]"
39
+ con.print(Panel(report.summary, title=title, border_style="#2A3D28"))
40
+
41
+ if report.regression and report.regression.get("has_baseline"):
42
+ res = report.regression.get("resolved_failures")
43
+ if res:
44
+ con.print(f"[dim]{len(res)} previously-failing test(s) now pass.[/dim]")
45
+
46
+ if claim is not None:
47
+ ok = claim_holds(claim, report)
48
+ verdict = "[#4ADE80]TRUE[/#4ADE80]" if ok else "[#FACC15]FALSE[/#FACC15]"
49
+ con.print()
50
+ con.print(f'[bold]Claim:[/bold] "{claim}" → holds: {verdict}')
51
+ if not ok:
52
+ con.print(
53
+ "[dim]Do not report this as done. Fix and re-run [bold]p verify[/bold].[/dim]"
54
+ )
55
+
56
+ con.print()