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.
- patchi/__init__.py +1 -0
- patchi/__main__.py +13 -0
- patchi/cli/__init__.py +0 -0
- patchi/cli/command_families.py +235 -0
- patchi/cli/commands/__init__.py +0 -0
- patchi/cli/commands/access_cmd.py +65 -0
- patchi/cli/commands/agent_stats_cmd.py +273 -0
- patchi/cli/commands/agents_cmd.py +187 -0
- patchi/cli/commands/ai_cmd.py +308 -0
- patchi/cli/commands/assure_cmd.py +538 -0
- patchi/cli/commands/audit_cmd.py +286 -0
- patchi/cli/commands/auto_cmd.py +110 -0
- patchi/cli/commands/blame_cmd.py +53 -0
- patchi/cli/commands/chains_cmd.py +327 -0
- patchi/cli/commands/charter_cmd.py +173 -0
- patchi/cli/commands/chat_cmd.py +597 -0
- patchi/cli/commands/check_cmd.py +232 -0
- patchi/cli/commands/cleanup_cmd.py +328 -0
- patchi/cli/commands/cockpit_cmd.py +208 -0
- patchi/cli/commands/commands_cmd.py +160 -0
- patchi/cli/commands/cross_repo_cmd.py +113 -0
- patchi/cli/commands/deps_cmd.py +110 -0
- patchi/cli/commands/dev_check_cmd.py +342 -0
- patchi/cli/commands/dev_cmd.py +445 -0
- patchi/cli/commands/doctor_cmd.py +457 -0
- patchi/cli/commands/findings_cmd.py +187 -0
- patchi/cli/commands/fix_cmd.py +648 -0
- patchi/cli/commands/fix_review_cmd.py +273 -0
- patchi/cli/commands/heatmap_cmd.py +62 -0
- patchi/cli/commands/help_cmd.py +159 -0
- patchi/cli/commands/hosted_cmd.py +980 -0
- patchi/cli/commands/init.py +456 -0
- patchi/cli/commands/key_cmd.py +571 -0
- patchi/cli/commands/learn_cmd.py +140 -0
- patchi/cli/commands/link_cmd.py +104 -0
- patchi/cli/commands/log_cmd.py +57 -0
- patchi/cli/commands/memory_cmd.py +215 -0
- patchi/cli/commands/model_cmd.py +207 -0
- patchi/cli/commands/notify_cmd.py +213 -0
- patchi/cli/commands/notify_prompts.py +29 -0
- patchi/cli/commands/patch_cmd.py +231 -0
- patchi/cli/commands/plan_cmd.py +128 -0
- patchi/cli/commands/plugins_cmd.py +307 -0
- patchi/cli/commands/queue_cmd.py +152 -0
- patchi/cli/commands/quick_cmd.py +159 -0
- patchi/cli/commands/ready_cmd.py +292 -0
- patchi/cli/commands/report_cmd.py +416 -0
- patchi/cli/commands/restrict_cmd.py +127 -0
- patchi/cli/commands/review_cmd.py +225 -0
- patchi/cli/commands/rules_cmd.py +233 -0
- patchi/cli/commands/scan_cmd.py +1908 -0
- patchi/cli/commands/settings_cmd.py +45 -0
- patchi/cli/commands/status_cmd.py +679 -0
- patchi/cli/commands/test_cmd.py +1052 -0
- patchi/cli/commands/trend_cmd.py +296 -0
- patchi/cli/commands/undo_cmd.py +235 -0
- patchi/cli/commands/update_cmd.py +345 -0
- patchi/cli/commands/verify_cmd.py +56 -0
- patchi/cli/commands/vr_cmd.py +440 -0
- patchi/cli/commands/watch_cmd.py +304 -0
- patchi/cli/commands/web_cmd.py +114 -0
- patchi/cli/console.py +101 -0
- patchi/cli/display/__init__.py +1 -0
- patchi/cli/display/live_audit.py +269 -0
- patchi/cli/display/live_progress.py +169 -0
- patchi/cli/framework.py +241 -0
- patchi/cli/logo.py +128 -0
- patchi/cli/main.py +222 -0
- patchi/cli/registry.py +1171 -0
- patchi/cli/style.py +68 -0
- patchi/cli/themes.py +187 -0
- patchi/cli/ux.py +444 -0
- patchi/core/__init__.py +0 -0
- patchi/core/agents/__init__.py +0 -0
- patchi/core/agents/api_fuzzer_agent.py +141 -0
- patchi/core/agents/attack_agent.py +242 -0
- patchi/core/agents/base.py +1012 -0
- patchi/core/agents/bug_predictor_agent.py +58 -0
- patchi/core/agents/build_tool_validator.py +150 -0
- patchi/core/agents/cache.py +192 -0
- patchi/core/agents/chaos_agent.py +133 -0
- patchi/core/agents/cicd_generator.py +240 -0
- patchi/core/agents/comment_scanner.py +280 -0
- patchi/core/agents/console_logging_agent.py +156 -0
- patchi/core/agents/coordinator.py +858 -0
- patchi/core/agents/core_scanner.py +269 -0
- patchi/core/agents/coverage_prioritizer.py +181 -0
- patchi/core/agents/dead_code_hygiene.py +296 -0
- patchi/core/agents/dead_code_scanner.py +692 -0
- patchi/core/agents/dependency_scanner.py +725 -0
- patchi/core/agents/doc_claim_agent.py +573 -0
- patchi/core/agents/duplicate_scanner.py +568 -0
- patchi/core/agents/env_scanner.py +410 -0
- patchi/core/agents/feature_flag_agent.py +89 -0
- patchi/core/agents/frontend_framework_agent.py +133 -0
- patchi/core/agents/goroutine_agent.py +82 -0
- patchi/core/agents/governor.py +1972 -0
- patchi/core/agents/i18n_agent.py +95 -0
- patchi/core/agents/license_compliance.py +247 -0
- patchi/core/agents/linking_agent.py +251 -0
- patchi/core/agents/memory_profiler_agent.py +102 -0
- patchi/core/agents/modernization_agent.py +84 -0
- patchi/core/agents/mutation_agent.py +174 -0
- patchi/core/agents/nl_query_agent.py +74 -0
- patchi/core/agents/promise_rejection_agent.py +100 -0
- patchi/core/agents/refactoring_agent.py +286 -0
- patchi/core/agents/resource_leak_agent.py +91 -0
- patchi/core/agents/route_graph_scanner.py +951 -0
- patchi/core/agents/run_agent.py +106 -0
- patchi/core/agents/rust_unwrap_agent.py +100 -0
- patchi/core/agents/sbom_generator.py +284 -0
- patchi/core/agents/scanners.py +67 -0
- patchi/core/agents/side/__init__.py +1 -0
- patchi/core/agents/side/build_agent.py +65 -0
- patchi/core/agents/side/format_agent.py +50 -0
- patchi/core/agents/side/install_agent.py +63 -0
- patchi/core/agents/side_file_scanner.py +549 -0
- patchi/core/agents/snapshot_drift_detector.py +146 -0
- patchi/core/agents/spa_route_inventory.py +203 -0
- patchi/core/agents/test_scanner.py +442 -0
- patchi/core/agents/tool_health.py +109 -0
- patchi/core/agents/tool_runner.py +162 -0
- patchi/core/agents/type_scanner.py +168 -0
- patchi/core/agents/ui_scanner.py +558 -0
- patchi/core/ai/__init__.py +20 -0
- patchi/core/ai/agent_audit.py +153 -0
- patchi/core/ai/agent_profiler.py +277 -0
- patchi/core/ai/client.py +499 -0
- patchi/core/ai/cost_tracker.py +107 -0
- patchi/core/ai/model_router.py +318 -0
- patchi/core/ai/orchestrator.py +625 -0
- patchi/core/ai/prompts.py +681 -0
- patchi/core/ai/smart.py +302 -0
- patchi/core/ai/tool_executor.py +24 -0
- patchi/core/ai/tools/__init__.py +10 -0
- patchi/core/ai/tools/executor.py +621 -0
- patchi/core/ai/tools/realize.py +1160 -0
- patchi/core/ai/tools/registry.py +1577 -0
- patchi/core/assurance/__init__.py +33 -0
- patchi/core/assurance/builder.py +211 -0
- patchi/core/assurance/graph.py +342 -0
- patchi/core/assurance/invariants.py +168 -0
- patchi/core/atomic.py +61 -0
- patchi/core/attackers/__init__.py +17 -0
- patchi/core/attackers/api_abuse.py +89 -0
- patchi/core/attackers/auth_bypass.py +73 -0
- patchi/core/attackers/base.py +91 -0
- patchi/core/attackers/business_logic.py +88 -0
- patchi/core/attackers/planner.py +108 -0
- patchi/core/attackers/priv_escalation.py +88 -0
- patchi/core/attackers/recon.py +87 -0
- patchi/core/brain/__init__.py +0 -0
- patchi/core/brain/ast_utils/__init__.py +81 -0
- patchi/core/brain/ast_utils/assignments.py +219 -0
- patchi/core/brain/ast_utils/calls.py +139 -0
- patchi/core/brain/ast_utils/config.py +132 -0
- patchi/core/brain/ast_utils/control_flow.py +74 -0
- patchi/core/brain/ast_utils/dead_symbols.py +205 -0
- patchi/core/brain/ast_utils/decorators.py +108 -0
- patchi/core/brain/ast_utils/helpers.py +144 -0
- patchi/core/brain/ast_utils/imports.py +169 -0
- patchi/core/brain/ast_utils/scan.py +143 -0
- patchi/core/brain/ast_utils/taint.py +310 -0
- patchi/core/brain/audit.py +379 -0
- patchi/core/brain/baseline.py +195 -0
- patchi/core/brain/blast_radius.py +312 -0
- patchi/core/brain/body_tags.py +144 -0
- patchi/core/brain/brain.py +1161 -0
- patchi/core/brain/brain_context.py +393 -0
- patchi/core/brain/brain_watcher.py +340 -0
- patchi/core/brain/charter.py +473 -0
- patchi/core/brain/classifier.py +214 -0
- patchi/core/brain/cockpit.py +350 -0
- patchi/core/brain/code_query.py +710 -0
- patchi/core/brain/contract.py +889 -0
- patchi/core/brain/contract_diff.py +155 -0
- patchi/core/brain/council.py +800 -0
- patchi/core/brain/cross_repo.py +104 -0
- patchi/core/brain/dead_code_tools.py +157 -0
- patchi/core/brain/doc_validator.py +197 -0
- patchi/core/brain/domain_activator.py +2183 -0
- patchi/core/brain/enriched_context.py +220 -0
- patchi/core/brain/file_corpus.py +220 -0
- patchi/core/brain/framework.py +953 -0
- patchi/core/brain/freshness.py +273 -0
- patchi/core/brain/git_aware.py +206 -0
- patchi/core/brain/heatmap.py +104 -0
- patchi/core/brain/ignore_parser.py +153 -0
- patchi/core/brain/import_graph.py +486 -0
- patchi/core/brain/languages.py +397 -0
- patchi/core/brain/layered_brain.py +419 -0
- patchi/core/brain/learning.py +229 -0
- patchi/core/brain/orphaned_endpoints.py +313 -0
- patchi/core/brain/personas/__init__.py +648 -0
- patchi/core/brain/personas/bad_user.py +165 -0
- patchi/core/brain/personas/base.py +349 -0
- patchi/core/brain/proactive.py +807 -0
- patchi/core/brain/project_context.py +121 -0
- patchi/core/brain/project_reader.py +521 -0
- patchi/core/brain/reasoning.py +269 -0
- patchi/core/brain/route_detector/__init__.py +15 -0
- patchi/core/brain/route_detector/base.py +31 -0
- patchi/core/brain/route_detector/csharp.py +209 -0
- patchi/core/brain/route_detector/file_based.py +81 -0
- patchi/core/brain/route_detector/go.py +152 -0
- patchi/core/brain/route_detector/java.py +195 -0
- patchi/core/brain/route_detector/javascript.py +197 -0
- patchi/core/brain/route_detector/php.py +158 -0
- patchi/core/brain/route_detector/python.py +193 -0
- patchi/core/brain/route_detector/registry.py +25 -0
- patchi/core/brain/route_detector/ruby.py +134 -0
- patchi/core/brain/route_detector/rust.py +216 -0
- patchi/core/brain/route_detector/swift.py +118 -0
- patchi/core/brain/route_mapper.py +265 -0
- patchi/core/brain/scanner.py +2136 -0
- patchi/core/brain/secrets.py +280 -0
- patchi/core/brain/symbol_graph.py +1955 -0
- patchi/core/brain/team.py +28 -0
- patchi/core/brain/trace_log.py +132 -0
- patchi/core/brain/type_checker/__init__.py +65 -0
- patchi/core/brain/type_checker/base.py +60 -0
- patchi/core/brain/type_checker/csharp.py +59 -0
- patchi/core/brain/type_checker/dart.py +59 -0
- patchi/core/brain/type_checker/go.py +81 -0
- patchi/core/brain/type_checker/java.py +75 -0
- patchi/core/brain/type_checker/kotlin.py +75 -0
- patchi/core/brain/type_checker/php.py +88 -0
- patchi/core/brain/type_checker/python.py +87 -0
- patchi/core/brain/type_checker/rust.py +81 -0
- patchi/core/brain/type_checker/swift.py +59 -0
- patchi/core/brain/type_checker/typescript.py +298 -0
- patchi/core/brain/understander.py +130 -0
- patchi/core/brain/verify.py +379 -0
- patchi/core/campaigns/__init__.py +14 -0
- patchi/core/campaigns/base.py +62 -0
- patchi/core/campaigns/data_flow_abuse.py +153 -0
- patchi/core/campaigns/orchestrator.py +140 -0
- patchi/core/campaigns/state_transitions.py +178 -0
- patchi/core/ci_bundle.py +104 -0
- patchi/core/config.py +311 -0
- patchi/core/constants.py +245 -0
- patchi/core/debug/__init__.py +25 -0
- patchi/core/debug/adapters/__init__.py +11 -0
- patchi/core/debug/adapters/codelldb.py +379 -0
- patchi/core/debug/adapters/node.py +222 -0
- patchi/core/debug/adapters/powershell.py +210 -0
- patchi/core/debug/adapters/python.py +244 -0
- patchi/core/debug/capture.py +210 -0
- patchi/core/debug/dap_client.py +268 -0
- patchi/core/detector/__init__.py +0 -0
- patchi/core/detector/audit.py +194 -0
- patchi/core/detector/bus.py +226 -0
- patchi/core/detector/dispatcher.py +275 -0
- patchi/core/detector/event.py +254 -0
- patchi/core/detector/sigma_engine.py +378 -0
- patchi/core/detector/triage.py +289 -0
- patchi/core/export/sarif.py +113 -0
- patchi/core/fix/__init__.py +17 -0
- patchi/core/fix/applier.py +574 -0
- patchi/core/fix/base.py +510 -0
- patchi/core/fix/code_fixer.py +169 -0
- patchi/core/fix/dead_code_remover.py +131 -0
- patchi/core/fix/fix_agents.py +775 -0
- patchi/core/fix/patch.py +444 -0
- patchi/core/fix/risk_gate.py +383 -0
- patchi/core/fix/security_fixer.py +93 -0
- patchi/core/fix/verify_loop.py +204 -0
- patchi/core/fuzz/__init__.py +8 -0
- patchi/core/fuzz/corpus.py +137 -0
- patchi/core/fuzz/input_fuzzer.py +256 -0
- patchi/core/fuzz/sequence_fuzzer.py +162 -0
- patchi/core/fuzz/state_fuzzer.py +236 -0
- patchi/core/health.py +407 -0
- patchi/core/hosted/__init__.py +1 -0
- patchi/core/hosted/anomaly.py +298 -0
- patchi/core/hosted/audit_log.py +102 -0
- patchi/core/hosted/compliance_report.py +148 -0
- patchi/core/hosted/ip_reputation.py +169 -0
- patchi/core/hosted/log_parsers.py +251 -0
- patchi/core/hosted/tokens.py +127 -0
- patchi/core/hosted/watchlist.py +164 -0
- patchi/core/hosted/webhooks.py +156 -0
- patchi/core/memory.py +437 -0
- patchi/core/notifications/__init__.py +18 -0
- patchi/core/notifications/channels.py +192 -0
- patchi/core/notifications/digest.py +141 -0
- patchi/core/notifications/escalation.py +158 -0
- patchi/core/notifications/notifier.py +182 -0
- patchi/core/notifications/quiet_hours.py +69 -0
- patchi/core/plugins/__init__.py +48 -0
- patchi/core/plugins/analyzer.py +326 -0
- patchi/core/plugins/analyzers/__init__.py +6 -0
- patchi/core/plugins/analyzers/dead_code_analyzer.py +120 -0
- patchi/core/plugins/analyzers/secret_scanner.py +158 -0
- patchi/core/plugins/analyzers/todo_scanner.py +115 -0
- patchi/core/plugins/registry.py +335 -0
- patchi/core/queue.py +375 -0
- patchi/core/reliability/__init__.py +13 -0
- patchi/core/reliability/chaos.py +163 -0
- patchi/core/reliability/fault_injector.py +172 -0
- patchi/core/reliability/idempotency.py +128 -0
- patchi/core/reliability/recovery.py +147 -0
- patchi/core/runtime/__init__.py +5 -0
- patchi/core/runtime/tracer.py +230 -0
- patchi/core/scan_bus.py +156 -0
- patchi/core/security/__init__.py +1 -0
- patchi/core/security/ai_validator.py +462 -0
- patchi/core/security/app_mapper.py +216 -0
- patchi/core/security/app_profile.py +464 -0
- patchi/core/security/attack_feedback.py +141 -0
- patchi/core/security/attack_scenarios/__init__.py +1 -0
- patchi/core/security/attack_tree.py +176 -0
- patchi/core/security/auth_audit_agent.py +344 -0
- patchi/core/security/authz_agent.py +602 -0
- patchi/core/security/auto_fix_proactive.py +620 -0
- patchi/core/security/auto_fixer.py +660 -0
- patchi/core/security/auto_ticket.py +53 -0
- patchi/core/security/bandit_agent.py +152 -0
- patchi/core/security/blast_radius.py +226 -0
- patchi/core/security/browser_tester.py +333 -0
- patchi/core/security/business_logic_agent.py +263 -0
- patchi/core/security/catch_block_auditor.py +395 -0
- patchi/core/security/cdn_cache_agent.py +357 -0
- patchi/core/security/chain_analyzer.py +321 -0
- patchi/core/security/chain_to_assurance.py +168 -0
- patchi/core/security/charter.py +510 -0
- patchi/core/security/cloud_waf_detector.py +295 -0
- patchi/core/security/codeql_agent.py +233 -0
- patchi/core/security/compliance_agent.py +348 -0
- patchi/core/security/confidence_gate.py +423 -0
- patchi/core/security/container_scanner.py +282 -0
- patchi/core/security/crypto_agent.py +378 -0
- patchi/core/security/cve_monitor.py +262 -0
- patchi/core/security/dast_agent.py +865 -0
- patchi/core/security/defectdojo.py +238 -0
- patchi/core/security/defenders/__init__.py +75 -0
- patchi/core/security/defenders/auth_middleware.py +115 -0
- patchi/core/security/defenders/base.py +97 -0
- patchi/core/security/defenders/block_ip.py +71 -0
- patchi/core/security/defenders/block_ws_origin.py +36 -0
- patchi/core/security/defenders/crypto_fix.py +118 -0
- patchi/core/security/defenders/enforce_rate_limit.py +108 -0
- patchi/core/security/defenders/fix_code.py +93 -0
- patchi/core/security/defenders/invalidate_session.py +40 -0
- patchi/core/security/defenders/patch_config.py +70 -0
- patchi/core/security/defenders/rotate_secret.py +54 -0
- patchi/core/security/defenders/suspend_account.py +41 -0
- patchi/core/security/defenders/update_dependency.py +160 -0
- patchi/core/security/defense_layer.py +217 -0
- patchi/core/security/dependency_vulnerability_agent.py +616 -0
- patchi/core/security/detection_pipeline.py +289 -0
- patchi/core/security/dns_security_agent.py +497 -0
- patchi/core/security/domain_activator_v2.py +913 -0
- patchi/core/security/domain_loader.py +1004 -0
- patchi/core/security/domains/__init__.py +0 -0
- patchi/core/security/email_authentication_agent.py +417 -0
- patchi/core/security/env_var_validator.py +304 -0
- patchi/core/security/evidence.py +100 -0
- patchi/core/security/falco_runtime_agent.py +387 -0
- patchi/core/security/fix-playbooks/__init__.py +0 -0
- patchi/core/security/gated_finding.py +85 -0
- patchi/core/security/git_diff_activator.py +367 -0
- patchi/core/security/governance.py +208 -0
- patchi/core/security/gradual_gate.py +34 -0
- patchi/core/security/history.py +315 -0
- patchi/core/security/iac_scanner.py +250 -0
- patchi/core/security/ignore_expiry.py +111 -0
- patchi/core/security/ignore_learner.py +416 -0
- patchi/core/security/injection_agent.py +319 -0
- patchi/core/security/insecure_randomness_agent.py +288 -0
- patchi/core/security/intent_analyzer.py +326 -0
- patchi/core/security/jwt_agent.py +453 -0
- patchi/core/security/kubernetes_agent.py +638 -0
- patchi/core/security/layer2_orchestrator.py +341 -0
- patchi/core/security/llm_security_agent.py +252 -0
- patchi/core/security/misconfig_agent.py +600 -0
- patchi/core/security/mobile_security_agent.py +474 -0
- patchi/core/security/network_agent.py +376 -0
- patchi/core/security/noise_filter.py +274 -0
- patchi/core/security/orchestrator.py +313 -0
- patchi/core/security/pattern_context.py +125 -0
- patchi/core/security/pattern_loader.py +101 -0
- patchi/core/security/pentest/__init__.py +4 -0
- patchi/core/security/pentest/base.py +58 -0
- patchi/core/security/pentest/dalfox_adapter.py +40 -0
- patchi/core/security/pentest/ffuf_adapter.py +48 -0
- patchi/core/security/pentest/nuclei_adapter.py +50 -0
- patchi/core/security/pentest/registry.py +80 -0
- patchi/core/security/pentest/shannon_adapter.py +107 -0
- patchi/core/security/pentest/sqlmap_adapter.py +56 -0
- patchi/core/security/pentest/zap_adapter.py +52 -0
- patchi/core/security/plan_auditor.py +276 -0
- patchi/core/security/policy_engine.py +272 -0
- patchi/core/security/prechecks.py +172 -0
- patchi/core/security/precommit_hook.py +247 -0
- patchi/core/security/privacy_agent.py +361 -0
- patchi/core/security/push_notification_agent.py +417 -0
- patchi/core/security/pysa_agent.py +143 -0
- patchi/core/security/reasoning.py +442 -0
- patchi/core/security/red_team_agent.py +184 -0
- patchi/core/security/red_team_engine.py +1142 -0
- patchi/core/security/remediation.py +360 -0
- patchi/core/security/request_interceptor.py +294 -0
- patchi/core/security/runtime_validator.py +245 -0
- patchi/core/security/saml_sso_agent.py +401 -0
- patchi/core/security/sast_agent.py +213 -0
- patchi/core/security/sast_gate.py +95 -0
- patchi/core/security/scheduler.py +287 -0
- patchi/core/security/secrets_runtime_agent.py +476 -0
- patchi/core/security/security_agents.py +175 -0
- patchi/core/security/security_config.py +551 -0
- patchi/core/security/security_probe.py +762 -0
- patchi/core/security/security_taint.py +1005 -0
- patchi/core/security/sensitive_data_agent.py +271 -0
- patchi/core/security/service_mesh_agent.py +412 -0
- patchi/core/security/session_management_agent.py +245 -0
- patchi/core/security/ssrf_agent.py +422 -0
- patchi/core/security/supply_chain.py +449 -0
- patchi/core/security/threat_model_generator.py +378 -0
- patchi/core/security/threat_model_updater.py +196 -0
- patchi/core/security/tool_adapters.py +135 -0
- patchi/core/security/tool_verify.py +173 -0
- patchi/core/security/websocket_security_agent.py +188 -0
- patchi/core/snapshot.py +242 -0
- patchi/core/tenant.py +386 -0
- patchi/core/testing/__init__.py +17 -0
- patchi/core/testing/_browser.py +147 -0
- patchi/core/testing/ads_agent.py +141 -0
- patchi/core/testing/api_contract_agent.py +450 -0
- patchi/core/testing/app_discovery_agent.py +641 -0
- patchi/core/testing/app_launcher.py +184 -0
- patchi/core/testing/browser_test_agent.py +516 -0
- patchi/core/testing/e2e_flow_agent.py +354 -0
- patchi/core/testing/flake_detector_agent.py +292 -0
- patchi/core/testing/gate.py +31 -0
- patchi/core/testing/live_test_runner.py +304 -0
- patchi/core/testing/live_v2/__init__.py +1 -0
- patchi/core/testing/live_v2/browser_pool.py +349 -0
- patchi/core/testing/live_v2/browser_test_runner.py +313 -0
- patchi/core/testing/live_v2/runner.py +626 -0
- patchi/core/testing/live_v2/screenshot_manager.py +474 -0
- patchi/core/testing/live_v2/stress_orchestrator.py +523 -0
- patchi/core/testing/live_v2/video_recorder.py +303 -0
- patchi/core/testing/regression_agent.py +302 -0
- patchi/core/testing/security_test_agent.py +253 -0
- patchi/core/testing/stress_test_agent.py +203 -0
- patchi/core/testing/test_agents.py +50 -0
- patchi/core/testing/test_config.py +194 -0
- patchi/core/testing/ui_accessibility_agent.py +324 -0
- patchi/core/testing/ui_button_agent.py +294 -0
- patchi/core/testing/ui_layout_agent.py +330 -0
- patchi/core/testing/unit_test_agent.py +1149 -0
- patchi/core/testing/visual_regression_agent.py +260 -0
- patchi/web/__init__.py +1 -0
- patchi/web/api/__init__.py +1 -0
- patchi/web/api/brain_map.py +114 -0
- patchi/web/api/charts.py +47 -0
- patchi/web/api/chat.py +224 -0
- patchi/web/api/cicd.py +576 -0
- patchi/web/api/dast_evidence.py +49 -0
- patchi/web/api/dev_check.py +320 -0
- patchi/web/api/fix.py +134 -0
- patchi/web/api/guard.py +65 -0
- patchi/web/api/hosted.py +128 -0
- patchi/web/api/hosted_v2.py +234 -0
- patchi/web/api/live_testing.py +699 -0
- patchi/web/api/scan.py +582 -0
- patchi/web/api/smart.py +111 -0
- patchi/web/api/tenant.py +117 -0
- patchi/web/api/tools.py +85 -0
- patchi/web/api_legacy.py +2401 -0
- patchi/web/app.py +310 -0
- patchi/web/events.py +483 -0
- patchi/web/routes/__init__.py +1 -0
- patchi/web/routes/assurance.py +541 -0
- patchi/web/routes/brain.py +36 -0
- patchi/web/routes/charter.py +227 -0
- patchi/web/routes/chat.py +23 -0
- patchi/web/routes/dashboard.py +558 -0
- patchi/web/routes/dashboard_v2.py +402 -0
- patchi/web/routes/findings.py +330 -0
- patchi/web/routes/guard.py +35 -0
- patchi/web/routes/history.py +126 -0
- patchi/web/routes/landing.py +52 -0
- patchi/web/routes/live_testing.py +24 -0
- patchi/web/routes/review.py +57 -0
- patchi/web/routes/self_improvement.py +110 -0
- patchi/web/routes/settings.py +49 -0
- patchi/web/routes/tokens.py +29 -0
- patchi/web/spawn.py +139 -0
- patchi/web/ws.py +141 -0
- patchi-0.7.5.dist-info/METADATA +315 -0
- patchi-0.7.5.dist-info/RECORD +496 -0
- patchi-0.7.5.dist-info/WHEEL +5 -0
- patchi-0.7.5.dist-info/licenses/LICENSE +60 -0
- patchi-0.7.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
"""
|
|
2
|
+
`p dev` — Developer utilities, testing docs, and diagnostics.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
p dev — show all development info
|
|
6
|
+
p dev info — show project health, config, security status
|
|
7
|
+
p dev test — show testing tool documentation
|
|
8
|
+
p dev playwright — show Playwright/browser testing docs
|
|
9
|
+
p dev security — show security pipeline status
|
|
10
|
+
p dev docs — show all CLI commands reference
|
|
11
|
+
p dev hook — install pre-commit hook (ruff + pytest + scan --changed)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
|
|
18
|
+
from rich.console import Console
|
|
19
|
+
from rich.panel import Panel
|
|
20
|
+
from rich.table import Table
|
|
21
|
+
|
|
22
|
+
from patchi.cli.console import con
|
|
23
|
+
from patchi.core import config as cfg
|
|
24
|
+
from patchi.core.agents.base import AgentGroup, list_agents
|
|
25
|
+
|
|
26
|
+
_log = logging.getLogger("patchi.cli.dev_cmd")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def run(action: str | None = None, verbose: bool = False, json_output: bool = False, strict: bool = False, auto_fix: bool = False, fast: bool = False) -> None:
|
|
30
|
+
|
|
31
|
+
if action == "test":
|
|
32
|
+
_show_test_docs(con)
|
|
33
|
+
elif action == "playwright":
|
|
34
|
+
_show_playwright_docs(con)
|
|
35
|
+
elif action == "security":
|
|
36
|
+
_show_security_status(con)
|
|
37
|
+
elif action == "docs":
|
|
38
|
+
_show_cli_reference(con)
|
|
39
|
+
elif action == "hook":
|
|
40
|
+
_install_hook(con, strict=strict, auto_fix=auto_fix)
|
|
41
|
+
elif action == "check":
|
|
42
|
+
from patchi.cli.commands.dev_check_cmd import run as check_run
|
|
43
|
+
check_run(json_output=json_output, fast=fast)
|
|
44
|
+
else:
|
|
45
|
+
_show_dev_overview(con, verbose)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _show_dev_overview(con: Console, verbose: bool) -> None:
|
|
49
|
+
con.print()
|
|
50
|
+
con.print(Panel.fit("[bold cyan]Patchi Developer Console[/bold cyan]", border_style="cyan"))
|
|
51
|
+
con.print()
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
root = cfg.require_project_root()
|
|
55
|
+
config = cfg.load(root)
|
|
56
|
+
except Exception as e:
|
|
57
|
+
_log.warning("_show_dev_overview failed: %s", e)
|
|
58
|
+
root = None
|
|
59
|
+
config = {}
|
|
60
|
+
|
|
61
|
+
info = Table.grid(padding=(0, 2))
|
|
62
|
+
info.add_column()
|
|
63
|
+
info.add_column()
|
|
64
|
+
|
|
65
|
+
info.add_row("[bold]Project Root:[/bold]", str(root or "Not initialized"))
|
|
66
|
+
mode = config.get("mode", "unknown")
|
|
67
|
+
info.add_row("[bold]Mode:[/bold]", mode)
|
|
68
|
+
pipeline_enabled = config.get("pipeline", {}).get("enabled", False)
|
|
69
|
+
info.add_row("[bold]Security Pipeline:[/bold]", "ENABLED" if pipeline_enabled else "DISABLED")
|
|
70
|
+
interceptor_enabled = config.get("pipeline", {}).get("interceptor", {}).get("enabled", False)
|
|
71
|
+
info.add_row(
|
|
72
|
+
"[bold]Request Interceptor:[/bold]", "ENABLED" if interceptor_enabled else "DISABLED"
|
|
73
|
+
)
|
|
74
|
+
ai_keys = config.get("ai", {}).get("keys", [])
|
|
75
|
+
info.add_row("[bold]AI Keys:[/bold]", f"{len(ai_keys)} configured")
|
|
76
|
+
info.add_row("[bold]Agent Queue:[/bold]", config.get("queue_mode", "single"))
|
|
77
|
+
info.add_row("[bold]Version:[/bold]", _get_version())
|
|
78
|
+
con.print(info)
|
|
79
|
+
con.print()
|
|
80
|
+
|
|
81
|
+
_show_quick_commands(con)
|
|
82
|
+
con.print()
|
|
83
|
+
con.print(
|
|
84
|
+
"[dim]Run [bold]p dev test[/bold] for testing docs, [bold]p dev security[/bold] for security status, [bold]p dev docs[/bold] for all commands[/dim]"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _show_quick_commands(con: Console) -> None:
|
|
89
|
+
t = Table(title="Quick Reference", box=None)
|
|
90
|
+
t.add_column("Command", style="cyan")
|
|
91
|
+
t.add_column("Description")
|
|
92
|
+
t.add_row("p dev test", "Show all testing tools and commands")
|
|
93
|
+
t.add_row("p dev playwright", "Show Playwright/browser testing docs")
|
|
94
|
+
t.add_row("p dev security", "Show security pipeline status")
|
|
95
|
+
t.add_row("p dev docs", "Show all CLI commands reference")
|
|
96
|
+
t.add_row("p scan", "Run a full scan")
|
|
97
|
+
t.add_row("p scan --pipeline", "Run scan with full security pipeline")
|
|
98
|
+
t.add_row("p security all", "Run all 34 security agents")
|
|
99
|
+
t.add_row("p test full", "Run all test agents")
|
|
100
|
+
t.add_row("p test smoke", "Quick smoke test (buttons + layout + a11y)")
|
|
101
|
+
t.add_row("p test e2e", "AI-generated Playwright E2E tests")
|
|
102
|
+
t.add_row("p web", "Launch the Patchi web dashboard")
|
|
103
|
+
t.add_row("p doctor", "Validate setup and dependencies")
|
|
104
|
+
t.add_row("p audit", "Full project audit in one shot")
|
|
105
|
+
con.print(t)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _show_test_docs(con: Console) -> None:
|
|
109
|
+
con.print()
|
|
110
|
+
con.print(
|
|
111
|
+
Panel.fit("[bold yellow]Testing Tools Reference[/bold yellow]", border_style="yellow")
|
|
112
|
+
)
|
|
113
|
+
con.print()
|
|
114
|
+
|
|
115
|
+
t = Table(title="Test Commands")
|
|
116
|
+
t.add_column("Command", style="cyan")
|
|
117
|
+
t.add_column("Type")
|
|
118
|
+
t.add_column("Description")
|
|
119
|
+
|
|
120
|
+
t.add_row("p test", "default", "Run unit + regression tests")
|
|
121
|
+
t.add_row("p test unit", "unit", "Run pytest/unittest/jest/mocha tests via UnitTestAgent")
|
|
122
|
+
t.add_row(
|
|
123
|
+
"p test browser", "browser", "Run Playwright critical-flow tests via BrowserTestAgent"
|
|
124
|
+
)
|
|
125
|
+
t.add_row("p test e2e", "e2e", "AI-generated end-to-end Playwright tests via E2EFlowAgent")
|
|
126
|
+
t.add_row("p test buttons", "buttons", "Button/form/interaction tests via UIButtonAgent")
|
|
127
|
+
t.add_row(
|
|
128
|
+
"p test layout",
|
|
129
|
+
"layout",
|
|
130
|
+
"Responsive layout tests at 320/768/1024/1440px via UILayoutAgent",
|
|
131
|
+
)
|
|
132
|
+
t.add_row(
|
|
133
|
+
"p test accessibility",
|
|
134
|
+
"accessibility",
|
|
135
|
+
"WCAG a11y via axe-core injection via UIAccessibilityAgent",
|
|
136
|
+
)
|
|
137
|
+
t.add_row("p test visual", "visual", "Screenshot comparison at 3 viewports via VisualRegressionAgent")
|
|
138
|
+
t.add_row("p test api", "api", "OpenAPI/JSON Schema contract tests via APIContractAgent")
|
|
139
|
+
t.add_row("p test stress", "stress", "Locust load testing via StressTestAgent")
|
|
140
|
+
t.add_row(
|
|
141
|
+
"p test security",
|
|
142
|
+
"security",
|
|
143
|
+
"Route-specific security pytest generation via SecurityTestAgent",
|
|
144
|
+
)
|
|
145
|
+
t.add_row("p test regression", "regression", "Snapshot-based regression tests via RegressionAgent")
|
|
146
|
+
t.add_row("p test smoke", "smoke", "Quick smoke: buttons + layout + accessibility")
|
|
147
|
+
t.add_row("p test full", "full", f"ALL test agents ({len(list_agents(AgentGroup.TEST))} agents)")
|
|
148
|
+
t.add_row("p test generate", "generate", "AI generates a full test suite")
|
|
149
|
+
t.add_row("p test report", "report", "Show test run history (last 50)")
|
|
150
|
+
t.add_row("p test config show", "config", "Show test configuration")
|
|
151
|
+
t.add_row("p test config set <k> <v>", "config", "Set a config value")
|
|
152
|
+
t.add_row("p security browsertest", "security", "Security-focused Playwright browser tests")
|
|
153
|
+
|
|
154
|
+
con.print(t)
|
|
155
|
+
con.print()
|
|
156
|
+
|
|
157
|
+
t2 = Table(title="Test Agents (12 total)")
|
|
158
|
+
t2.add_column("Agent", style="green")
|
|
159
|
+
t2.add_column("File")
|
|
160
|
+
t2.add_column("Framework")
|
|
161
|
+
|
|
162
|
+
t2.add_row("UnitTestAgent", "unit_test_agent.py", "pytest / jest / mocha")
|
|
163
|
+
t2.add_row("BrowserTestAgent", "browser_test_agent.py", "Playwright")
|
|
164
|
+
t2.add_row("E2EFlowAgent", "e2e_flow_agent.py", "Playwright + AI")
|
|
165
|
+
t2.add_row("UIButtonAgent", "ui_button_agent.py", "Playwright")
|
|
166
|
+
t2.add_row("UILayoutAgent", "ui_layout_agent.py", "Playwright")
|
|
167
|
+
t2.add_row("UIAccessibilityAgent", "ui_accessibility_agent.py", "Playwright + axe-core")
|
|
168
|
+
t2.add_row("VisualRegressionAgent", "visual_regression_agent.py", "Playwright screenshots")
|
|
169
|
+
t2.add_row("AccessibilityAgent", "accessibility_agent.py", "Playwright + axe-core")
|
|
170
|
+
t2.add_row("APIContractAgent", "api_contract_agent.py", "OpenAPI / JSON Schema")
|
|
171
|
+
t2.add_row("RegressionAgent", "regression_agent.py", "Snapshot baselines")
|
|
172
|
+
t2.add_row("StressTestAgent", "stress_test_agent.py", "Locust")
|
|
173
|
+
t2.add_row("SecurityTestAgent", "security_test_agent.py", "pytest generation")
|
|
174
|
+
|
|
175
|
+
con.print(t2)
|
|
176
|
+
con.print()
|
|
177
|
+
|
|
178
|
+
t3 = Table(title="Security Tester", box=None)
|
|
179
|
+
t3.add_column("Tool", style="red")
|
|
180
|
+
t3.add_column("Description")
|
|
181
|
+
t3.add_row("BrowserTesterAgent (security)", "Playwright auth bypass / XSS / SQLi testing")
|
|
182
|
+
con.print(t3)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _show_playwright_docs(con: Console) -> None:
|
|
186
|
+
con.print()
|
|
187
|
+
con.print(
|
|
188
|
+
Panel.fit(
|
|
189
|
+
"[bold magenta]Playwright / Browser Testing Reference[/bold magenta]",
|
|
190
|
+
border_style="magenta",
|
|
191
|
+
)
|
|
192
|
+
)
|
|
193
|
+
con.print()
|
|
194
|
+
|
|
195
|
+
t = Table(title="Playwright Test Types")
|
|
196
|
+
t.add_column("Command", style="cyan")
|
|
197
|
+
t.add_column("What It Tests")
|
|
198
|
+
t.add_column("Viewports")
|
|
199
|
+
|
|
200
|
+
t.add_row("p test browser", "Critical flows: login, forms, navigation, API calls", "N/A")
|
|
201
|
+
t.add_row("p test e2e", "AI-generated full user flows", "N/A")
|
|
202
|
+
t.add_row("p test buttons", "Buttons, forms, hover/focus, keyboard, disabled states", "N/A")
|
|
203
|
+
t.add_row(
|
|
204
|
+
"p test layout",
|
|
205
|
+
"Responsive design, overflow, overlap, touch targets",
|
|
206
|
+
"320 / 768 / 1024 / 1440",
|
|
207
|
+
)
|
|
208
|
+
t.add_row("p test accessibility", "WCAG: contrast, alt text, labels, ARIA, landmarks", "N/A")
|
|
209
|
+
t.add_row("p test visual", "Screenshot diff detection", "375 / 768 / 1440")
|
|
210
|
+
t.add_row("p security browsertest", "Auth bypass, XSS injection, SQLi injection", "N/A")
|
|
211
|
+
|
|
212
|
+
con.print(t)
|
|
213
|
+
con.print()
|
|
214
|
+
|
|
215
|
+
con.print("[bold]Playwright Browsers:[/bold]")
|
|
216
|
+
con.print(" Playwright is a core dependency (playwright>=1.40 in pyproject.toml)")
|
|
217
|
+
con.print(" Browser binaries must be installed separately:")
|
|
218
|
+
con.print()
|
|
219
|
+
con.print(" [bold]p npm playwright install chromium[/bold] — or —")
|
|
220
|
+
con.print(" [bold]playwright install chromium[/bold] — in activated venv")
|
|
221
|
+
con.print()
|
|
222
|
+
con.print("[dim]All Playwright agents gracefully skip if Playwright is not installed.[/dim]")
|
|
223
|
+
con.print()
|
|
224
|
+
|
|
225
|
+
con.print("[bold]Web UI Events for Test Agents:[/bold]")
|
|
226
|
+
con.print(" test.suite.started — When a test run begins")
|
|
227
|
+
con.print(" test.case.passed — Individual test passed")
|
|
228
|
+
con.print(" test.case.failed — Individual test failed (screenshot on fail)")
|
|
229
|
+
con.print(" test.browser.flow_started — Browser flow started")
|
|
230
|
+
con.print(" test.browser.step_passed — Browser step passed")
|
|
231
|
+
con.print(" test.browser.step_failed — Browser step failed")
|
|
232
|
+
con.print(" test.stress.update — Load test stats")
|
|
233
|
+
con.print(" test.stress.break_found — Load test breakpoint")
|
|
234
|
+
con.print()
|
|
235
|
+
con.print("[dim]Open [bold]p web[/bold] and watch the dashboard while tests run![/dim]")
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _show_security_status(con: Console) -> None:
|
|
239
|
+
con.print()
|
|
240
|
+
con.print(Panel.fit("[bold red]Security Pipeline Status[/bold red]", border_style="red"))
|
|
241
|
+
con.print()
|
|
242
|
+
|
|
243
|
+
try:
|
|
244
|
+
root = cfg.require_project_root()
|
|
245
|
+
config = cfg.load(root)
|
|
246
|
+
except Exception as e:
|
|
247
|
+
_log.warning("_show_security_status: %s", e)
|
|
248
|
+
root = None
|
|
249
|
+
config = {}
|
|
250
|
+
|
|
251
|
+
pipeline = config.get("pipeline", {})
|
|
252
|
+
interceptor = pipeline.get("interceptor", {})
|
|
253
|
+
ai_keys = config.get("ai", {}).get("keys", [])
|
|
254
|
+
|
|
255
|
+
t = Table(box=None)
|
|
256
|
+
t.add_column("Component", style="cyan")
|
|
257
|
+
t.add_column("Status")
|
|
258
|
+
t.add_column("Detail")
|
|
259
|
+
|
|
260
|
+
t.add_row(
|
|
261
|
+
"Security Pipeline",
|
|
262
|
+
"ENABLED" if pipeline.get("enabled") else "DISABLED",
|
|
263
|
+
"DetectionPipeline + ConfidenceGate + Layer2Orchestrator + DefenseLayer",
|
|
264
|
+
)
|
|
265
|
+
t.add_row(
|
|
266
|
+
"Request Interceptor",
|
|
267
|
+
"ENABLED" if interceptor.get("enabled") else "DISABLED",
|
|
268
|
+
f"ASGI middleware, threshold={interceptor.get('block_threshold', 0.7)}, rate={interceptor.get('rate_limit', 100)}/min",
|
|
269
|
+
)
|
|
270
|
+
t.add_row(
|
|
271
|
+
"Security Agents",
|
|
272
|
+
f"{len(list_agents(AgentGroup.SECURITY))} agents",
|
|
273
|
+
"All registered via @register decorator",
|
|
274
|
+
)
|
|
275
|
+
t.add_row("ConfidenceGate", "Active", "Routes findings: defend / ai_analyze / human_review / discard")
|
|
276
|
+
t.add_row(
|
|
277
|
+
"Layer2 AI",
|
|
278
|
+
"Active" if ai_keys else "No AI keys",
|
|
279
|
+
"Batches medium-confidence findings for AI confirmation",
|
|
280
|
+
)
|
|
281
|
+
t.add_row("DefenseLayer", "Active", "Creates patches / blocks IPs / rotates secrets / escalates")
|
|
282
|
+
t.add_row("RiskGate", "Always active", "Enforces mode, no-touch paths, quiet hours, secrets gate")
|
|
283
|
+
t.add_row("Sigma Engine", "Standby", "Loaded from .patchi/sigma/ (if rules exist)")
|
|
284
|
+
t.add_row("SecretsGuard", "Always active", "Gate-checks proposed code for secrets before apply")
|
|
285
|
+
|
|
286
|
+
con.print(t)
|
|
287
|
+
con.print()
|
|
288
|
+
|
|
289
|
+
con.print("[bold]Security Commands:[/bold]")
|
|
290
|
+
con.print(" p security all — Run all 34 security scanners")
|
|
291
|
+
con.print(
|
|
292
|
+
" p security <type> — Run specific security scan (sqli, xss, jwt, crypto, etc.)"
|
|
293
|
+
)
|
|
294
|
+
con.print(" p security report — Show correlated security report")
|
|
295
|
+
con.print(" p security browsertest — Run Playwright security browser tests")
|
|
296
|
+
con.print(" p scan --pipeline — Full scan + security pipeline + auto-defense")
|
|
297
|
+
con.print(" p audit — Full project audit in one shot")
|
|
298
|
+
con.print()
|
|
299
|
+
con.print("[bold]Defense Actions:[/bold]")
|
|
300
|
+
con.print(" fix_code — Creates Patch, passes RiskGate, applies if allowed")
|
|
301
|
+
con.print(" update_dependency — Runs pip/npm update + patches manifest")
|
|
302
|
+
con.print(" block_ip — Persists to .patchi/blocked_ips.json + iptables")
|
|
303
|
+
con.print(" rotate_secret — Generates 256-bit secret, replaces in .env")
|
|
304
|
+
con.print(" patch_config — Edits config files with known-good values")
|
|
305
|
+
con.print(" auth_middleware — Adds auth middleware/decorator templates")
|
|
306
|
+
con.print(" invalidate_session — Queues to .patchi/invalidate_sessions.json")
|
|
307
|
+
con.print(" suspend_account — Queues to .patchi/suspend_accounts.json")
|
|
308
|
+
con.print(" block_ws_origin — Persists to .patchi/blocked_ws_origins.json")
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def _show_cli_reference(con: Console) -> None:
|
|
312
|
+
con.print()
|
|
313
|
+
con.print(
|
|
314
|
+
Panel.fit(
|
|
315
|
+
"[bold green]Patchi CLI Reference — All Commands[/bold green]", border_style="green"
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
con.print()
|
|
319
|
+
|
|
320
|
+
t = Table(box=None)
|
|
321
|
+
t.add_column("Command", style="cyan", width=20)
|
|
322
|
+
t.add_column("Description")
|
|
323
|
+
t.add_column("File")
|
|
324
|
+
|
|
325
|
+
cmds = [
|
|
326
|
+
("p init", "Initialize .patchi in a project", "init.py (436 lines)"),
|
|
327
|
+
("p scan", "Run scanner agents", "scan_cmd.py (947 lines)"),
|
|
328
|
+
("p status", "Show project health overview", "status_cmd.py (167 lines)"),
|
|
329
|
+
("p watch", "Watch mode — auto-rescan on file changes", "watch_cmd.py (109 lines)"),
|
|
330
|
+
("p doctor", "Validate setup, check deps, test AI", "doctor_cmd.py (386 lines)"),
|
|
331
|
+
("p fix", "Auto-fix findings", "fix_cmd.py (374 lines)"),
|
|
332
|
+
("p review", "Review pending patches", "review_cmd.py (225 lines)"),
|
|
333
|
+
("p patch", "Manage patches (list/show/apply/reject)", "patch_cmd.py (215 lines)"),
|
|
334
|
+
("p undo / redo / rollback", "Undo/redo/rollback patches", "undo_cmd.py (233 lines)"),
|
|
335
|
+
(
|
|
336
|
+
"p test",
|
|
337
|
+
f"Run test agents ({len(list_agents(AgentGroup.TEST))} types)",
|
|
338
|
+
"test_cmd.py (699 lines)",
|
|
339
|
+
),
|
|
340
|
+
(
|
|
341
|
+
"p security",
|
|
342
|
+
f"Run security agents ({len(list_agents(AgentGroup.SECURITY))} types)",
|
|
343
|
+
"security_cmd.py (538 lines)",
|
|
344
|
+
),
|
|
345
|
+
("p memory", "Show/manage brain memory", "memory_cmd.py (219 lines)"),
|
|
346
|
+
("p queue", "Manage agent queue", "queue_cmd.py (154 lines)"),
|
|
347
|
+
("p mode", "Set confirm/auto/autopilot mode", "mode_cmd.py (78 lines)"),
|
|
348
|
+
("p restrict", "Add/remove path restrictions", "restrict_cmd.py (128 lines)"),
|
|
349
|
+
("p settings", "Show/edit settings", "inline in main.py"),
|
|
350
|
+
("p key", "Manage API keys (10 providers)", "key_cmd.py (505 lines)"),
|
|
351
|
+
("p ai", "AI status, test, horde management", "ai_cmd.py (205 lines)"),
|
|
352
|
+
("p model", "Set/list AI models", "model_cmd.py (205 lines)"),
|
|
353
|
+
("p access", "Manage dev access tokens", "inline in main.py"),
|
|
354
|
+
("p notify", "Notification channels", "notify_cmd.py (213 lines)"),
|
|
355
|
+
("p agents", "List/status/reset agents", "agents_cmd.py (185 lines)"),
|
|
356
|
+
("p hosted", "Hosted mode management", "hosted_cmd.py (957 lines)"),
|
|
357
|
+
("p report", "Export reports (JSON/HTML/markdown)", "report_cmd.py (414 lines)"),
|
|
358
|
+
("p chat", "Interactive AI chat", "chat_cmd.py (134 lines)"),
|
|
359
|
+
("p web", "Launch web dashboard", "web_cmd.py (102 lines)"),
|
|
360
|
+
("p explain", "Explain a finding", "explain_cmd.py (330 lines)"),
|
|
361
|
+
("p blast", "Blast radius analysis", "blast_cmd.py (318 lines)"),
|
|
362
|
+
("p scan", "Scan project and auto-generate BRAIN.md", "scan_cmd.py"),
|
|
363
|
+
("p trend", "Health quality trends", "trend_cmd.py (298 lines)"),
|
|
364
|
+
("p blame", "Git blame for a file", "blame_cmd.py (52 lines)"),
|
|
365
|
+
("p log", "Git changelog", "log_cmd.py (59 lines)"),
|
|
366
|
+
("p deps", "Supply chain security scan", "deps_cmd.py (79 lines)"),
|
|
367
|
+
("p audit", "Full project audit in one shot", "audit_cmd.py (381 lines)"),
|
|
368
|
+
("p learn", "Learn project conventions", "learn_cmd.py (375 lines)"),
|
|
369
|
+
("p dev", "Developer utilities (this command)", "dev_cmd.py"),
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
for cmd, desc, src in cmds:
|
|
373
|
+
t.add_row(cmd, desc, src)
|
|
374
|
+
|
|
375
|
+
con.print(t)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def _get_version() -> str:
|
|
379
|
+
try:
|
|
380
|
+
from patchi import __version__
|
|
381
|
+
|
|
382
|
+
return __version__
|
|
383
|
+
except Exception as e:
|
|
384
|
+
_log.warning("_get_version failed: %s", e)
|
|
385
|
+
return "unknown"
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def _install_hook(con: Console, strict: bool = False, auto_fix: bool = False) -> None:
|
|
389
|
+
"""Install the Patchi pre-commit hook."""
|
|
390
|
+
from patchi.core.config import require_project_root
|
|
391
|
+
from patchi.core.security.precommit_hook import install_hook, read_hook_status
|
|
392
|
+
|
|
393
|
+
try:
|
|
394
|
+
root = require_project_root()
|
|
395
|
+
except RuntimeError as e:
|
|
396
|
+
con.print(f"[red]{e}[/red]")
|
|
397
|
+
return
|
|
398
|
+
|
|
399
|
+
# Show current status
|
|
400
|
+
status = read_hook_status(root)
|
|
401
|
+
if status.get("installed"):
|
|
402
|
+
con.print(f"[dim]Current hook:[/dim] {status.get('path', '?')}")
|
|
403
|
+
parts = []
|
|
404
|
+
if status.get("auto_fix"):
|
|
405
|
+
parts.append("auto-fix")
|
|
406
|
+
if status.get("has_ruff"):
|
|
407
|
+
parts.append("ruff")
|
|
408
|
+
if status.get("has_pytest"):
|
|
409
|
+
parts.append("pytest")
|
|
410
|
+
if status.get("has_scan"):
|
|
411
|
+
parts.append("scan --changed")
|
|
412
|
+
if status.get("strict"):
|
|
413
|
+
parts.append("strict")
|
|
414
|
+
con.print(f" Gates: {', '.join(parts) or 'none'}")
|
|
415
|
+
con.print()
|
|
416
|
+
|
|
417
|
+
# Install
|
|
418
|
+
mode_label = "[bold red]STRICT[/bold red]" if strict else "[dim]warn-only[/dim]"
|
|
419
|
+
fix_label = "[bold green]ON[/bold green]" if auto_fix else "[dim]OFF[/dim]"
|
|
420
|
+
try:
|
|
421
|
+
hook_path = install_hook(root, strict=strict, with_tests=True, with_scan=True, auto_fix=auto_fix)
|
|
422
|
+
con.print(f"[#4ADE80]✓[/#4ADE80] Pre-commit hook installed: [bold]{hook_path}[/bold]")
|
|
423
|
+
con.print(f" Mode: {mode_label} | Auto-fix: {fix_label}")
|
|
424
|
+
con.print()
|
|
425
|
+
con.print(" Gates on every commit:")
|
|
426
|
+
if auto_fix:
|
|
427
|
+
con.print(" 1. [dim]proactive auto-fix[/dim] — charter violations (imports, headers)")
|
|
428
|
+
step = 1 if auto_fix else 0
|
|
429
|
+
step += 1
|
|
430
|
+
con.print(f" {step}. [dim]ruff check patchi/[/dim] — lint")
|
|
431
|
+
step += 1
|
|
432
|
+
con.print(f" {step}. [dim]pytest tests/[/dim] — tests")
|
|
433
|
+
step += 1
|
|
434
|
+
con.print(f" {step}. [dim]p scan --changed[/dim] — security scan of changed files")
|
|
435
|
+
con.print()
|
|
436
|
+
if strict:
|
|
437
|
+
con.print("[bold red]Strict mode ON:[/bold red] violations block the commit.")
|
|
438
|
+
else:
|
|
439
|
+
con.print("[dim]Run [bold]p dev hook --strict[/bold] to fail commits on violations.[/dim]")
|
|
440
|
+
if auto_fix:
|
|
441
|
+
con.print("[dim]Auto-fix will fix safe charter violations (headers, imports) automatically.[/dim]")
|
|
442
|
+
else:
|
|
443
|
+
con.print("[dim]Run [bold]p dev hook --auto-fix[/bold] to auto-fix charter violations on commit.[/dim]")
|
|
444
|
+
except Exception as e:
|
|
445
|
+
con.print(f"[red]Failed to install hook: {e}[/red]")
|