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
patchi/cli/registry.py
ADDED
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command registry — the single source of truth §3 Command Unification promises.
|
|
3
|
+
|
|
4
|
+
Every `p <command>` in the system is declared here and nowhere else. The
|
|
5
|
+
incremental migration is complete: the legacy argparse blocks and the elif
|
|
6
|
+
dispatch ladder in main.py are gone, and TestCLIRegistryLinking in
|
|
7
|
+
tests/test_regression_audit.py proves parser ↔ registry exact equality at
|
|
8
|
+
every nesting level — no command can ever live on a hidden ladder again.
|
|
9
|
+
|
|
10
|
+
Command shapes used:
|
|
11
|
+
|
|
12
|
+
- Kwarg handlers (the default): Arg specs map to handler parameters
|
|
13
|
+
(scan, fix, report, audit, undo, reason, trend, learn, ...).
|
|
14
|
+
- Subcommand trees: Command.subcommands for `p <cmd> <sub>` (queue, patch,
|
|
15
|
+
key, agents, model, memory, restrict, settings, access, ai, charter, ...).
|
|
16
|
+
- Self-routing Namespace handlers (framework namespace_handler=True): the
|
|
17
|
+
handler receives the whole parsed Namespace and routes on the subcommand
|
|
18
|
+
dests itself. Used by notify, hosted (deepest tree: hosted token revoke
|
|
19
|
+
<id>), test, security, and cross-repo — all dispatch on parsed values a
|
|
20
|
+
static Arg->kwarg mapping can't express (e.g. `p test generate` routes to a
|
|
21
|
+
different function than `p test unit`).
|
|
22
|
+
|
|
23
|
+
Every handler's ACTUAL signature was checked against these entries before
|
|
24
|
+
registering — several didn't match the parser's attribute name at first pass
|
|
25
|
+
(scan's --file stores under `file`, handler wants `file_path`; queue's mode
|
|
26
|
+
positional was `mode_name`, handler wants `mode_str`; patch's id args were
|
|
27
|
+
`id`, handlers want `patch_id`; key's remove/test were `name`, handlers want
|
|
28
|
+
`nickname`). All are fixed below, not assumed — and TestCLIRegistryLinking now
|
|
29
|
+
guards the whole set mechanically.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
from patchi.cli.framework import Arg, Command
|
|
35
|
+
from patchi.core.constants import RestrictionType as _RestrictionType
|
|
36
|
+
|
|
37
|
+
COMMANDS: list[Command] = [
|
|
38
|
+
Command(
|
|
39
|
+
"init",
|
|
40
|
+
"Initialize Patchi in the current project",
|
|
41
|
+
"patchi.cli.commands.init:run",
|
|
42
|
+
args=(
|
|
43
|
+
Arg("--no-logo", dest="no_logo", action="store_true", help="Skip logo draw (for CI)"),
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
Command(
|
|
47
|
+
"ready",
|
|
48
|
+
"Ship readiness check — is my code ready to ship?",
|
|
49
|
+
"patchi.cli.commands.ready_cmd:run",
|
|
50
|
+
args=(
|
|
51
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
52
|
+
Arg("--quick", dest="quick", action="store_true", help="Fast check (subset of agents)"),
|
|
53
|
+
Arg("--ci", dest="ci", action="store_true", help="CI-friendly output (exit 1 on failure)"),
|
|
54
|
+
),
|
|
55
|
+
),
|
|
56
|
+
Command(
|
|
57
|
+
"quick",
|
|
58
|
+
"Fast readiness check — minimal agents for quick verification",
|
|
59
|
+
"patchi.cli.commands.quick_cmd:run",
|
|
60
|
+
args=(
|
|
61
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
62
|
+
),
|
|
63
|
+
),
|
|
64
|
+
Command(
|
|
65
|
+
"status",
|
|
66
|
+
"Show Brain health, mode, queue state, and key status",
|
|
67
|
+
"patchi.cli.commands.status_cmd:run",
|
|
68
|
+
args=(
|
|
69
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
70
|
+
Arg("--deep", dest="deep", action="store_true", help="Show detailed health breakdown (was p health)"),
|
|
71
|
+
Arg("--validate", dest="validate", action="store_true", help="Run system validation checks (was p doctor)"),
|
|
72
|
+
Arg("--verbose", dest="verbose", action="store_true", help="Show detailed output"),
|
|
73
|
+
),
|
|
74
|
+
),
|
|
75
|
+
Command(
|
|
76
|
+
"doctor",
|
|
77
|
+
"System health check — stale commands, dependencies, config",
|
|
78
|
+
"patchi.cli.commands.doctor_cmd:run",
|
|
79
|
+
args=(
|
|
80
|
+
Arg("--verbose", dest="verbose", action="store_true", help="Show detailed output"),
|
|
81
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
82
|
+
Arg("--fix", dest="fix", action="store_true", help="Auto-update stale command references in scripts/"),
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
Command(
|
|
86
|
+
"watch",
|
|
87
|
+
"Auto-scan on file saves",
|
|
88
|
+
"patchi.cli.commands.watch_cmd:run",
|
|
89
|
+
args=(
|
|
90
|
+
Arg("area", nargs="?", help="Watch specific area only"),
|
|
91
|
+
Arg("--dry-run", action="store_true", help="Preview auto-fixes without applying them"),
|
|
92
|
+
Arg("--preview", action="store_true", help="Show detailed before/after of proposed fixes"),
|
|
93
|
+
Arg("--auto-fix", action="store_true", help="Enable proactive fixing on file saves (overrides config)"),
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
Command(
|
|
97
|
+
"scan",
|
|
98
|
+
"Scan the project (full or targeted)",
|
|
99
|
+
"patchi.cli.commands.scan_cmd:run",
|
|
100
|
+
args=(
|
|
101
|
+
Arg("area", nargs="?", help="Targeted area — plain language or path"),
|
|
102
|
+
Arg("--force", action="store_true", help="Re-scan even if brain is fresh"),
|
|
103
|
+
Arg(
|
|
104
|
+
"--offline",
|
|
105
|
+
dest="offline",
|
|
106
|
+
action="store_true",
|
|
107
|
+
help="Skip all AI calls — static analysis only, zero token cost",
|
|
108
|
+
),
|
|
109
|
+
Arg(
|
|
110
|
+
"--dry-run",
|
|
111
|
+
dest="dry_run",
|
|
112
|
+
action="store_true",
|
|
113
|
+
help="Preview what would be scanned without parsing",
|
|
114
|
+
),
|
|
115
|
+
Arg(
|
|
116
|
+
"--quiet",
|
|
117
|
+
dest="quiet",
|
|
118
|
+
action="store_true",
|
|
119
|
+
help="Suppress non-essential output",
|
|
120
|
+
),
|
|
121
|
+
Arg(
|
|
122
|
+
"--deep",
|
|
123
|
+
action="store_true",
|
|
124
|
+
help="Include LLM analysis of changed files (uses AI tokens)",
|
|
125
|
+
),
|
|
126
|
+
Arg("--file", dest="file_path", type=str, help="Deep analysis of a specific file"),
|
|
127
|
+
Arg("--contract", action="store_true", help="Review and confirm app contract flows"),
|
|
128
|
+
Arg(
|
|
129
|
+
"--all-flows",
|
|
130
|
+
dest="all_flows",
|
|
131
|
+
action="store_true",
|
|
132
|
+
help="Show all flows including low-confidence (used with --contract)",
|
|
133
|
+
),
|
|
134
|
+
Arg(
|
|
135
|
+
"--json",
|
|
136
|
+
dest="json_output",
|
|
137
|
+
action="store_true",
|
|
138
|
+
help="Output scan results as JSON (machine-readable)",
|
|
139
|
+
),
|
|
140
|
+
Arg(
|
|
141
|
+
"--no-side",
|
|
142
|
+
dest="side",
|
|
143
|
+
action="store_false",
|
|
144
|
+
default=True,
|
|
145
|
+
help="Skip side file scanners (faster, source-only scan). Default: on",
|
|
146
|
+
),
|
|
147
|
+
Arg(
|
|
148
|
+
"--pipeline",
|
|
149
|
+
action="store_true",
|
|
150
|
+
help="Enable defense pipeline: ConfidenceGate + DefenseLayer auto-fix",
|
|
151
|
+
),
|
|
152
|
+
Arg("--daemon", action="store_true", help="Start background scan scheduler daemon"),
|
|
153
|
+
Arg(
|
|
154
|
+
"--governor",
|
|
155
|
+
action="store_true",
|
|
156
|
+
help="Run Governor v2 pipeline: scan → graph → test → fix → reverify → select",
|
|
157
|
+
),
|
|
158
|
+
Arg(
|
|
159
|
+
"--with-attackers",
|
|
160
|
+
dest="with_attackers",
|
|
161
|
+
action="store_true",
|
|
162
|
+
help="Run adversarial attacker hypotheses against the assurance graph",
|
|
163
|
+
),
|
|
164
|
+
Arg(
|
|
165
|
+
"--with-campaigns",
|
|
166
|
+
dest="with_campaigns",
|
|
167
|
+
action="store_true",
|
|
168
|
+
help="Run state transition and data flow abuse campaigns",
|
|
169
|
+
),
|
|
170
|
+
Arg(
|
|
171
|
+
"--with-fuzz",
|
|
172
|
+
dest="with_fuzz",
|
|
173
|
+
action="store_true",
|
|
174
|
+
help="Generate fuzz inputs for discovered endpoints",
|
|
175
|
+
),
|
|
176
|
+
Arg(
|
|
177
|
+
"--red-team",
|
|
178
|
+
dest="red_team",
|
|
179
|
+
action="store_true",
|
|
180
|
+
help="Run Red Team Engine: live attack simulation + auto-fix generation",
|
|
181
|
+
),
|
|
182
|
+
Arg(
|
|
183
|
+
"--dast",
|
|
184
|
+
action="store_true",
|
|
185
|
+
help="Run DAST scanner: Playwright-based dynamic security testing with screenshots",
|
|
186
|
+
),
|
|
187
|
+
Arg(
|
|
188
|
+
"--changed",
|
|
189
|
+
action="store_true",
|
|
190
|
+
help="On-demand mode: only activate domains relevant to git-diff changed files",
|
|
191
|
+
),
|
|
192
|
+
Arg(
|
|
193
|
+
"--since",
|
|
194
|
+
dest="since",
|
|
195
|
+
default=None,
|
|
196
|
+
help="Only report findings in files changed since git ref (e.g. HEAD~3, main)",
|
|
197
|
+
),
|
|
198
|
+
Arg(
|
|
199
|
+
"--fail-on",
|
|
200
|
+
dest="fail_on",
|
|
201
|
+
default=None,
|
|
202
|
+
choices=("critical", "high", "medium"),
|
|
203
|
+
help="Exit 1 when findings at/above this severity exist (CI gate). Default: always exit 0",
|
|
204
|
+
),
|
|
205
|
+
Arg(
|
|
206
|
+
"--changed-commits",
|
|
207
|
+
dest="changed_commits",
|
|
208
|
+
type=int,
|
|
209
|
+
default=1,
|
|
210
|
+
help="Number of commits to diff (default: 1)",
|
|
211
|
+
),
|
|
212
|
+
Arg(
|
|
213
|
+
"--with-license",
|
|
214
|
+
dest="with_license",
|
|
215
|
+
action="store_true",
|
|
216
|
+
help="Include license compliance findings (heavy/noisy). Use p scan --with-license for full supply-chain license audit",
|
|
217
|
+
),
|
|
218
|
+
Arg(
|
|
219
|
+
"--with-extended",
|
|
220
|
+
dest="with_extended",
|
|
221
|
+
action="store_true",
|
|
222
|
+
help="Include extended noise (duplicates, hygiene). Main scan stays focused; use for deep audit",
|
|
223
|
+
),
|
|
224
|
+
Arg("--quiet", dest="quiet", global_flag=True),
|
|
225
|
+
),
|
|
226
|
+
),
|
|
227
|
+
Command(
|
|
228
|
+
"cockpit",
|
|
229
|
+
"Live session dashboard — health, drift, fix list, blast radius",
|
|
230
|
+
"patchi.cli.commands.cockpit_cmd:run",
|
|
231
|
+
args=(
|
|
232
|
+
Arg("--area", dest="area", default=None, help="Scope the fix list to this area/path"),
|
|
233
|
+
Arg(
|
|
234
|
+
"--interval",
|
|
235
|
+
dest="interval",
|
|
236
|
+
type=float,
|
|
237
|
+
default=15.0,
|
|
238
|
+
help="Seconds between full health/drift/fix refreshes",
|
|
239
|
+
),
|
|
240
|
+
Arg(
|
|
241
|
+
"--poll",
|
|
242
|
+
dest="poll",
|
|
243
|
+
type=float,
|
|
244
|
+
default=1.0,
|
|
245
|
+
help="Seconds between file-change polls",
|
|
246
|
+
),
|
|
247
|
+
Arg(
|
|
248
|
+
"--once",
|
|
249
|
+
dest="once",
|
|
250
|
+
action="store_true",
|
|
251
|
+
help="Render one frame and exit (CI / smoke test)",
|
|
252
|
+
),
|
|
253
|
+
Arg(
|
|
254
|
+
"--scan-secrets",
|
|
255
|
+
dest="scan_secrets",
|
|
256
|
+
action="store_true",
|
|
257
|
+
help="Run a full secrets sweep at startup",
|
|
258
|
+
),
|
|
259
|
+
),
|
|
260
|
+
),
|
|
261
|
+
Command(
|
|
262
|
+
"queue",
|
|
263
|
+
"View and control the task queue",
|
|
264
|
+
"patchi.cli.commands.queue_cmd:run_show", # used when no subcommand given
|
|
265
|
+
subcommands=(
|
|
266
|
+
Command("pause", "Pause queue execution", "patchi.cli.commands.queue_cmd:run_pause"),
|
|
267
|
+
Command("resume", "Resume queue", "patchi.cli.commands.queue_cmd:run_resume"),
|
|
268
|
+
Command(
|
|
269
|
+
"skip", "Skip the current active task", "patchi.cli.commands.queue_cmd:run_skip"
|
|
270
|
+
),
|
|
271
|
+
# `p mode` merged into `p settings` — use `p settings set mode <name>`
|
|
272
|
+
Command(
|
|
273
|
+
"mode",
|
|
274
|
+
"Set queue mode",
|
|
275
|
+
"patchi.cli.commands.queue_cmd:run_set_mode",
|
|
276
|
+
args=(Arg("mode_str", choices=("single", "multi", "off")),),
|
|
277
|
+
),
|
|
278
|
+
),
|
|
279
|
+
),
|
|
280
|
+
Command(
|
|
281
|
+
"patch",
|
|
282
|
+
"Manage individual patches",
|
|
283
|
+
"patchi.cli.commands.patch_cmd:run_list", # used when no subcommand given
|
|
284
|
+
subcommands=(
|
|
285
|
+
Command(
|
|
286
|
+
"list",
|
|
287
|
+
"List all patches",
|
|
288
|
+
"patchi.cli.commands.patch_cmd:run_list",
|
|
289
|
+
args=(
|
|
290
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
291
|
+
),
|
|
292
|
+
),
|
|
293
|
+
Command(
|
|
294
|
+
"show",
|
|
295
|
+
"Show diff for a patch",
|
|
296
|
+
"patchi.cli.commands.patch_cmd:run_show",
|
|
297
|
+
args=(
|
|
298
|
+
Arg("patch_id"),
|
|
299
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
300
|
+
),
|
|
301
|
+
),
|
|
302
|
+
Command(
|
|
303
|
+
"apply",
|
|
304
|
+
"Apply a pending patch",
|
|
305
|
+
"patchi.cli.commands.patch_cmd:run_apply",
|
|
306
|
+
args=(Arg("patch_id"),),
|
|
307
|
+
),
|
|
308
|
+
Command(
|
|
309
|
+
"reject",
|
|
310
|
+
"Reject a patch",
|
|
311
|
+
"patchi.cli.commands.patch_cmd:run_reject",
|
|
312
|
+
args=(Arg("patch_id"),),
|
|
313
|
+
),
|
|
314
|
+
# Canonical home for the undo family (top-level names kept as compat)
|
|
315
|
+
Command(
|
|
316
|
+
"undo",
|
|
317
|
+
"Undo last applied fix or specific patch",
|
|
318
|
+
"patchi.cli.commands.undo_cmd:run_undo",
|
|
319
|
+
args=(Arg("patch_id", nargs="?", help="Specific patch ID"),),
|
|
320
|
+
),
|
|
321
|
+
Command(
|
|
322
|
+
"redo",
|
|
323
|
+
"Redo last undone fix or specific patch",
|
|
324
|
+
"patchi.cli.commands.undo_cmd:run_redo",
|
|
325
|
+
args=(Arg("patch_id", nargs="?", help="Specific patch ID"),),
|
|
326
|
+
),
|
|
327
|
+
Command(
|
|
328
|
+
"rollback",
|
|
329
|
+
"Roll back to a specific patch",
|
|
330
|
+
"patchi.cli.commands.undo_cmd:run_rollback",
|
|
331
|
+
args=(Arg("patch_id"),),
|
|
332
|
+
),
|
|
333
|
+
),
|
|
334
|
+
),
|
|
335
|
+
Command(
|
|
336
|
+
"key",
|
|
337
|
+
"Manage API keys",
|
|
338
|
+
"patchi.cli.commands.key_cmd:run_add", # no subcommand -> interactive add, matches original
|
|
339
|
+
subcommands=(
|
|
340
|
+
Command("add", "Add an API key (interactive)", "patchi.cli.commands.key_cmd:run_add"),
|
|
341
|
+
Command("list", "List all keys with status", "patchi.cli.commands.key_cmd:run_list"),
|
|
342
|
+
Command(
|
|
343
|
+
"remove",
|
|
344
|
+
"Remove a key by nickname",
|
|
345
|
+
"patchi.cli.commands.key_cmd:run_remove",
|
|
346
|
+
args=(Arg("nickname"),),
|
|
347
|
+
),
|
|
348
|
+
Command(
|
|
349
|
+
"test",
|
|
350
|
+
"Test a key connection",
|
|
351
|
+
"patchi.cli.commands.key_cmd:run_test",
|
|
352
|
+
args=(Arg("nickname", nargs="?", help="Key nickname (omit for all)"),),
|
|
353
|
+
),
|
|
354
|
+
),
|
|
355
|
+
),
|
|
356
|
+
# `p ignore` merged into `p memory` — use `p memory ignore`
|
|
357
|
+
# ── Batch 3: 22 more commands. Every handler signature checked directly
|
|
358
|
+
# against the real code, not assumed from the parser's attribute names --
|
|
359
|
+
# 7 more drift fixes found this batch (running total: 11 across the whole
|
|
360
|
+
# migration): undo/redo/rollback's `id`->`patch_id`, explain's `type`->
|
|
361
|
+
# `finding_type`, blast's `all`->`show_all`. ────────────────────────────
|
|
362
|
+
Command(
|
|
363
|
+
"fix",
|
|
364
|
+
"Fix issues in the project",
|
|
365
|
+
"patchi.cli.commands.fix_cmd:run",
|
|
366
|
+
args=(
|
|
367
|
+
Arg("area", nargs="?", help="Targeted area"),
|
|
368
|
+
Arg(
|
|
369
|
+
"--dry-run",
|
|
370
|
+
dest="dry_run",
|
|
371
|
+
action="store_true",
|
|
372
|
+
help="Preview fixes without applying",
|
|
373
|
+
),
|
|
374
|
+
Arg(
|
|
375
|
+
"--preview",
|
|
376
|
+
dest="preview",
|
|
377
|
+
action="store_true",
|
|
378
|
+
help="Show before/after code diffs for each proposed fix",
|
|
379
|
+
),
|
|
380
|
+
Arg(
|
|
381
|
+
"--safe-all",
|
|
382
|
+
dest="safe_all",
|
|
383
|
+
action="store_true",
|
|
384
|
+
help="Apply every non-blocked patch (AUTO + review), not just AUTO — test-only edits still queue",
|
|
385
|
+
),
|
|
386
|
+
),
|
|
387
|
+
),
|
|
388
|
+
Command(
|
|
389
|
+
"fix-review",
|
|
390
|
+
"Review and decide on proposed patches",
|
|
391
|
+
"patchi.cli.commands.fix_review_cmd:run",
|
|
392
|
+
args=(
|
|
393
|
+
Arg("--patch", dest="patch_id", help="Review a specific patch by ID"),
|
|
394
|
+
),
|
|
395
|
+
),
|
|
396
|
+
Command("review", "Review pending changes", "patchi.cli.commands.review_cmd:run"),
|
|
397
|
+
Command(
|
|
398
|
+
"undo",
|
|
399
|
+
"Undo last applied fix or specific patch (compat — prefer p patch undo)",
|
|
400
|
+
"patchi.cli.commands.undo_cmd:run_undo",
|
|
401
|
+
args=(Arg("patch_id", nargs="?", help="Specific patch ID"),),
|
|
402
|
+
),
|
|
403
|
+
Command(
|
|
404
|
+
"redo",
|
|
405
|
+
"Redo last undone fix or specific patch (compat — prefer p patch redo)",
|
|
406
|
+
"patchi.cli.commands.undo_cmd:run_redo",
|
|
407
|
+
args=(Arg("patch_id", nargs="?", help="Specific patch ID"),),
|
|
408
|
+
),
|
|
409
|
+
Command(
|
|
410
|
+
"rollback",
|
|
411
|
+
"Roll back to a specific patch (compat — prefer p patch rollback)",
|
|
412
|
+
"patchi.cli.commands.undo_cmd:run_rollback",
|
|
413
|
+
args=(Arg("patch_id"),),
|
|
414
|
+
),
|
|
415
|
+
Command(
|
|
416
|
+
"why",
|
|
417
|
+
"Explain why a file matters",
|
|
418
|
+
"patchi.cli.commands.reason_cmd:run_why",
|
|
419
|
+
args=(Arg("path", help="File path to explain"),),
|
|
420
|
+
),
|
|
421
|
+
Command(
|
|
422
|
+
"impact",
|
|
423
|
+
"Show change-impact / blast radius for changed files",
|
|
424
|
+
"patchi.cli.commands.reason_cmd:run_impact",
|
|
425
|
+
aliases=("blast",),
|
|
426
|
+
args=(
|
|
427
|
+
Arg("files", nargs="*", help="One or more changed file paths"),
|
|
428
|
+
Arg(
|
|
429
|
+
"--all",
|
|
430
|
+
dest="show_all",
|
|
431
|
+
action="store_true",
|
|
432
|
+
help="Show blast radius for all files (absorbed from p blast)",
|
|
433
|
+
),
|
|
434
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
435
|
+
),
|
|
436
|
+
),
|
|
437
|
+
Command(
|
|
438
|
+
"auto",
|
|
439
|
+
"Propose/apply safe fixes for changed files",
|
|
440
|
+
"patchi.cli.commands.auto_cmd:run",
|
|
441
|
+
args=(
|
|
442
|
+
Arg("files", nargs="+", help="One or more changed file paths"),
|
|
443
|
+
Arg("--apply", action="store_true", help="Apply safe fixes automatically"),
|
|
444
|
+
Arg("--unsafe", action="store_true", help="Also apply non-safe fixes (with --apply)"),
|
|
445
|
+
Arg(
|
|
446
|
+
"--reject",
|
|
447
|
+
dest="reject",
|
|
448
|
+
default=None,
|
|
449
|
+
help="Record that you reject a fix type (Phase 5 learning), then exit",
|
|
450
|
+
),
|
|
451
|
+
),
|
|
452
|
+
),
|
|
453
|
+
# verify currently has zero CLI-exposed args in the original (no_scan/claim
|
|
454
|
+
# exist on the handler but nothing ever set them) -- replicated faithfully
|
|
455
|
+
# as-is, not "fixed" into a new feature that wasn't there before.
|
|
456
|
+
Command(
|
|
457
|
+
"verify",
|
|
458
|
+
"Independently re-run tests+scan and report truth (not self-report)",
|
|
459
|
+
"patchi.cli.commands.verify_cmd:run",
|
|
460
|
+
args=(
|
|
461
|
+
Arg(
|
|
462
|
+
"--no-scan",
|
|
463
|
+
dest="no_scan",
|
|
464
|
+
action="store_true",
|
|
465
|
+
help="Only re-run tests, skip scan",
|
|
466
|
+
),
|
|
467
|
+
Arg(
|
|
468
|
+
"--claim",
|
|
469
|
+
dest="claim",
|
|
470
|
+
default=None,
|
|
471
|
+
help="Assert a claim (e.g. 'tests pass') against actual truth",
|
|
472
|
+
),
|
|
473
|
+
),
|
|
474
|
+
),
|
|
475
|
+
# `p mode` merged into `p settings` - use `p settings set mode <name>`
|
|
476
|
+
Command(
|
|
477
|
+
"chat",
|
|
478
|
+
"Interactive AI chat with Patchi",
|
|
479
|
+
"patchi.cli.commands.chat_cmd:run",
|
|
480
|
+
args=(
|
|
481
|
+
Arg("message", nargs="?", help="Single message (non-interactive)"),
|
|
482
|
+
Arg("--stream", action="store_true", help="Show real-time tool execution progress"),
|
|
483
|
+
Arg("--explain-all", action="store_true", dest="explain_all", help="Show full security knowledge base"),
|
|
484
|
+
),
|
|
485
|
+
),
|
|
486
|
+
Command(
|
|
487
|
+
"dev",
|
|
488
|
+
"Developer utilities, testing docs, and diagnostics",
|
|
489
|
+
"patchi.cli.commands.dev_cmd:run",
|
|
490
|
+
args=(
|
|
491
|
+
Arg(
|
|
492
|
+
"action",
|
|
493
|
+
nargs="?",
|
|
494
|
+
default=None,
|
|
495
|
+
help="Dev action: check | test | security | playwright | docs | hook (--strict)",
|
|
496
|
+
),
|
|
497
|
+
# dev has its own --verbose, separate from the global one
|
|
498
|
+
Arg("--verbose", dest="verbose", action="store_true", help="Show detailed output"),
|
|
499
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON (for check)"),
|
|
500
|
+
Arg("--strict", dest="strict", action="store_true", help="Fail commits on violations (hook)"),
|
|
501
|
+
Arg("--auto-fix", dest="auto_fix", action="store_true", help="Auto-fix charter violations on commit (hook)"),
|
|
502
|
+
Arg("--fast", dest="fast", action="store_true", help="Fast mode: run only core tests (~18s) for quick iteration"),
|
|
503
|
+
),
|
|
504
|
+
),
|
|
505
|
+
Command(
|
|
506
|
+
"deps",
|
|
507
|
+
"Supply chain security scan",
|
|
508
|
+
"patchi.cli.commands.deps_cmd:run",
|
|
509
|
+
args=(
|
|
510
|
+
Arg("--sbom", action="store_true", help="Generate SBOM"),
|
|
511
|
+
Arg("--licenses", action="store_true", help="Check license compliance"),
|
|
512
|
+
Arg("--outdated", action="store_true", help="Check for outdated packages"),
|
|
513
|
+
Arg("--cve", action="store_true", help="Check for known CVEs"),
|
|
514
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
515
|
+
),
|
|
516
|
+
),
|
|
517
|
+
# `p blast` was merged into `p impact` (--all + alias). One blast-radius
|
|
518
|
+
# implementation, one command.
|
|
519
|
+
# `p brain` merged into `p agents list --brain` — use `p agents list --brain`
|
|
520
|
+
Command(
|
|
521
|
+
"trend",
|
|
522
|
+
"Health and quality trend over time",
|
|
523
|
+
"patchi.cli.commands.trend_cmd:run",
|
|
524
|
+
args=(
|
|
525
|
+
Arg(
|
|
526
|
+
"metric",
|
|
527
|
+
nargs="?",
|
|
528
|
+
choices=("security", "tests"),
|
|
529
|
+
help="Specific metric (default: overall health)",
|
|
530
|
+
),
|
|
531
|
+
Arg(
|
|
532
|
+
"--last",
|
|
533
|
+
dest="last_n",
|
|
534
|
+
type=int,
|
|
535
|
+
default=20,
|
|
536
|
+
help="Number of recent entries to show",
|
|
537
|
+
),
|
|
538
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
539
|
+
),
|
|
540
|
+
),
|
|
541
|
+
Command(
|
|
542
|
+
"heatmap",
|
|
543
|
+
"Risk heatmap — bug-prone hotspots (score = findings×10 + churn×2 + size/10)",
|
|
544
|
+
"patchi.cli.commands.heatmap_cmd:run",
|
|
545
|
+
args=(Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),),
|
|
546
|
+
),
|
|
547
|
+
Command(
|
|
548
|
+
"blame",
|
|
549
|
+
"Show git blame for a file",
|
|
550
|
+
"patchi.cli.commands.blame_cmd:run",
|
|
551
|
+
args=(
|
|
552
|
+
Arg("file_path", help="File path to blame"),
|
|
553
|
+
Arg("line", nargs="?", type=int, help="Specific line number"),
|
|
554
|
+
),
|
|
555
|
+
),
|
|
556
|
+
Command(
|
|
557
|
+
"log",
|
|
558
|
+
"Show git changelog",
|
|
559
|
+
"patchi.cli.commands.log_cmd:run",
|
|
560
|
+
args=(Arg("--since", default="HEAD~10", help="Git ref or date (default: HEAD~10)"),),
|
|
561
|
+
),
|
|
562
|
+
Command(
|
|
563
|
+
"update",
|
|
564
|
+
"Check for and apply updates",
|
|
565
|
+
"patchi.cli.commands.update_cmd:run",
|
|
566
|
+
args=(
|
|
567
|
+
Arg("--check", action="store_true", help="Check only, no install"),
|
|
568
|
+
Arg("--force", action="store_true", help="Force reinstall current version"),
|
|
569
|
+
Arg("--auto", action="store_true", help="Auto-install without prompting (for CI)"),
|
|
570
|
+
),
|
|
571
|
+
),
|
|
572
|
+
Command(
|
|
573
|
+
"learn",
|
|
574
|
+
"Learn project conventions and patterns",
|
|
575
|
+
"patchi.cli.commands.learn_cmd:run",
|
|
576
|
+
args=(
|
|
577
|
+
Arg("--force", action="store_true", help="Relearn even if conventions already stored"),
|
|
578
|
+
Arg("sub", nargs="?", choices=("patterns",), help="Show fix patterns"),
|
|
579
|
+
),
|
|
580
|
+
),
|
|
581
|
+
# ── Batch 4: agents, model, memory, plan, restrict. ─────────────────────
|
|
582
|
+
# `restrict` needed the new `fixed_kwargs` framework feature -- add/
|
|
583
|
+
# scan-only/sensitive all call the SAME run_add(path, rtype, reason) with
|
|
584
|
+
# a different hardcoded RestrictionType per subcommand, not something
|
|
585
|
+
# derivable from parsed args alone. 8th drift fix this migration: run_add's
|
|
586
|
+
# second param is `rtype`, not `restriction_type`.
|
|
587
|
+
Command(
|
|
588
|
+
"agents",
|
|
589
|
+
"Inspect and manage agents",
|
|
590
|
+
"patchi.cli.commands.agents_cmd:run_list", # no subcommand -> list, matches original
|
|
591
|
+
subcommands=(
|
|
592
|
+
Command(
|
|
593
|
+
"list",
|
|
594
|
+
"List agent groups or agents in a group",
|
|
595
|
+
"patchi.cli.commands.agents_cmd:run_list",
|
|
596
|
+
args=(Arg("group_name", nargs="?"),),
|
|
597
|
+
),
|
|
598
|
+
Command(
|
|
599
|
+
"status",
|
|
600
|
+
"Show currently active agents",
|
|
601
|
+
"patchi.cli.commands.agents_cmd:run_status",
|
|
602
|
+
),
|
|
603
|
+
Command(
|
|
604
|
+
"reset",
|
|
605
|
+
"Reset circuit breaker for an agent (LIMIT-04)",
|
|
606
|
+
"patchi.cli.commands.agents_cmd:run_reset",
|
|
607
|
+
args=(Arg("agent_name", nargs="?", help="Agent name to reset (omit for all)"),),
|
|
608
|
+
),
|
|
609
|
+
),
|
|
610
|
+
),
|
|
611
|
+
Command(
|
|
612
|
+
"model",
|
|
613
|
+
"Manage local Ollama model",
|
|
614
|
+
"patchi.cli.commands.model_cmd:run_status", # no subcommand -> status, matches original
|
|
615
|
+
subcommands=(
|
|
616
|
+
Command(
|
|
617
|
+
"set",
|
|
618
|
+
"Set local model",
|
|
619
|
+
"patchi.cli.commands.model_cmd:run_set",
|
|
620
|
+
args=(Arg("model_name"),),
|
|
621
|
+
),
|
|
622
|
+
Command(
|
|
623
|
+
"list", "List available local models", "patchi.cli.commands.model_cmd:run_list"
|
|
624
|
+
),
|
|
625
|
+
Command(
|
|
626
|
+
"status", "Show model connection health", "patchi.cli.commands.model_cmd:run_status"
|
|
627
|
+
),
|
|
628
|
+
),
|
|
629
|
+
),
|
|
630
|
+
Command(
|
|
631
|
+
"memory",
|
|
632
|
+
"View and manage Patchi's memory",
|
|
633
|
+
"patchi.cli.commands.memory_cmd:run_show_all", # no subcommand -> show_all, matches original
|
|
634
|
+
subcommands=(
|
|
635
|
+
Command(
|
|
636
|
+
"show",
|
|
637
|
+
"Show memory for a category",
|
|
638
|
+
"patchi.cli.commands.memory_cmd:run_show",
|
|
639
|
+
args=(Arg("category_str"),),
|
|
640
|
+
),
|
|
641
|
+
Command(
|
|
642
|
+
"delete",
|
|
643
|
+
"Clear memory (category or all)",
|
|
644
|
+
"patchi.cli.commands.memory_cmd:run_delete",
|
|
645
|
+
args=(Arg("category_str", help="Category name or 'all'"),),
|
|
646
|
+
),
|
|
647
|
+
),
|
|
648
|
+
),
|
|
649
|
+
Command(
|
|
650
|
+
"plan",
|
|
651
|
+
"Plan changes before making them",
|
|
652
|
+
"patchi.cli.commands.plan_cmd:run",
|
|
653
|
+
args=(
|
|
654
|
+
Arg("area", nargs="?", help="Targeted area — plain language or path"),
|
|
655
|
+
Arg(
|
|
656
|
+
"--format",
|
|
657
|
+
dest="include_format",
|
|
658
|
+
action="store_true",
|
|
659
|
+
help="Include formatting-only changes",
|
|
660
|
+
),
|
|
661
|
+
Arg(
|
|
662
|
+
"--missing-import",
|
|
663
|
+
dest="include_missing_import",
|
|
664
|
+
action="store_true",
|
|
665
|
+
help="Include missing-import fixes",
|
|
666
|
+
),
|
|
667
|
+
Arg("--json", dest="json_output", action="store_true"),
|
|
668
|
+
Arg("--html", dest="html", default=None, help="Write a self-contained HTML report"),
|
|
669
|
+
),
|
|
670
|
+
),
|
|
671
|
+
Command(
|
|
672
|
+
"restrict",
|
|
673
|
+
"Manage file restrictions",
|
|
674
|
+
"patchi.cli.commands.restrict_cmd:run_list", # no subcommand -> list, matches original
|
|
675
|
+
subcommands=(
|
|
676
|
+
Command(
|
|
677
|
+
"add",
|
|
678
|
+
"Add path as no-touch zone",
|
|
679
|
+
"patchi.cli.commands.restrict_cmd:run_add",
|
|
680
|
+
args=(Arg("path"), Arg("--reason", dest="reason", default="")),
|
|
681
|
+
fixed_kwargs={"rtype": _RestrictionType.NO_TOUCH},
|
|
682
|
+
),
|
|
683
|
+
Command(
|
|
684
|
+
"scan-only",
|
|
685
|
+
"Mark path as scan-only",
|
|
686
|
+
"patchi.cli.commands.restrict_cmd:run_add",
|
|
687
|
+
args=(Arg("path"), Arg("--reason", dest="reason", default="")),
|
|
688
|
+
fixed_kwargs={"rtype": _RestrictionType.SCAN_ONLY},
|
|
689
|
+
),
|
|
690
|
+
Command(
|
|
691
|
+
"sensitive",
|
|
692
|
+
"Mark path as sensitive",
|
|
693
|
+
"patchi.cli.commands.restrict_cmd:run_add",
|
|
694
|
+
args=(Arg("path"), Arg("--reason", dest="reason", default="")),
|
|
695
|
+
fixed_kwargs={"rtype": _RestrictionType.SENSITIVE},
|
|
696
|
+
),
|
|
697
|
+
Command("list", "List all restrictions", "patchi.cli.commands.restrict_cmd:run_list"),
|
|
698
|
+
Command(
|
|
699
|
+
"remove",
|
|
700
|
+
"Remove a restriction",
|
|
701
|
+
"patchi.cli.commands.restrict_cmd:run_remove",
|
|
702
|
+
args=(Arg("path"),),
|
|
703
|
+
),
|
|
704
|
+
Command(
|
|
705
|
+
"disable",
|
|
706
|
+
"Temporarily disable a restriction",
|
|
707
|
+
"patchi.cli.commands.restrict_cmd:run_disable",
|
|
708
|
+
args=(Arg("path"),),
|
|
709
|
+
),
|
|
710
|
+
Command(
|
|
711
|
+
"enable",
|
|
712
|
+
"Re-enable a restriction",
|
|
713
|
+
"patchi.cli.commands.restrict_cmd:run_enable",
|
|
714
|
+
args=(Arg("path"),),
|
|
715
|
+
),
|
|
716
|
+
),
|
|
717
|
+
),
|
|
718
|
+
# ── Batch 5: Legacy ladder commands migrated last ──────────────────────
|
|
719
|
+
Command(
|
|
720
|
+
"check",
|
|
721
|
+
"Preflight install/build/format — side agents before app run (also --fix domain: type/deps)",
|
|
722
|
+
"patchi.cli.commands.check_cmd:run",
|
|
723
|
+
args=(
|
|
724
|
+
Arg("--fix", action="store_true", help="Auto-fix domain issues (type/deps/build)"),
|
|
725
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
726
|
+
),
|
|
727
|
+
),
|
|
728
|
+
Command(
|
|
729
|
+
"link",
|
|
730
|
+
"Link frontend + backend for separate repos (auto discovery + tag confirm)",
|
|
731
|
+
"patchi.cli.commands.link_cmd:run",
|
|
732
|
+
args=(
|
|
733
|
+
Arg("action", nargs="?", choices=("status", "add", "confirm", "remove", "list"), help="status|add|confirm|remove"),
|
|
734
|
+
Arg("--frontend", dest="frontend", default=None, help="Frontend repo path (for add)"),
|
|
735
|
+
Arg("--backend", dest="backend", default=None, help="Backend repo path (for add)"),
|
|
736
|
+
Arg("--frontend-url", dest="frontend_url", default=None, help="Frontend URL"),
|
|
737
|
+
Arg("--backend-url", dest="backend_url", default=None, help="Backend URL"),
|
|
738
|
+
),
|
|
739
|
+
),
|
|
740
|
+
Command(
|
|
741
|
+
"report",
|
|
742
|
+
"Generate a structured analysis report",
|
|
743
|
+
"patchi.cli.commands.report_cmd:run",
|
|
744
|
+
args=(
|
|
745
|
+
Arg("report_cmd", nargs="?", choices=("export", "weekly"), help="export | weekly"),
|
|
746
|
+
Arg("--format", dest="fmt", default="markdown", help="Output format (markdown | json)"),
|
|
747
|
+
),
|
|
748
|
+
),
|
|
749
|
+
Command(
|
|
750
|
+
"assure",
|
|
751
|
+
"Assurance campaigns — prove properties, record evidence",
|
|
752
|
+
"patchi.cli.commands.assure_cmd:run",
|
|
753
|
+
args=(
|
|
754
|
+
Arg("--json", dest="json_output", action="store_true", help="JSON output"),
|
|
755
|
+
Arg("--reset", action="store_true", help="Discard all recorded claims/evidence"),
|
|
756
|
+
Arg(
|
|
757
|
+
"--run-attackers",
|
|
758
|
+
dest="run_attackers",
|
|
759
|
+
action="store_true",
|
|
760
|
+
help="Run adversarial attacker hypotheses against the assurance graph",
|
|
761
|
+
),
|
|
762
|
+
Arg(
|
|
763
|
+
"--run-campaigns",
|
|
764
|
+
dest="run_campaigns",
|
|
765
|
+
action="store_true",
|
|
766
|
+
help="Run state transition + data flow abuse campaigns",
|
|
767
|
+
),
|
|
768
|
+
Arg(
|
|
769
|
+
"--run-all",
|
|
770
|
+
dest="run_all",
|
|
771
|
+
action="store_true",
|
|
772
|
+
help="Run attackers + campaigns + fuzz in sequence",
|
|
773
|
+
),
|
|
774
|
+
Arg(
|
|
775
|
+
"--chain-report",
|
|
776
|
+
dest="chain_report",
|
|
777
|
+
action="store_true",
|
|
778
|
+
help="Show chain-sourced assurance claims with remediation",
|
|
779
|
+
),
|
|
780
|
+
),
|
|
781
|
+
),
|
|
782
|
+
Command(
|
|
783
|
+
"audit",
|
|
784
|
+
"Full project audit + Plan-vs-Built drift",
|
|
785
|
+
"patchi.cli.commands.audit_cmd:run",
|
|
786
|
+
args=(
|
|
787
|
+
Arg("--quick", action="store_true", help="Quick audit (skip deep scan)"),
|
|
788
|
+
Arg("--json", dest="json_output", action="store_true", help="JSON output"),
|
|
789
|
+
Arg("--plan", action="store_true", help="Snapshot current state as the agreed Plan"),
|
|
790
|
+
Arg(
|
|
791
|
+
"--plan-file",
|
|
792
|
+
dest="plan_file",
|
|
793
|
+
type=str,
|
|
794
|
+
help="Audit built state against a plan file",
|
|
795
|
+
),
|
|
796
|
+
Arg("--intent", type=str, help="Intent description (with --plan)"),
|
|
797
|
+
Arg("--no-scan", dest="no_scan", action="store_true", help="Skip scan during audit"),
|
|
798
|
+
Arg("--html", type=str, help="Write self-contained HTML report"),
|
|
799
|
+
),
|
|
800
|
+
),
|
|
801
|
+
Command(
|
|
802
|
+
"settings",
|
|
803
|
+
"View or modify configuration",
|
|
804
|
+
"patchi.cli.commands.settings_cmd:run_show", # no subcommand -> show
|
|
805
|
+
subcommands=(
|
|
806
|
+
Command(
|
|
807
|
+
"show", "Show current configuration", "patchi.cli.commands.settings_cmd:run_show"
|
|
808
|
+
),
|
|
809
|
+
Command(
|
|
810
|
+
"set",
|
|
811
|
+
"Set a configuration value",
|
|
812
|
+
"patchi.cli.commands.settings_cmd:run_set",
|
|
813
|
+
args=(Arg("key"), Arg("value")),
|
|
814
|
+
),
|
|
815
|
+
Command(
|
|
816
|
+
"mode",
|
|
817
|
+
"View or set operating mode (confirm/auto/autopilot)",
|
|
818
|
+
"patchi.cli.commands.mode_cmd:run",
|
|
819
|
+
args=(
|
|
820
|
+
Arg("mode_str", nargs="?", choices=("confirm", "auto", "autopilot"), help="New mode"),
|
|
821
|
+
),
|
|
822
|
+
),
|
|
823
|
+
),
|
|
824
|
+
),
|
|
825
|
+
Command(
|
|
826
|
+
"access",
|
|
827
|
+
"Manage dev access tokens",
|
|
828
|
+
"patchi.cli.commands.access_cmd:run_list", # no subcommand -> list
|
|
829
|
+
subcommands=(
|
|
830
|
+
Command(
|
|
831
|
+
"add",
|
|
832
|
+
"Add a token",
|
|
833
|
+
"patchi.cli.commands.access_cmd:run_add",
|
|
834
|
+
args=(Arg("name"), Arg("--env-var", dest="env_var")),
|
|
835
|
+
),
|
|
836
|
+
Command("list", "List all tokens", "patchi.cli.commands.access_cmd:run_list"),
|
|
837
|
+
Command(
|
|
838
|
+
"remove",
|
|
839
|
+
"Remove a token",
|
|
840
|
+
"patchi.cli.commands.access_cmd:run_remove",
|
|
841
|
+
args=(Arg("name"),),
|
|
842
|
+
),
|
|
843
|
+
),
|
|
844
|
+
),
|
|
845
|
+
Command(
|
|
846
|
+
"web",
|
|
847
|
+
"Launch the unified Patchi web UI (dashboard, council, red team, tests, hosted)",
|
|
848
|
+
"patchi.cli.commands.web_cmd:run",
|
|
849
|
+
args=(
|
|
850
|
+
Arg("--host", help="Bind address", default="127.0.0.1"),
|
|
851
|
+
Arg("--port", help="Port to listen on", default=1612, type=int),
|
|
852
|
+
Arg(
|
|
853
|
+
"--open",
|
|
854
|
+
help="Open the browser after start",
|
|
855
|
+
action="store_true",
|
|
856
|
+
dest="open_browser",
|
|
857
|
+
),
|
|
858
|
+
Arg(
|
|
859
|
+
"--project",
|
|
860
|
+
help="Path to the project to view (default: nearest .patchi up from cwd)",
|
|
861
|
+
default=None,
|
|
862
|
+
),
|
|
863
|
+
),
|
|
864
|
+
),
|
|
865
|
+
Command(
|
|
866
|
+
"ai",
|
|
867
|
+
"AI configuration and status",
|
|
868
|
+
"patchi.cli.commands.ai_cmd:run_status", # no subcommand -> status
|
|
869
|
+
subcommands=(
|
|
870
|
+
Command(
|
|
871
|
+
"status",
|
|
872
|
+
"Show all configured AI keys and status",
|
|
873
|
+
"patchi.cli.commands.ai_cmd:run_status",
|
|
874
|
+
),
|
|
875
|
+
Command(
|
|
876
|
+
"test",
|
|
877
|
+
"Send test prompt to active AI provider",
|
|
878
|
+
"patchi.cli.commands.ai_cmd:run_test",
|
|
879
|
+
),
|
|
880
|
+
Command("add", "Add a new API key interactively", "patchi.cli.commands.ai_cmd:run_add"),
|
|
881
|
+
Command(
|
|
882
|
+
"remove",
|
|
883
|
+
"Remove an API key by name",
|
|
884
|
+
"patchi.cli.commands.ai_cmd:run_remove",
|
|
885
|
+
args=(Arg("name"),),
|
|
886
|
+
),
|
|
887
|
+
Command(
|
|
888
|
+
"profiles",
|
|
889
|
+
"List configured AI provider profiles (E-12 S-2)",
|
|
890
|
+
"patchi.cli.commands.ai_cmd:run_profiles",
|
|
891
|
+
),
|
|
892
|
+
),
|
|
893
|
+
),
|
|
894
|
+
Command(
|
|
895
|
+
"charter",
|
|
896
|
+
"Manage project charter and rules",
|
|
897
|
+
"patchi.cli.commands.charter_cmd:run_show",
|
|
898
|
+
namespace_handler=True,
|
|
899
|
+
subcommands=(
|
|
900
|
+
Command("show", "Show current charter", "patchi.cli.commands.charter_cmd:run_show", namespace_handler=True),
|
|
901
|
+
Command(
|
|
902
|
+
"set",
|
|
903
|
+
"Set charter from a file",
|
|
904
|
+
"patchi.cli.commands.charter_cmd:run_set",
|
|
905
|
+
namespace_handler=True,
|
|
906
|
+
args=(
|
|
907
|
+
Arg("text"),
|
|
908
|
+
Arg(
|
|
909
|
+
"--ai",
|
|
910
|
+
dest="use_ai",
|
|
911
|
+
action="store_true",
|
|
912
|
+
help="Use AI to generate charter",
|
|
913
|
+
),
|
|
914
|
+
),
|
|
915
|
+
),
|
|
916
|
+
Command(
|
|
917
|
+
"check",
|
|
918
|
+
"Check code against charter",
|
|
919
|
+
"patchi.cli.commands.charter_cmd:run_check",
|
|
920
|
+
namespace_handler=True,
|
|
921
|
+
args=(Arg("--rebuild", action="store_true", help="Rebuild charter index"),),
|
|
922
|
+
),
|
|
923
|
+
Command(
|
|
924
|
+
"hooks",
|
|
925
|
+
"Manage git hooks",
|
|
926
|
+
"patchi.cli.commands.charter_cmd:run_hooks",
|
|
927
|
+
namespace_handler=True,
|
|
928
|
+
args=(Arg("--install", action="store_true", help="Install git hooks"),),
|
|
929
|
+
),
|
|
930
|
+
),
|
|
931
|
+
),
|
|
932
|
+
Command(
|
|
933
|
+
"chains",
|
|
934
|
+
"Show exploit chains and intent gaps from last scan",
|
|
935
|
+
"patchi.cli.commands.chains_cmd:run",
|
|
936
|
+
args=(
|
|
937
|
+
Arg("--min-score", type=float, default=0, help="Filter chains by minimum score"),
|
|
938
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
939
|
+
Arg("--fix", action="store_true", help="Apply auto-fixable remediations via RiskGate"),
|
|
940
|
+
Arg("--analyze", action="store_true", help="Analyze findings from memory (like old p chain)"),
|
|
941
|
+
Arg("--min-severity", dest="min_severity", default="medium", help="Minimum severity for --analyze mode"),
|
|
942
|
+
),
|
|
943
|
+
),
|
|
944
|
+
Command(
|
|
945
|
+
"findings",
|
|
946
|
+
"View and manage security findings",
|
|
947
|
+
"patchi.cli.commands.findings_cmd:run",
|
|
948
|
+
namespace_handler=True,
|
|
949
|
+
args=(
|
|
950
|
+
Arg("--summary", action="store_true", help="Per-agent before/after counts"),
|
|
951
|
+
Arg("--save-baseline", action="store_true", help="Snapshot current counts as baseline"),
|
|
952
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
953
|
+
),
|
|
954
|
+
),
|
|
955
|
+
Command(
|
|
956
|
+
"rules",
|
|
957
|
+
"View and validate security rule packs",
|
|
958
|
+
"patchi.cli.commands.rules_cmd:run",
|
|
959
|
+
namespace_handler=True,
|
|
960
|
+
args=(
|
|
961
|
+
Arg("--validate", action="store_true", help="Validate all rule packs"),
|
|
962
|
+
Arg(
|
|
963
|
+
"--which", type=str, default=None, help="Map a finding control id to its rule pack"
|
|
964
|
+
),
|
|
965
|
+
),
|
|
966
|
+
),
|
|
967
|
+
# ── Batch 6: the last commands off the legacy ladder. ────────────────────
|
|
968
|
+
# notify / hosted / test / security / cross-repo use the self-routing
|
|
969
|
+
# Namespace-handler shape (framework namespace_handler=True): the handler
|
|
970
|
+
# receives the whole parsed Namespace and routes on the subcommand dests
|
|
971
|
+
# itself, so the subcommand tree below is parsing/help sugar only. `help`
|
|
972
|
+
# is a plain kwarg command backed by help_cmd.py. With these six, main.py
|
|
973
|
+
# has zero elif-dispatch left — the registry IS the router.
|
|
974
|
+
Command(
|
|
975
|
+
"notify",
|
|
976
|
+
"Configure notifications",
|
|
977
|
+
"patchi.cli.commands.notify_cmd:run_notify",
|
|
978
|
+
namespace_handler=True,
|
|
979
|
+
subcommands=(
|
|
980
|
+
Command("list", "List channels"),
|
|
981
|
+
Command(
|
|
982
|
+
"add",
|
|
983
|
+
"Add a notification channel",
|
|
984
|
+
args=(
|
|
985
|
+
Arg(
|
|
986
|
+
"channel_type", choices=("email", "slack", "discord", "webhook", "telegram")
|
|
987
|
+
),
|
|
988
|
+
),
|
|
989
|
+
),
|
|
990
|
+
Command("remove", "Remove a channel", args=(Arg("channel_name"),)),
|
|
991
|
+
Command(
|
|
992
|
+
"test",
|
|
993
|
+
"Send test alert to all or one channel",
|
|
994
|
+
args=(Arg("channel_name", nargs="?"),),
|
|
995
|
+
),
|
|
996
|
+
Command("ack", "Acknowledge a CRITICAL/HIGH alert", args=(Arg("alert_id"),)),
|
|
997
|
+
Command("flush", "Force-flush the digest queue now"),
|
|
998
|
+
Command("pending", "Show unacknowledged escalation alerts"),
|
|
999
|
+
),
|
|
1000
|
+
),
|
|
1001
|
+
Command(
|
|
1002
|
+
"hosted",
|
|
1003
|
+
"Hosted mode — monitor live apps(experimental)",
|
|
1004
|
+
"patchi.cli.commands.hosted_cmd:run",
|
|
1005
|
+
namespace_handler=True,
|
|
1006
|
+
subcommands=(
|
|
1007
|
+
Command("init", "Set up hosted mode (interactive)"),
|
|
1008
|
+
Command("worker", "Start the background worker"),
|
|
1009
|
+
Command(
|
|
1010
|
+
"daemon",
|
|
1011
|
+
"Start worker with auto-restart + health checks",
|
|
1012
|
+
args=(
|
|
1013
|
+
Arg(
|
|
1014
|
+
"--guard",
|
|
1015
|
+
action="store_true",
|
|
1016
|
+
help="Also run anomaly detection in daemon mode",
|
|
1017
|
+
),
|
|
1018
|
+
),
|
|
1019
|
+
),
|
|
1020
|
+
Command("stop", "Stop a running daemon"),
|
|
1021
|
+
Command("guard", "Start live guard monitoring"),
|
|
1022
|
+
Command(
|
|
1023
|
+
"status",
|
|
1024
|
+
"Show connection status",
|
|
1025
|
+
args=(Arg("--json", action="store_true", help="Output as JSON"),),
|
|
1026
|
+
),
|
|
1027
|
+
Command("logs", "Stream hosted logs in real time"),
|
|
1028
|
+
Command(
|
|
1029
|
+
"token",
|
|
1030
|
+
"Manage admin tokens",
|
|
1031
|
+
subcommands=(
|
|
1032
|
+
Command("add", "Generate new admin token"),
|
|
1033
|
+
Command("list", "List active tokens"),
|
|
1034
|
+
Command("revoke", "Revoke a token", args=(Arg("id"),)),
|
|
1035
|
+
),
|
|
1036
|
+
),
|
|
1037
|
+
Command("block", "Block an IP address", args=(Arg("ip"),)),
|
|
1038
|
+
Command("unblock", "Unblock an IP address", args=(Arg("ip"),)),
|
|
1039
|
+
Command("disconnect", "Disconnect from hosted mode"),
|
|
1040
|
+
),
|
|
1041
|
+
),
|
|
1042
|
+
Command(
|
|
1043
|
+
"test",
|
|
1044
|
+
"Run tests, generate suites, view history",
|
|
1045
|
+
"patchi.cli.commands.test_cmd:run_test",
|
|
1046
|
+
namespace_handler=True,
|
|
1047
|
+
args=(
|
|
1048
|
+
Arg(
|
|
1049
|
+
"type",
|
|
1050
|
+
nargs="?",
|
|
1051
|
+
help="Test type, agent name, or generate/report/config subcommand",
|
|
1052
|
+
),
|
|
1053
|
+
Arg("area", nargs="?", help="Test scope area, or config action for 'config'"),
|
|
1054
|
+
Arg("config_key", nargs="?", help="Config key to set"),
|
|
1055
|
+
Arg("config_value", nargs="?", help="New value for config key"),
|
|
1056
|
+
Arg("--last", type=int, default=20, help="Number of recent runs to show"),
|
|
1057
|
+
Arg(
|
|
1058
|
+
"--attack",
|
|
1059
|
+
action="store_true",
|
|
1060
|
+
help="Run Metasploit auxiliary/scanner probes against localhost (requires msfrpcd)",
|
|
1061
|
+
),
|
|
1062
|
+
),
|
|
1063
|
+
),
|
|
1064
|
+
# `p security` merged into `p scan` — use `p scan --deep` or `p scan <area>`
|
|
1065
|
+
Command(
|
|
1066
|
+
"command",
|
|
1067
|
+
"List all commands with tags and arguments",
|
|
1068
|
+
"patchi.cli.commands.help_cmd:run",
|
|
1069
|
+
namespace_handler=True,
|
|
1070
|
+
args=(
|
|
1071
|
+
Arg("--all", action="store_true", help="Show all commands with arguments and subcommands"),
|
|
1072
|
+
Arg("--json", action="store_true", help="Output as JSON"),
|
|
1073
|
+
Arg("--write-md", action="store_true", help="Write command_list.md"),
|
|
1074
|
+
),
|
|
1075
|
+
),
|
|
1076
|
+
Command(
|
|
1077
|
+
"help",
|
|
1078
|
+
"Show command help",
|
|
1079
|
+
"patchi.cli.commands.help_cmd:run",
|
|
1080
|
+
namespace_handler=True,
|
|
1081
|
+
args=(Arg("group", nargs="?", help="Command group"),),
|
|
1082
|
+
),
|
|
1083
|
+
# `p smart` merged into `p chat` — use `p chat --stream` for the same functionality
|
|
1084
|
+
Command(
|
|
1085
|
+
"cross-repo",
|
|
1086
|
+
"Cross-repository dependency intelligence",
|
|
1087
|
+
"patchi.cli.commands.cross_repo_cmd:run",
|
|
1088
|
+
namespace_handler=True,
|
|
1089
|
+
args=(
|
|
1090
|
+
Arg(
|
|
1091
|
+
"action",
|
|
1092
|
+
nargs="?",
|
|
1093
|
+
default="scan",
|
|
1094
|
+
choices=("scan", "health", "fix"),
|
|
1095
|
+
help="Action: scan (default), health, fix",
|
|
1096
|
+
),
|
|
1097
|
+
Arg("--target", type=str, help="Target project path for fix action"),
|
|
1098
|
+
),
|
|
1099
|
+
),
|
|
1100
|
+
Command(
|
|
1101
|
+
"goal",
|
|
1102
|
+
"Autonomous mode: loop the agent pipeline until the health score hits the target",
|
|
1103
|
+
"patchi.cli.commands.goal_cmd:run",
|
|
1104
|
+
args=(
|
|
1105
|
+
Arg("--max-loops", type=int, default=5, help="Maximum pipeline iterations (default 5)"),
|
|
1106
|
+
Arg(
|
|
1107
|
+
"--target", type=int, default=100, help="Health score target to reach (default 100)"
|
|
1108
|
+
),
|
|
1109
|
+
Arg(
|
|
1110
|
+
"--dry-run",
|
|
1111
|
+
action="store_true",
|
|
1112
|
+
help="Produce + verify patches but never apply them",
|
|
1113
|
+
),
|
|
1114
|
+
),
|
|
1115
|
+
),
|
|
1116
|
+
Command(
|
|
1117
|
+
"cleanup",
|
|
1118
|
+
"Clean stale .patchi/ artifacts (JUnit, caches, logs, DBs)",
|
|
1119
|
+
"patchi.cli.commands.cleanup_cmd:cleanup",
|
|
1120
|
+
args=(
|
|
1121
|
+
Arg("--apply", action="store_true", help="Actually delete files (default is dry-run)"),
|
|
1122
|
+
Arg("--all", action="store_true", help="Also remove evidence/screenshots"),
|
|
1123
|
+
Arg("--older-than", dest="older_than", default=None, help="Only remove files older than this (e.g. 7d, 24h, 30m)"),
|
|
1124
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON for CI integration"),
|
|
1125
|
+
),
|
|
1126
|
+
),
|
|
1127
|
+
Command(
|
|
1128
|
+
"agent-stats",
|
|
1129
|
+
"Agent profiling stats and learning state",
|
|
1130
|
+
"patchi.cli.commands.agent_stats_cmd:run",
|
|
1131
|
+
args=(
|
|
1132
|
+
Arg("agent_name", nargs="?", default=None, help="Show details for a specific agent"),
|
|
1133
|
+
Arg("--profile", dest="show_profile", action="store_true", help="Show only profiler stats"),
|
|
1134
|
+
Arg("--learning", dest="show_learning", action="store_true", help="Show only learning state"),
|
|
1135
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
1136
|
+
),
|
|
1137
|
+
),
|
|
1138
|
+
Command(
|
|
1139
|
+
"vr",
|
|
1140
|
+
"Visual regression baseline management",
|
|
1141
|
+
"patchi.cli.commands.vr_cmd:run",
|
|
1142
|
+
args=(
|
|
1143
|
+
Arg(
|
|
1144
|
+
"action",
|
|
1145
|
+
nargs="?",
|
|
1146
|
+
default="list",
|
|
1147
|
+
choices=("capture", "baseline", "compare", "diff", "reset", "list", "ls"),
|
|
1148
|
+
help="baseline=capture, compare=diff, reset=delete, list=show",
|
|
1149
|
+
),
|
|
1150
|
+
Arg("--json", dest="json_output", action="store_true", help="Output as JSON"),
|
|
1151
|
+
),
|
|
1152
|
+
),
|
|
1153
|
+
Command(
|
|
1154
|
+
"plugins",
|
|
1155
|
+
"Manage analyzer plugins (list, run, info)",
|
|
1156
|
+
"patchi.cli.commands.plugins_cmd:cmd_plugins",
|
|
1157
|
+
namespace_handler=True,
|
|
1158
|
+
args=(
|
|
1159
|
+
Arg("args", nargs="*", help="Plugin subcommand and arguments"),
|
|
1160
|
+
),
|
|
1161
|
+
),
|
|
1162
|
+
Command(
|
|
1163
|
+
"commands",
|
|
1164
|
+
"Show command families and subcommands",
|
|
1165
|
+
"patchi.cli.commands.commands_cmd:run",
|
|
1166
|
+
args=(
|
|
1167
|
+
Arg("--flat", action="store_true", help="Alphabetical list of all commands"),
|
|
1168
|
+
Arg("--search", dest="search", type=str, help="Search commands by name/description"),
|
|
1169
|
+
),
|
|
1170
|
+
),
|
|
1171
|
+
]
|