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
patchi/core/config.py ADDED
@@ -0,0 +1,311 @@
1
+ """
2
+ Config system for Patchi.
3
+
4
+ Reads and writes .patchi/config.json in the current project directory.
5
+ All other modules import config through here — never read the JSON directly.
6
+ """
7
+
8
+ import json
9
+ from pathlib import Path
10
+ from typing import Any
11
+
12
+ from patchi.core.constants import (
13
+ CONFIG_FILE,
14
+ MEMORY_DIR,
15
+ MEMORY_FILES,
16
+ PATCHI_DIR,
17
+ QUEUE_FILE,
18
+ SNAPSHOT_DIR,
19
+ DeviceTier,
20
+ MemoryCategory,
21
+ Mode,
22
+ QueueMode,
23
+ RestrictionType,
24
+ )
25
+
26
+ # ── Default config ─────────────────────────────────────────────────────────────
27
+
28
+
29
+ def _default_config() -> dict:
30
+ return {
31
+ "mode": Mode.CONFIRM.value,
32
+ "queue_mode": QueueMode.SINGLE.value,
33
+ "device_tier": DeviceTier.MID.value,
34
+ "fps": 60,
35
+ "theme": "dark",
36
+ "restrictions": [],
37
+ "ignore_paths": ["node_modules", ".git", "__pycache__", ".patchi"],
38
+ "scan_depth": None,
39
+ "brain_freshness_any_change": True,
40
+ "watch_mode": False,
41
+ "risk_threshold": 30,
42
+ "max_fixes_per_cycle": None,
43
+ "dead_code_confirmation": "follow_mode",
44
+ "require_blast_radius_on_high_risk": True,
45
+ "show_confidence_scores": True,
46
+ "ai": {
47
+ "local_model_path": None,
48
+ "local_model_name": None,
49
+ "keys": [],
50
+ "cost_limit_enabled": False,
51
+ "cost_limit": None,
52
+ "cost_limit_per_run": None,
53
+ },
54
+ "notifications": [],
55
+ "quiet_hours": {
56
+ "enabled": False,
57
+ "start": "22:00",
58
+ "end": "08:00",
59
+ "timezone": "UTC",
60
+ },
61
+ "digest_frequency": "daily",
62
+ "queue_max_depth": 50,
63
+ "scan_bus": {"enabled": True, "shards": 4},
64
+ "max_scanner_agents": 8,
65
+ "max_security_agents": 19,
66
+ "max_test_agents": 3,
67
+ "onboarding_complete": False,
68
+ "pipeline": {
69
+ "enabled": True,
70
+ "interceptor": {
71
+ "enabled": True,
72
+ "mode": "asgi",
73
+ "block_threshold": 0.7,
74
+ "rate_limit": 100,
75
+ "exclude_paths": ["/health", "/metrics", "/static", "/favicon.ico"],
76
+ },
77
+ "sigma_rules_dir": ".patchi/sigma",
78
+ },
79
+ }
80
+
81
+
82
+ # ── Patchi root detection ──────────────────────────────────────────────────────
83
+
84
+
85
+ def find_project_root(start: Path | None = None) -> Path | None:
86
+ """
87
+ Walk up from start (default: cwd) looking for a .patchi directory.
88
+ Returns the project root Path if found, else None.
89
+ """
90
+ current = start or Path.cwd()
91
+ while True:
92
+ if (current / PATCHI_DIR).is_dir():
93
+ return current
94
+ parent = current.parent
95
+ if parent == current:
96
+ return None
97
+ current = parent
98
+
99
+
100
+ def require_project_root() -> Path:
101
+ """Like find_project_root but raises if not found."""
102
+ root = find_project_root()
103
+ if root is None:
104
+ raise RuntimeError("No .patchi directory found. Run 'p init' in your project folder first.")
105
+ return root
106
+
107
+
108
+ # ── Low-level JSON helpers ─────────────────────────────────────────────────────
109
+
110
+
111
+ def _config_path(root: Path) -> Path:
112
+ return root / CONFIG_FILE
113
+
114
+
115
+ def _read_raw(root: Path) -> dict:
116
+ path = _config_path(root)
117
+ if not path.exists():
118
+ return {}
119
+ with path.open("r", encoding="utf-8") as f:
120
+ return json.load(f)
121
+
122
+
123
+ def _write_raw(root: Path, data: dict) -> None:
124
+ path = _config_path(root)
125
+ path.parent.mkdir(parents=True, exist_ok=True)
126
+ with path.open("w", encoding="utf-8") as f:
127
+ json.dump(data, f, indent=2)
128
+
129
+
130
+ # ── Public API ─────────────────────────────────────────────────────────────────
131
+
132
+
133
+ def init_project(root: Path, device_tier: DeviceTier | None = None) -> dict:
134
+ """
135
+ Create the full .patchi directory structure and write default config.
136
+ Safe to call on an already-initialised project (merges, does not overwrite).
137
+ Returns the resulting config dict.
138
+ """
139
+ # Directories
140
+ for directory in [
141
+ root / PATCHI_DIR,
142
+ root / MEMORY_DIR,
143
+ root / SNAPSHOT_DIR,
144
+ ]:
145
+ directory.mkdir(parents=True, exist_ok=True)
146
+
147
+ # Memory files — touch if missing
148
+ for category, rel_path in MEMORY_FILES.items():
149
+ mem_path = root / rel_path
150
+ if not mem_path.exists():
151
+ _write_json(mem_path, _default_memory(category))
152
+
153
+ # Queue file
154
+ queue_path = root / QUEUE_FILE
155
+ if not queue_path.exists():
156
+ _write_json(queue_path, {"items": [], "paused": False})
157
+
158
+ # Config — merge defaults with existing
159
+ existing = _read_raw(root)
160
+ defaults = _default_config()
161
+ if device_tier:
162
+ defaults["device_tier"] = device_tier.value
163
+ defaults["fps"] = device_tier.default_fps()
164
+ merged = {**defaults, **existing}
165
+ _write_raw(root, merged)
166
+
167
+ return merged
168
+
169
+
170
+ def _default_memory(category: MemoryCategory) -> dict | list:
171
+ empties: dict[MemoryCategory, dict | list] = {
172
+ MemoryCategory.BRAIN: {},
173
+ MemoryCategory.PATCHES: [],
174
+ MemoryCategory.FAILED: [],
175
+ MemoryCategory.SCANS: {},
176
+ MemoryCategory.ISSUES: [],
177
+ MemoryCategory.RESTRICTIONS: [],
178
+ MemoryCategory.TOKENS: [],
179
+ MemoryCategory.LAYERS: {},
180
+ MemoryCategory.CHARTER: {},
181
+ }
182
+ return empties[category]
183
+
184
+
185
+ def _write_json(path: Path, data: Any) -> None:
186
+ path.parent.mkdir(parents=True, exist_ok=True)
187
+ with path.open("w", encoding="utf-8") as f:
188
+ json.dump(data, f, indent=2)
189
+
190
+
191
+ def load(root: Path | None = None) -> dict:
192
+ """Load config for the current project. Merges with defaults for forward compat."""
193
+ root = root or require_project_root()
194
+ raw = _read_raw(root)
195
+ return {**_default_config(), **raw}
196
+
197
+
198
+ def save(config: dict, root: Path | None = None) -> None:
199
+ """Write config back to disk."""
200
+ root = root or require_project_root()
201
+ _write_raw(root, config)
202
+
203
+
204
+ def get(key: str, root: Path | None = None) -> Any:
205
+ """Get a single top-level config value."""
206
+ return load(root)[key]
207
+
208
+
209
+ def set_value(key: str, value: Any, root: Path | None = None) -> None:
210
+ """Update a single config key and save."""
211
+ root = root or require_project_root()
212
+ config = load(root)
213
+ # Support dot-notation for nested keys (e.g. "ai.local_model_name")
214
+ parts = key.split(".")
215
+ node = config
216
+ for part in parts[:-1]:
217
+ node = node.setdefault(part, {})
218
+ node[parts[-1]] = value
219
+ save(config, root)
220
+
221
+
222
+ # ── Mode helpers ───────────────────────────────────────────────────────────────
223
+
224
+
225
+ def get_mode(root: Path | None = None) -> Mode:
226
+ return Mode(get("mode", root))
227
+
228
+
229
+ def set_mode(mode: Mode, root: Path | None = None) -> None:
230
+ set_value("mode", mode.value, root)
231
+
232
+
233
+ def get_queue_mode(root: Path | None = None) -> QueueMode:
234
+ return QueueMode(get("queue_mode", root))
235
+
236
+
237
+ def set_queue_mode(mode: QueueMode, root: Path | None = None) -> None:
238
+ set_value("queue_mode", mode.value, root)
239
+
240
+
241
+ # ── Restriction helpers ────────────────────────────────────────────────────────
242
+
243
+
244
+ def get_restrictions(root: Path | None = None) -> list[dict]:
245
+ return get("restrictions", root)
246
+
247
+
248
+ def add_restriction(
249
+ path: str, rtype: RestrictionType, reason: str = "", root: Path | None = None
250
+ ) -> None:
251
+ root = root or require_project_root()
252
+ config = load(root)
253
+ # No duplicates
254
+ existing_paths = {r["path"] for r in config["restrictions"]}
255
+ if path not in existing_paths:
256
+ config["restrictions"].append(
257
+ {
258
+ "path": path,
259
+ "type": rtype.value,
260
+ "reason": reason,
261
+ "enabled": True,
262
+ }
263
+ )
264
+ save(config, root)
265
+
266
+
267
+ def remove_restriction(path: str, root: Path | None = None) -> bool:
268
+ root = root or require_project_root()
269
+ config = load(root)
270
+ before = len(config["restrictions"])
271
+ config["restrictions"] = [r for r in config["restrictions"] if r["path"] != path]
272
+ save(config, root)
273
+ return len(config["restrictions"]) < before
274
+
275
+
276
+ def toggle_restriction(path: str, enabled: bool, root: Path | None = None) -> bool:
277
+ root = root or require_project_root()
278
+ config = load(root)
279
+ for r in config["restrictions"]:
280
+ if r["path"] == path:
281
+ r["enabled"] = enabled
282
+ save(config, root)
283
+ return True
284
+ return False
285
+
286
+
287
+ # ── Dev access token helpers ───────────────────────────────────────────────────
288
+
289
+
290
+ def add_dev_token(name: str, env_var: str, root: Path | None = None) -> None:
291
+ root = root or require_project_root()
292
+ config = load(root)
293
+ tokens = config.get("dev_tokens", [])
294
+ if not any(t["name"] == name for t in tokens):
295
+ tokens.append({"name": name, "env_var": env_var})
296
+ config["dev_tokens"] = tokens
297
+ save(config, root)
298
+
299
+
300
+ def remove_dev_token(name: str, root: Path | None = None) -> bool:
301
+ root = root or require_project_root()
302
+ config = load(root)
303
+ tokens = config.get("dev_tokens", [])
304
+ before = len(tokens)
305
+ config["dev_tokens"] = [t for t in tokens if t["name"] != name]
306
+ save(config, root)
307
+ return len(config["dev_tokens"]) < before
308
+
309
+
310
+ def list_dev_tokens(root: Path | None = None) -> list[dict]:
311
+ return load(root).get("dev_tokens", [])
@@ -0,0 +1,245 @@
1
+ """
2
+ Shared constants for Patchi.
3
+ Every magic string lives here. Nothing is scattered across modules.
4
+ """
5
+
6
+ import os
7
+ from enum import StrEnum
8
+
9
+
10
+ def is_offline() -> bool:
11
+ """True when PATCHI_OFFLINE=1 (set by `p scan --offline` / CI gate).
12
+
13
+ Offline mode is a hard contract: NO network calls of any kind — not just
14
+ AI provider calls. Network-probing agents (CVE/OSV lookups, live app
15
+ crawling, runtime validation) must honor this or `--offline` silently
16
+ leaks traffic and hangs on blocked egress.
17
+ """
18
+ return bool(os.environ.get("PATCHI_OFFLINE"))
19
+
20
+
21
+ # ── Modes ─────────────────────────────────────────────────────────────────────
22
+
23
+
24
+ class Mode(StrEnum):
25
+ CONFIRM = "confirm" # every action requires approval
26
+ AUTO = "auto" # safe fixes auto-apply, risky ones ask
27
+ AUTOPILOT = "autopilot" # full trust, Patchi decides everything
28
+
29
+ def label(self) -> str:
30
+ return self.value.upper()
31
+
32
+ def color(self) -> str:
33
+ return {"confirm": "cyan", "auto": "yellow", "autopilot": "green"}[self.value]
34
+
35
+
36
+ # ── Queue modes ────────────────────────────────────────────────────────────────
37
+
38
+
39
+ class QueueMode(StrEnum):
40
+ SINGLE = "single" # one task at a time
41
+ MULTI = "multi" # auto-scaled parallel
42
+ OFF = "off" # full speed, no queue
43
+
44
+ def description(self) -> str:
45
+ return {
46
+ "single": "One task at a time. Lowest resource use. Safe on any device.",
47
+ "multi": "Parallel tasks. Auto-scaled to your hardware.",
48
+ "off": "Full speed. Everything runs immediately.",
49
+ }[self.value]
50
+
51
+
52
+ # ── Queue item states ──────────────────────────────────────────────────────────
53
+
54
+
55
+ class QueueItemState(StrEnum):
56
+ WAITING = "waiting"
57
+ ACTIVE = "active"
58
+ DONE = "done"
59
+ FAILED = "failed"
60
+ SKIPPED = "skipped"
61
+
62
+
63
+ # ── Restriction types ──────────────────────────────────────────────────────────
64
+
65
+
66
+ class RestrictionType(StrEnum):
67
+ NO_TOUCH = "no_touch" # Patchi never reads, scans, or modifies
68
+ SCAN_ONLY = "scan_only" # read and report, never fix
69
+ SENSITIVE = "sensitive" # acknowledges existence, never reads contents
70
+
71
+
72
+ # ── Memory categories ──────────────────────────────────────────────────────────
73
+
74
+
75
+ class MemoryCategory(StrEnum):
76
+ BRAIN = "brain"
77
+ PATCHES = "patches"
78
+ FAILED = "failed"
79
+ SCANS = "scans"
80
+ ISSUES = "issues"
81
+ RESTRICTIONS = "restrictions"
82
+ TOKENS = "tokens"
83
+ LAYERS = "layers"
84
+ CHARTER = "charter"
85
+
86
+
87
+ # ── Risk levels ────────────────────────────────────────────────────────────────
88
+
89
+
90
+ class RiskLevel(StrEnum):
91
+ LOW = "low" # 0–30: safe to auto-apply
92
+ MEDIUM = "medium" # 31–60: logic changes, requires review in confirm mode
93
+ HIGH = "high" # 61–100: auth, payments, data — always ask
94
+
95
+ @staticmethod
96
+ def from_score(score: int) -> "RiskLevel":
97
+ if score <= 30:
98
+ return RiskLevel.LOW
99
+ if score <= 60:
100
+ return RiskLevel.MEDIUM
101
+ return RiskLevel.HIGH
102
+
103
+ def color(self) -> str:
104
+ return {"low": "green", "medium": "yellow", "high": "red"}[self.value]
105
+
106
+
107
+ # ── Device tiers ───────────────────────────────────────────────────────────────
108
+
109
+
110
+ class DeviceTier(StrEnum):
111
+ LOW = "low" # < 4 GB RAM
112
+ MID = "mid" # 4–16 GB
113
+ HIGH = "high" # 16 GB+
114
+
115
+ def max_parallel_agents(self) -> int:
116
+ return {"low": 3, "mid": 8, "high": 20}[self.value]
117
+
118
+ def default_fps(self) -> int:
119
+ return {"low": 30, "mid": 60, "high": 60}[self.value]
120
+
121
+ def max_brain_map_nodes(self) -> int:
122
+ return {"low": 100, "mid": 500, "high": 0}[self.value] # 0 = unlimited
123
+
124
+ def max_ants(self) -> int:
125
+ return {"low": 50, "mid": 200, "high": 0}[self.value] # 0 = unlimited
126
+
127
+
128
+ # ── Paths ──────────────────────────────────────────────────────────────────────
129
+
130
+ PATCHI_DIR = ".patchi"
131
+ CONFIG_FILE = f"{PATCHI_DIR}/config.json"
132
+ MEMORY_DIR = f"{PATCHI_DIR}/memory"
133
+ SNAPSHOT_DIR = f"{PATCHI_DIR}/snapshots"
134
+ QUEUE_FILE = f"{PATCHI_DIR}/queue.json"
135
+
136
+ MEMORY_FILES: dict[MemoryCategory, str] = {
137
+ MemoryCategory.BRAIN: f"{MEMORY_DIR}/brain.json",
138
+ MemoryCategory.PATCHES: f"{MEMORY_DIR}/patches.json",
139
+ MemoryCategory.FAILED: f"{MEMORY_DIR}/failed_patches.json",
140
+ MemoryCategory.SCANS: f"{MEMORY_DIR}/scan_results.json",
141
+ MemoryCategory.ISSUES: f"{MEMORY_DIR}/known_issues.json",
142
+ MemoryCategory.RESTRICTIONS: f"{MEMORY_DIR}/restrictions.json",
143
+ MemoryCategory.TOKENS: f"{MEMORY_DIR}/dev_tokens.json",
144
+ MemoryCategory.LAYERS: f"{MEMORY_DIR}/layers.json",
145
+ MemoryCategory.CHARTER: f"{MEMORY_DIR}/charter.json",
146
+ }
147
+
148
+ # ── Queue limits ───────────────────────────────────────────────────────────────
149
+
150
+ QUEUE_WARN_DEPTH = 40
151
+ QUEUE_MAX_DEPTH = 50
152
+
153
+ # ── AI provider registry ──────────────────────────────────────────────────────
154
+ # Single source of truth for all provider base URLs and default models.
155
+ # Every module that needs provider info imports from here.
156
+
157
+ PROVIDERS: dict[str, dict] = {
158
+ "openai": {"base_url": "https://api.openai.com/v1", "model": "gpt-4o-mini", "format": "openai"},
159
+ "anthropic": {
160
+ "base_url": "https://api.anthropic.com",
161
+ "model": "claude-sonnet-4-20250514",
162
+ "format": "anthropic",
163
+ },
164
+ "google": {
165
+ "base_url": "https://generativelanguage.googleapis.com/v1beta",
166
+ "model": "gemini-2.0-flash",
167
+ "format": "openai",
168
+ },
169
+ "groq": {
170
+ "base_url": "https://api.groq.com/openai/v1",
171
+ "model": "llama-3.3-70b-versatile",
172
+ "format": "openai",
173
+ },
174
+ "mistral": {
175
+ "base_url": "https://api.mistral.ai/v1",
176
+ "model": "mistral-small-latest",
177
+ "format": "openai",
178
+ },
179
+ "cohere": {"base_url": "https://api.cohere.ai/v2", "model": "command-r", "format": "openai"},
180
+ "together": {
181
+ "base_url": "https://api.together.xyz/v1",
182
+ "model": "meta-llama/Llama-3-70b-chat-hf",
183
+ "format": "openai",
184
+ },
185
+ "fireworks": {
186
+ "base_url": "https://api.fireworks.ai/inference/v1",
187
+ "model": "accounts/fireworks/models/llama-v3p3-70b-instruct",
188
+ "format": "openai",
189
+ },
190
+ "perplexity": {
191
+ "base_url": "https://api.perplexity.ai",
192
+ "model": "llama-3.1-sonar-small-128k-online",
193
+ "format": "openai",
194
+ },
195
+ "openrouter": {
196
+ "base_url": "https://openrouter.ai/api/v1",
197
+ "model": "meta-llama/llama-3.3-70b-instruct:free",
198
+ "format": "openai",
199
+ },
200
+ "deepseek": {
201
+ "base_url": "https://api.deepseek.com/v1",
202
+ "model": "deepseek-chat",
203
+ "format": "openai",
204
+ },
205
+ "xai": {"base_url": "https://api.x.ai/v1", "model": "grok-2", "format": "openai"},
206
+ "nvidia": {
207
+ "base_url": "https://integrate.api.nvidia.com/v1",
208
+ "model": "meta/llama-3.1-70b-instruct",
209
+ "format": "openai",
210
+ },
211
+ "huggingface": {
212
+ "base_url": "https://api-inference.huggingface.co/v1",
213
+ "model": "meta-llama/Llama-3.3-70B-Instruct",
214
+ "format": "openai",
215
+ },
216
+ "pollinations": {
217
+ "base_url": "https://gen.pollinations.ai/v1",
218
+ "model": "openai",
219
+ "format": "openai",
220
+ },
221
+ }
222
+
223
+ # ── AI defaults ───────────────────────────────────────────────────────────────
224
+
225
+ OLLAMA_BASE_URL = "http://localhost:11434"
226
+ OLLAMA_GENERATE_URL = OLLAMA_BASE_URL + "/api/generate"
227
+ OLLAMA_TAGS_URL = OLLAMA_BASE_URL + "/api/tags"
228
+ ANTHROPIC_API_VERSION = "2023-06-01"
229
+ HTTP_REQUEST_TIMEOUT = 60
230
+ HTTP_REQUEST_TIMEOUT_SHORT = 15
231
+ DEFAULT_MAX_TOKENS = 2000
232
+ DEFAULT_TEMPERATURE = 0.3
233
+
234
+ # ── Budget thresholds ─────────────────────────────────────────────────────────
235
+
236
+ BUDGET_WARN_PCT = 75
237
+ BUDGET_CRITICAL_PCT = 90
238
+
239
+ # ── Brain ──────────────────────────────────────────────────────────────────────
240
+
241
+ BRAIN_FRESHNESS_THRESHOLD = 50
242
+
243
+ # ── Misc ───────────────────────────────────────────────────────────────────────
244
+
245
+ PATCHI_VERSION = "0.7.5"
@@ -0,0 +1,25 @@
1
+ from patchi.core.debug.adapters.codelldb import CodeLLDBAdapter
2
+ from patchi.core.debug.adapters.node import NodeDebugAdapter
3
+ from patchi.core.debug.adapters.powershell import PowerShellDebugAdapter
4
+ from patchi.core.debug.adapters.python import PythonDebugAdapter
5
+ from patchi.core.debug.capture import (
6
+ DebugCapture,
7
+ capture_exception,
8
+ capture_powershell_crash,
9
+ capture_rust_crash,
10
+ debug_context_from_finding,
11
+ )
12
+ from patchi.core.debug.dap_client import DAPClient
13
+
14
+ __all__ = [
15
+ "CodeLLDBAdapter",
16
+ "DAPClient",
17
+ "DebugCapture",
18
+ "NodeDebugAdapter",
19
+ "PowerShellDebugAdapter",
20
+ "PythonDebugAdapter",
21
+ "capture_exception",
22
+ "capture_powershell_crash",
23
+ "capture_rust_crash",
24
+ "debug_context_from_finding",
25
+ ]
@@ -0,0 +1,11 @@
1
+ from patchi.core.debug.adapters.codelldb import CodeLLDBAdapter
2
+ from patchi.core.debug.adapters.node import NodeDebugAdapter
3
+ from patchi.core.debug.adapters.powershell import PowerShellDebugAdapter
4
+ from patchi.core.debug.adapters.python import PythonDebugAdapter
5
+
6
+ __all__ = [
7
+ "CodeLLDBAdapter",
8
+ "NodeDebugAdapter",
9
+ "PowerShellDebugAdapter",
10
+ "PythonDebugAdapter",
11
+ ]