@orionscanner/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +248 -0
  3. package/assets/logo.png +0 -0
  4. package/bin/orion.js +48 -0
  5. package/docs/API_REFERENCE.md +211 -0
  6. package/docs/ARCHITECTURE.md +183 -0
  7. package/docs/CHANGELOG.md +112 -0
  8. package/docs/CONTRIBUTING.md +157 -0
  9. package/docs/ENGINE_CATALOG.md +87 -0
  10. package/docs/GETTING_STARTED.md +226 -0
  11. package/package.json +48 -0
  12. package/pyproject.toml +16 -0
  13. package/src/orion/__init__.py +0 -0
  14. package/src/orion/__pycache__/__init__.cpython-313.pyc +0 -0
  15. package/src/orion/engine/__init__.py +17 -0
  16. package/src/orion/engine/__pycache__/__init__.cpython-313.pyc +0 -0
  17. package/src/orion/engine/__pycache__/config.cpython-313.pyc +0 -0
  18. package/src/orion/engine/__pycache__/core.cpython-313.pyc +0 -0
  19. package/src/orion/engine/__pycache__/ir.cpython-313.pyc +0 -0
  20. package/src/orion/engine/__pycache__/languages.cpython-313.pyc +0 -0
  21. package/src/orion/engine/__pycache__/registry.cpython-313.pyc +0 -0
  22. package/src/orion/engine/__pycache__/results.cpython-313.pyc +0 -0
  23. package/src/orion/engine/__pycache__/runner.cpython-313.pyc +0 -0
  24. package/src/orion/engine/api_security/__pycache__/engine.cpython-313.pyc +0 -0
  25. package/src/orion/engine/api_security/engine.py +125 -0
  26. package/src/orion/engine/architecture/__pycache__/engine.cpython-313.pyc +0 -0
  27. package/src/orion/engine/architecture/engine.py +463 -0
  28. package/src/orion/engine/authorization/__pycache__/engine.cpython-313.pyc +0 -0
  29. package/src/orion/engine/authorization/engine.py +337 -0
  30. package/src/orion/engine/callgraph/__pycache__/engine.cpython-313.pyc +0 -0
  31. package/src/orion/engine/callgraph/engine.py +236 -0
  32. package/src/orion/engine/cfg/__pycache__/engine.cpython-313.pyc +0 -0
  33. package/src/orion/engine/cfg/engine.py +509 -0
  34. package/src/orion/engine/chaos/__pycache__/engine.cpython-313.pyc +0 -0
  35. package/src/orion/engine/chaos/engine.py +268 -0
  36. package/src/orion/engine/chaos_config/__pycache__/engine.cpython-313.pyc +0 -0
  37. package/src/orion/engine/chaos_config/engine.py +322 -0
  38. package/src/orion/engine/complexity/__pycache__/engine.cpython-313.pyc +0 -0
  39. package/src/orion/engine/complexity/engine.py +144 -0
  40. package/src/orion/engine/compliance/__pycache__/engine.cpython-313.pyc +0 -0
  41. package/src/orion/engine/compliance/engine.py +325 -0
  42. package/src/orion/engine/config.py +41 -0
  43. package/src/orion/engine/config_engine/__pycache__/engine.cpython-313.pyc +0 -0
  44. package/src/orion/engine/config_engine/engine.py +364 -0
  45. package/src/orion/engine/config_validation/__pycache__/engine.cpython-313.pyc +0 -0
  46. package/src/orion/engine/config_validation/engine.py +313 -0
  47. package/src/orion/engine/container/__pycache__/engine.cpython-313.pyc +0 -0
  48. package/src/orion/engine/container/engine.py +546 -0
  49. package/src/orion/engine/contract_probe/__pycache__/engine.cpython-313.pyc +0 -0
  50. package/src/orion/engine/contract_probe/engine.py +316 -0
  51. package/src/orion/engine/core.py +75 -0
  52. package/src/orion/engine/crypto_guard/__pycache__/engine.cpython-313.pyc +0 -0
  53. package/src/orion/engine/crypto_guard/engine.py +134 -0
  54. package/src/orion/engine/data_residency/__pycache__/engine.cpython-313.pyc +0 -0
  55. package/src/orion/engine/data_residency/engine.py +238 -0
  56. package/src/orion/engine/dataflow/__pycache__/engine.cpython-313.pyc +0 -0
  57. package/src/orion/engine/dataflow/engine.py +398 -0
  58. package/src/orion/engine/dead_import/__pycache__/engine.cpython-313.pyc +0 -0
  59. package/src/orion/engine/dead_import/engine.py +293 -0
  60. package/src/orion/engine/deps/__pycache__/engine.cpython-313.pyc +0 -0
  61. package/src/orion/engine/deps/engine.py +244 -0
  62. package/src/orion/engine/dispatcher.py +350 -0
  63. package/src/orion/engine/docs/AUDIT_PROMPT.md +1248 -0
  64. package/src/orion/engine/duplication/__pycache__/engine.cpython-313.pyc +0 -0
  65. package/src/orion/engine/duplication/engine.py +120 -0
  66. package/src/orion/engine/error_handling/__pycache__/engine.cpython-313.pyc +0 -0
  67. package/src/orion/engine/error_handling/engine.py +256 -0
  68. package/src/orion/engine/fp_learn/__pycache__/engine.cpython-313.pyc +0 -0
  69. package/src/orion/engine/fp_learn/engine.py +248 -0
  70. package/src/orion/engine/hunter/__pycache__/engine.cpython-313.pyc +0 -0
  71. package/src/orion/engine/hunter/engine.py +324 -0
  72. package/src/orion/engine/iac_security/__pycache__/engine.cpython-313.pyc +0 -0
  73. package/src/orion/engine/iac_security/engine.py +218 -0
  74. package/src/orion/engine/ir.py +22 -0
  75. package/src/orion/engine/languages.py +454 -0
  76. package/src/orion/engine/license/__pycache__/engine.cpython-313.pyc +0 -0
  77. package/src/orion/engine/license/engine.py +172 -0
  78. package/src/orion/engine/lint/__pycache__/engine.cpython-313.pyc +0 -0
  79. package/src/orion/engine/lint/engine.py +558 -0
  80. package/src/orion/engine/llm_security/__pycache__/engine.cpython-313.pyc +0 -0
  81. package/src/orion/engine/llm_security/engine.py +125 -0
  82. package/src/orion/engine/logging_c/__pycache__/engine.cpython-313.pyc +0 -0
  83. package/src/orion/engine/logging_c/engine.py +164 -0
  84. package/src/orion/engine/noise/__pycache__/engine.cpython-313.pyc +0 -0
  85. package/src/orion/engine/noise/engine.py +140 -0
  86. package/src/orion/engine/orphan/__pycache__/engine.cpython-313.pyc +0 -0
  87. package/src/orion/engine/orphan/engine.py +244 -0
  88. package/src/orion/engine/perf_guard/__pycache__/engine.cpython-313.pyc +0 -0
  89. package/src/orion/engine/perf_guard/engine.py +345 -0
  90. package/src/orion/engine/prompt_security/__pycache__/engine.cpython-313.pyc +0 -0
  91. package/src/orion/engine/prompt_security/detectors/__init__.py +4 -0
  92. package/src/orion/engine/prompt_security/engine.py +170 -0
  93. package/src/orion/engine/provenance/__pycache__/engine.cpython-313.pyc +0 -0
  94. package/src/orion/engine/provenance/engine.py +242 -0
  95. package/src/orion/engine/registry.py +55 -0
  96. package/src/orion/engine/regression/__pycache__/engine.cpython-313.pyc +0 -0
  97. package/src/orion/engine/regression/engine.py +213 -0
  98. package/src/orion/engine/results.py +21 -0
  99. package/src/orion/engine/runner.py +1310 -0
  100. package/src/orion/engine/sandbox_escape/__pycache__/engine.cpython-313.pyc +0 -0
  101. package/src/orion/engine/sandbox_escape/engine.py +284 -0
  102. package/src/orion/engine/sast/__pycache__/engine.cpython-313.pyc +0 -0
  103. package/src/orion/engine/sast/engine.py +217 -0
  104. package/src/orion/engine/sast/patterns/__init__.py +513 -0
  105. package/src/orion/engine/sast/patterns/__pycache__/__init__.cpython-313.pyc +0 -0
  106. package/src/orion/engine/secrets/__pycache__/engine.cpython-313.pyc +0 -0
  107. package/src/orion/engine/secrets/engine.py +77 -0
  108. package/src/orion/engine/secrets/patterns/__init__.py +74 -0
  109. package/src/orion/engine/secrets/patterns/__pycache__/__init__.cpython-313.pyc +0 -0
  110. package/src/orion/engine/sensitive_data/__pycache__/engine.cpython-313.pyc +0 -0
  111. package/src/orion/engine/sensitive_data/engine.py +143 -0
  112. package/src/orion/engine/state/__pycache__/engine.cpython-313.pyc +0 -0
  113. package/src/orion/engine/state/engine.py +218 -0
  114. package/src/orion/engine/supply_chain_sbom/__pycache__/engine.cpython-313.pyc +0 -0
  115. package/src/orion/engine/supply_chain_sbom/engine.py +290 -0
  116. package/src/orion/engine/symbol/__pycache__/engine.cpython-313.pyc +0 -0
  117. package/src/orion/engine/symbol/engine.py +463 -0
  118. package/src/orion/engine/taint/__pycache__/engine.cpython-313.pyc +0 -0
  119. package/src/orion/engine/taint/engine.py +464 -0
  120. package/src/orion/engine/test_coverage/__pycache__/engine.cpython-313.pyc +0 -0
  121. package/src/orion/engine/test_coverage/engine.py +445 -0
  122. package/src/orion/engine/threat_model/__pycache__/engine.cpython-313.pyc +0 -0
  123. package/src/orion/engine/threat_model/engine.py +126 -0
  124. package/src/orion/engine/wiring_trace/__pycache__/engine.cpython-313.pyc +0 -0
  125. package/src/orion/engine/wiring_trace/engine.py +200 -0
  126. package/src/orion_engine.egg-info/PKG-INFO +7 -0
  127. package/src/orion_engine.egg-info/SOURCES.txt +65 -0
  128. package/src/orion_engine.egg-info/dependency_links.txt +1 -0
  129. package/src/orion_engine.egg-info/entry_points.txt +2 -0
  130. package/src/orion_engine.egg-info/top_level.txt +1 -0
@@ -0,0 +1,1310 @@
1
+ #!/usr/bin/env python3
2
+ """Orion Engine - Enterprise Code Audit & Security Platform.
3
+
4
+ Proprietary In-House Engines for Security Auditing, Architecture & Governance.
5
+ """
6
+
7
+ import asyncio
8
+ import base64
9
+ import json
10
+ import sys
11
+ import html
12
+ import itertools
13
+ import os
14
+ import re
15
+ import threading
16
+ import time
17
+ from datetime import datetime
18
+ from pathlib import Path
19
+
20
+ from orion.engine import OrionEngine, EngineConfig, ResourceLimits
21
+ from orion.engine.ir import OrionIR
22
+ from orion.engine.languages import detect_language, is_binary_file, Language
23
+
24
+
25
+ # Ensure UTF-8 stdout on Windows console
26
+ if sys.platform == "win32":
27
+ try:
28
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
29
+ sys.stderr.reconfigure(encoding="utf-8", errors="replace")
30
+ except Exception:
31
+ pass
32
+
33
+
34
+ def clear_screen():
35
+ """Clear terminal screen cross-platform safely without shell execution."""
36
+ sys.stdout.write("\033[H\033[2J")
37
+ sys.stdout.flush()
38
+
39
+
40
+ # --- CLI Terminal Professional Styling Tokens ---
41
+ RESET = "\033[0m"
42
+ BOLD = "\033[1m"
43
+ DIM = "\033[2m"
44
+ ITALIC = "\033[3m"
45
+ UNDERLINE = "\033[4m"
46
+
47
+ RED = "\033[91m"
48
+ GREEN = "\033[92m"
49
+ YELLOW = "\033[93m"
50
+ BLUE = "\033[94m"
51
+ MAGENTA = "\033[95m"
52
+ CYAN = "\033[96m"
53
+ WHITE = "\033[97m"
54
+
55
+
56
+ BANNER = f"""{CYAN}{BOLD}
57
+ ┌───────────────────────────────────────────────────────────────────────────────────┐
58
+ │ ___ ____ _____ ____ _ __ {WHITE}{BOLD}ORION SECURITY SUITE{CYAN} │
59
+ │ / __ \\/ __ \\/ _/ __ \\/ | / / {DIM}Code Intelligence & Governance{CYAN} │
60
+ │ / / / / /_/ // // / / / |/ / {CYAN}─── {WHITE}{BOLD}SEE. ANALYZE. IMPROVE.{RESET}{CYAN} ──────────────── │
61
+ │/ /_/ / _, _// // /_/ / /| / │
62
+ │\\____/_/ |_/___/\\____/_/ |_/ {DIM}SAST & Threat Modeling{CYAN} │
63
+ └───────────────────────────────────────────────────────────────────────────────────┘{RESET}
64
+ """
65
+
66
+ MENU = f"""
67
+ {WHITE}{BOLD}AUDIT WORKSPACE EXECUTION{RESET}
68
+ {CYAN}─────────────────────────────────────────────────────────────────────────────────────{RESET}
69
+ {GREEN}{BOLD}[1]{RESET} {WHITE}{BOLD}Quick Workspace Audit{RESET} {DIM}Fast multi-engine scan on current workspace{RESET}
70
+ {GREEN}{BOLD}[2]{RESET} {WHITE}{BOLD}Full Deep Security Audit{RESET} {DIM}Comprehensive SAST, Secrets, Cloud, AI & Quality sweep{RESET}
71
+
72
+ {WHITE}{BOLD}SPECIALIZED SECURITY & COMPLIANCE SWEEPS{RESET}
73
+ {CYAN}─────────────────────────────────────────────────────────────────────────────────────{RESET}
74
+ {CYAN}{BOLD}[3]{RESET} {WHITE}Application Security & SAST{RESET} {DIM}DeepSAST™, SecretShield™, TaintStream™, AuthMatrix™{RESET}
75
+ {CYAN}{BOLD}[4]{RESET} {WHITE}Cloud, Container & IaC{RESET} {DIM}CloudPulse™, DockerAudit™, PolicyForge™, CloudConfig™{RESET}
76
+ {CYAN}{BOLD}[5]{RESET} {WHITE}AI & LLM Agent Security{RESET} {DIM}PromptArmor™, AgentShield™ (OWASP LLM Top 10){RESET}
77
+ {CYAN}{BOLD}[6]{RESET} {WHITE}Cryptography & Key Vault{RESET} {DIM}CryptoFortress™, SecretShield™ (Weak Ciphers & Keys){RESET}
78
+ {CYAN}{BOLD}[7]{RESET} {WHITE}Code Quality & Standards{RESET} {DIM}CognitivePulse™, CloneMatrix™, CleanSweep™, CodeStandard™{RESET}
79
+ {CYAN}{BOLD}[8]{RESET} {WHITE}Supply Chain & SBOM{RESET} {DIM}SupplyGuard™, VulnPulse™, LicenseAudit™, ReguGuard™{RESET}
80
+ {CYAN}{BOLD}[9]{RESET} {WHITE}Threat Model & Data Privacy{RESET} {DIM}ThreatPulse™ (STRIDE), PrivacyShield™ (PII / PCI-DSS){RESET}
81
+
82
+ {WHITE}{BOLD}REPORTING & SYSTEM STATUS{RESET}
83
+ {CYAN}─────────────────────────────────────────────────────────────────────────────────────{RESET}
84
+ {YELLOW}{BOLD}[R]{RESET} {WHITE}View Latest Report{RESET} {DIM}Open latest executive report with PDF export{RESET}
85
+ {YELLOW}{BOLD}[S]{RESET} {WHITE}Engine Health Matrix{RESET} {DIM}Inspect status and specifications of in-house engines{RESET}
86
+ {RED}{BOLD}[0]{RESET} {WHITE}Exit Orion Suite{RESET} {DIM}Terminate CLI session{RESET}
87
+ {CYAN}─────────────────────────────────────────────────────────────────────────────────────{RESET}
88
+ """
89
+
90
+
91
+ ENGINE_MARKETING_METADATA = {
92
+ # 1. Advanced Application Security & SAST
93
+ "sast": {"name": "DeepSAST™", "title": "Core Semantic Vulnerability Analyzer", "cat": "Application Security", "desc": "Next-Gen AST Code & Injection Defense"},
94
+ "taint": {"name": "TaintStream™", "title": "Source-to-Sink Dataflow Tracer", "cat": "Application Security", "desc": "Unsanitized Input & Injection Vector Tracker"},
95
+ "secrets": {"name": "SecretShield™", "title": "Credential & Token Vault", "cat": "Application Security", "desc": "Zero-Entropy Secret & Key Leak Detection"},
96
+ "authorization": {"name": "AuthMatrix™", "title": "Access Control & Privilege Guard", "cat": "Application Security", "desc": "RBAC / ABAC Broken Authorization Defense"},
97
+ "sandbox_escape": {"name": "ContainerBreak™", "title": "Sandbox & Isolation Auditor", "cat": "Application Security", "desc": "Subprocess & Jailbreak Prevention"},
98
+ "hunter": {"name": "ThreatHunter™", "title": "Zero-Day Vulnerability Hunter", "cat": "Application Security", "desc": "Proactive Exploit & Risk Vector Discovery"},
99
+
100
+ # 2. AI, LLM & Emerging Threat Defense
101
+ "prompt_security": {"name": "PromptArmor™", "title": "AI Guardrails & Jailbreak Shield", "cat": "AI & Emerging Threats", "desc": "Indirect Injection & Context Hijack Protection"},
102
+ "llm_security": {"name": "AgentShield™", "title": "OWASP LLM Top 10 Sentinel", "cat": "AI & Emerging Threats", "desc": "Autonomous Agency & Unsafe Execution Defense"},
103
+ "crypto_guard": {"name": "CryptoFortress™", "title": "Quantum-Ready Cipher Auditor", "cat": "AI & Emerging Threats", "desc": "Weak Cryptography & Broken Hash Detector"},
104
+ "api_security": {"name": "APIGuard™", "title": "Microservice & REST Security Sentry", "cat": "AI & Emerging Threats", "desc": "OWASP API Top 10 & BOLA/IDOR Defense"},
105
+
106
+ # 3. Cloud, Infrastructure & Container Governance
107
+ "iac_security": {"name": "CloudPulse™", "title": "Infrastructure-as-Code Sentinel", "cat": "Cloud & Infrastructure", "desc": "Terraform, Kubernetes & CI/CD Hardener"},
108
+ "container": {"name": "DockerAudit™", "title": "Image & Namespace Security Engine", "cat": "Cloud & Infrastructure", "desc": "Privilege Escalation & Manifest Scanner"},
109
+ "config_engine": {"name": "CloudConfig™", "title": "Environment & Secrets Validator", "cat": "Cloud & Infrastructure", "desc": "Production Settings & Env Hygiene"},
110
+ "config_validation": {"name": "PolicyForge™", "title": "Configuration Governance Engine", "cat": "Cloud & Infrastructure", "desc": "Schema & Setting Integrity Assurance"},
111
+ "chaos": {"name": "ChaosEngine™", "title": "Resilience & Fault Prober", "cat": "Cloud & Infrastructure", "desc": "Runtime Failure & Latency Simulation"},
112
+ "chaos_config": {"name": "ConfigChaos™", "title": "Stress & Edge-Case Validator", "cat": "Cloud & Infrastructure", "desc": "Configuration Fault Tolerance Testing"},
113
+
114
+ # 4. Supply Chain, Compliance & Legal Protection
115
+ "supply_chain_sbom": {"name": "SupplyGuard™", "title": "Enterprise SBOM Matrix Generator", "cat": "Supply Chain & Compliance", "desc": "CycloneDX/SPDX Inventory Assurance"},
116
+ "deps": {"name": "VulnPulse™", "title": "Real-Time Dependency CVE Scanner", "cat": "Supply Chain & Compliance", "desc": "Outdated & Compromised Package Detection"},
117
+ "license": {"name": "LicenseAudit™", "title": "Open-Source IP & Legal Compliance", "cat": "Supply Chain & Compliance", "desc": "GPL/Copyleft Risk Mitigation"},
118
+ "provenance": {"name": "ChainOfCustody™", "title": "Artifact Provenance Tracker", "cat": "Supply Chain & Compliance", "desc": "Build Integrity & Tamper Proofing"},
119
+ "compliance": {"name": "ReguGuard™", "title": "Multi-Standard Compliance Auditor", "cat": "Supply Chain & Compliance", "desc": "SOC 2, ISO 27001, HIPAA & PCI-DSS Audit"},
120
+ "data_residency": {"name": "GeoFence™", "title": "Data Sovereignty & Privacy Guard", "cat": "Supply Chain & Compliance", "desc": "GDPR, CCPA & Cross-Border Residency"},
121
+ "threat_model": {"name": "ThreatPulse™", "title": "Automated STRIDE & Boundary Model", "cat": "Supply Chain & Compliance", "desc": "Trust-Boundary Crossing & Entrypoint Risk Mapper"},
122
+ "sensitive_data": {"name": "PrivacyShield™", "title": "PII, GDPR, HIPAA & PCI-DSS Shield", "cat": "Supply Chain & Compliance", "desc": "Credit Card PAN, SSN & Cleartext PII Leak Sentry"},
123
+
124
+ # 5. Architectural Intelligence & Deep Flow Analysis
125
+ "callgraph": {"name": "GraphTrace™", "title": "Inter-Procedural Call Topology", "cat": "Architecture & Dataflow", "desc": "Deep Function Call & Callpath Mapper"},
126
+ "cfg": {"name": "ControlFlow™", "title": "Path Traversal & Reachability Engine", "cat": "Architecture & Dataflow", "desc": "Deadlock & Branch Reachability Analyzer"},
127
+ "dataflow": {"name": "DataFlow™", "title": "Global State & Variable Propagation", "cat": "Architecture & Dataflow", "desc": "Data Mutation & Side-Effect Engine"},
128
+ "symbol": {"name": "SymbolMatrix™", "title": "Cross-Module Symbol Table Engine", "cat": "Architecture & Dataflow", "desc": "Identifier Scope & Type Hierarchy"},
129
+ "architecture": {"name": "ArchPulse™", "title": "Structural Boundary & Layering Auditor", "cat": "Architecture & Dataflow", "desc": "Spaghetti Code & Circular Coupling Detector"},
130
+ "wiring_trace": {"name": "WiringTrace™", "title": "Service Bus & Pipeline Wire Tracer", "cat": "Architecture & Dataflow", "desc": "Component Interconnection Tracker"},
131
+ "state": {"name": "StateGuard™", "title": "Finite State & Race-Condition Detector", "cat": "Architecture & Dataflow", "desc": "Concurrency & Mutex Auditor"},
132
+ "contract_probe": {"name": "ContractProbe™", "title": "Microservice SLA & Interface Auditor", "cat": "Architecture & Dataflow", "desc": "HTTP Resiliency & Circuit Breaker Check"},
133
+ "orphan": {"name": "GhostCode™", "title": "Orphaned Endpoint & Asset Finder", "cat": "Architecture & Dataflow", "desc": "Zombie Routes & Unreachable Assets"},
134
+
135
+ # 6. Code Quality, Performance & Engineering Excellence
136
+ "complexity": {"name": "CognitivePulse™", "title": "Cyclomatic & Complexity Optimizer", "cat": "Quality & Performance", "desc": "Maintainability Index & Tech Debt Score"},
137
+ "duplication": {"name": "CloneMatrix™", "title": "Semantic Duplication Detector", "cat": "Quality & Performance", "desc": "Anti-Copy-Paste Refactoring Engine"},
138
+ "dead_import": {"name": "CleanSweep™", "title": "Dead Import & Dead Code Eliminator", "cat": "Quality & Performance", "desc": "Tree-Shaking & Bundle Optimizer"},
139
+ "error_handling": {"name": "ResilienceGuard™", "title": "Exception & Fault-Tolerance Auditor", "cat": "Quality & Performance", "desc": "Silent Error & Crash Prevention"},
140
+ "logging_c": {"name": "AuditLog™", "title": "Enterprise Telemetry & Audit Verifier", "cat": "Quality & Performance", "desc": "Compliance Logging & Redaction Engine"},
141
+ "lint": {"name": "CodeStandard™", "title": "Multi-Language Style Guardian", "cat": "Quality & Performance", "desc": "PEP8, Google & Enterprise Clean Code Enforcer"},
142
+ "test_coverage": {"name": "CoverageLens™", "title": "Test Gap & QA Inspector", "cat": "Quality & Performance", "desc": "Untested Path & Mutation Discovery"},
143
+ "perf_guard": {"name": "SpeedGuard™", "title": "Algorithmic & I/O Optimizer", "cat": "Quality & Performance", "desc": "Big-O & Memory Overhead Detector"},
144
+ "regression": {"name": "RegressionShield™", "title": "Semantic Differential Analyzer", "cat": "Quality & Performance", "desc": "Behavioral Drift & Regression Radar"},
145
+ "noise": {"name": "SignalFilter™", "title": "False-Positive Signal Amplifier", "cat": "Quality & Performance", "desc": "High-Fidelity Signal Processing"},
146
+ "fp_learn": {"name": "SmartLearn™", "title": "Adaptive Heuristics Feedback Loop", "cat": "Quality & Performance", "desc": "Continuous Learning False-Positive Reducer"},
147
+ }
148
+
149
+ SUPPORTED_EXTENSIONS = {
150
+ ".py", ".pyw", ".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx",
151
+ ".go", ".rs", ".java", ".c", ".cpp", ".cc", ".cxx", ".h", ".hpp",
152
+ ".cs", ".php", ".phtml", ".rb", ".swift", ".kt", ".kts", ".scala",
153
+ ".sql", ".html", ".htm", ".css", ".scss", ".json", ".yaml", ".yml",
154
+ ".toml", ".xml", ".ini", ".cfg", ".conf", ".properties", ".env",
155
+ ".tf", ".hcl", ".sh", ".bash", ".zsh", ".ps1", ".psm1", ".md"
156
+ }
157
+
158
+ SPECIAL_FILENAMES = {
159
+ "dockerfile", "docker-compose.yml", "docker-compose.yaml", "makefile",
160
+ "cmakelists.txt", "package.json", "go.mod", "cargo.toml", "pom.xml",
161
+ "requirements.txt", "pyproject.toml", "gemfile", "composer.json"
162
+ }
163
+
164
+
165
+ REPORTS_DIR = Path("ORION SCANNER REPORTS")
166
+ REPORTS_DIR.mkdir(exist_ok=True)
167
+
168
+
169
+ def get_logo_base64() -> str:
170
+ """Read assets/logo.png and return base64 data URI for self-contained report header."""
171
+ candidates = [
172
+ Path("assets/logo.png"),
173
+ Path(__file__).resolve().parent.parent.parent.parent / "assets" / "logo.png",
174
+ Path("D:/Homeworks/Orion_Engine/assets/logo.png")
175
+ ]
176
+ for p in candidates:
177
+ if p.exists():
178
+ try:
179
+ b64 = base64.b64encode(p.read_bytes()).decode("utf-8")
180
+ return f"data:image/png;base64,{b64}"
181
+ except Exception:
182
+ pass
183
+ return ""
184
+
185
+
186
+ def purge_old_reports():
187
+ """Remove previous reports and any nested subdirectories so only latest files exist."""
188
+ import shutil
189
+ try:
190
+ for item in REPORTS_DIR.iterdir():
191
+ try:
192
+ if item.is_dir():
193
+ shutil.rmtree(item, ignore_errors=True)
194
+ else:
195
+ item.unlink()
196
+ except Exception:
197
+ pass
198
+ except Exception:
199
+ pass
200
+
201
+
202
+ def deduplicate_and_filter_findings(findings):
203
+ """Intelligent cross-engine deduplication and false-positive suppression."""
204
+ seen = {}
205
+ normalized = []
206
+
207
+ for f in findings:
208
+ loc = f.location or ""
209
+ sev = f.severity.lower()
210
+ title_lower = f.title.lower()
211
+
212
+ cat = "general"
213
+ if "eval" in title_lower or "code injection" in title_lower:
214
+ cat = "code_injection"
215
+ elif "password" in title_lower or "secret" in title_lower or "token" in title_lower or "key" in title_lower:
216
+ cat = "secrets"
217
+ elif "sandbox" in title_lower or "escape" in title_lower or "subprocess" in title_lower:
218
+ cat = "sandbox_escape"
219
+ elif "jwt" in title_lower:
220
+ cat = "jwt"
221
+ elif "license" in title_lower or "gpl" in title_lower:
222
+ cat = "license"
223
+ elif "undefined name" in title_lower:
224
+ cat = "undefined_symbol"
225
+ elif "dead store" in title_lower:
226
+ cat = "dead_store"
227
+ elif "mutable" in title_lower:
228
+ cat = "mutable"
229
+
230
+ key = f"{loc}:{cat}"
231
+
232
+ if key in seen:
233
+ existing = seen[key]
234
+ contribs = existing.metadata.get("contributing_engines", [existing.engine])
235
+ if f.engine not in contribs:
236
+ contribs.append(f.engine)
237
+ existing.metadata["contributing_engines"] = contribs
238
+ continue
239
+
240
+ if "dead store" in title_lower and loc.startswith("src"):
241
+ continue
242
+ if "module-level mutable variable" in title_lower and any(k in loc for k in ["engine.py", "config.py", "registry.py"]):
243
+ continue
244
+
245
+ f.metadata["contributing_engines"] = [f.engine]
246
+ seen[key] = f
247
+ normalized.append(f)
248
+
249
+ return normalized
250
+
251
+
252
+ async def scan_path(target_path: str, config: EngineConfig, engine_filter: list = None):
253
+ """Scan a file or directory across all supported languages with clean steady terminal feedback."""
254
+ target = Path(target_path)
255
+
256
+ if not target.exists():
257
+ print(f"\n {RED}✖ Error: Target workspace path '{target_path}' does not exist.{RESET}\n")
258
+ return None
259
+
260
+ files = []
261
+ if target.is_file():
262
+ files = [target]
263
+ else:
264
+ exclude_dirs = {
265
+ "__pycache__", ".git", ".venv", "venv", "env", "node_modules",
266
+ "dist", "build", ".pytest_cache", ".mypy_cache", ".tox",
267
+ "vendor", ".github", ".idea", ".vscode", "target", "bin", "obj",
268
+ "orion scanner reports", "reports", "brain", ".system_generated"
269
+ }
270
+ for root, dirs, filenames in os.walk(target):
271
+ dirs[:] = [d for d in dirs if d.lower() not in exclude_dirs and not d.startswith(".")]
272
+ for filename in filenames:
273
+ file_path = Path(root) / filename
274
+ ext = file_path.suffix.lower()
275
+ name_lower = filename.lower()
276
+ if ext in SUPPORTED_EXTENSIONS or name_lower in SPECIAL_FILENAMES or name_lower.startswith(".env"):
277
+ if not is_binary_file(str(file_path)):
278
+ files.append(file_path)
279
+
280
+ total_files = len(files)
281
+ print(f"\n {CYAN}{BOLD}▶ Orion Engine Suite initialized{RESET}")
282
+ print(f" {DIM}Target Workspace:{RESET} {WHITE}{Path(target_path).resolve()}{RESET}")
283
+ print(f" {DIM}Identified Files:{RESET} {WHITE}{total_files} source files across supported languages{RESET}\n")
284
+
285
+ print(f" {CYAN}ℹ [Phase 1/3] Indexing workspace ASTs and generating IR models...{RESET}")
286
+ irs = []
287
+ for f in files:
288
+ try:
289
+ content = f.read_bytes()
290
+ rel_path = f.relative_to(target) if target.is_dir() else f.name
291
+ detected_lang = detect_language(str(f))
292
+ irs.append(OrionIR(
293
+ content=content,
294
+ metadata={
295
+ "path": str(rel_path),
296
+ "language": detected_lang.value if hasattr(detected_lang, "value") else str(detected_lang),
297
+ "project_root": str(target)
298
+ }
299
+ ))
300
+ except Exception:
301
+ pass
302
+
303
+ engine = OrionEngine()
304
+ if engine_filter:
305
+ original_engines = dict(engine._engines)
306
+ engine._engines = {k: v for k, v in engine._engines.items() if k in engine_filter}
307
+
308
+ print(f" {CYAN}ℹ [Phase 2/3] Executing in-house proprietary analysis engines across IR graph...{RESET}")
309
+ raw_result = await engine.run(irs, config or EngineConfig())
310
+
311
+ if engine_filter:
312
+ engine._engines = original_engines
313
+
314
+ print(f" {CYAN}ℹ [Phase 3/3] Deduplicating findings and generating executive intelligence report...{RESET}")
315
+ clean_findings = deduplicate_and_filter_findings(raw_result.findings)
316
+ raw_result.findings = clean_findings
317
+
318
+ print(f" {GREEN}{BOLD}✔ Engine Analysis Complete:{RESET} {len(clean_findings)} validated findings across {total_files} files ({raw_result.metrics.get('elapsed_s', 0):.2f}s)\n")
319
+
320
+ return raw_result
321
+
322
+
323
+ def generate_reports(scan_type: str, target_path: str, result):
324
+ """Generate state-of-the-art Executive HTML report, JSON, and TXT outputs."""
325
+ purge_old_reports()
326
+
327
+ base_name = "orion_executive_security_report"
328
+ html_path = REPORTS_DIR / f"{base_name}.html"
329
+ json_path = REPORTS_DIR / f"{base_name}.json"
330
+ txt_path = REPORTS_DIR / f"{base_name}.txt"
331
+
332
+ logo_data_uri = get_logo_base64()
333
+
334
+ total = len(result.findings)
335
+ critical = sum(1 for f in result.findings if f.severity == "critical")
336
+ high = sum(1 for f in result.findings if f.severity == "high")
337
+ medium = sum(1 for f in result.findings if f.severity == "medium")
338
+ low = sum(1 for f in result.findings if f.severity == "low")
339
+ info = sum(1 for f in result.findings if f.severity == "info")
340
+
341
+ score = 100
342
+ score -= critical * 15
343
+ score -= high * 8
344
+ score -= medium * 3
345
+ score -= low * 1
346
+ score = max(0, score)
347
+
348
+ if score >= 90: grade = "A"
349
+ elif score >= 75: grade = "B"
350
+ elif score >= 60: grade = "C"
351
+ else: grade = "F"
352
+
353
+ grade_colors = {"A": "#10b981", "B": "#84cc16", "C": "#eab308", "F": "#ef4444"}
354
+ grade_color = grade_colors[grade]
355
+
356
+ # JSON Report
357
+ json_report = {
358
+ "engine": "Orion Security Suite",
359
+ "version": "0.1.0",
360
+ "scan_type": scan_type,
361
+ "target_path": str(Path(target_path).resolve()),
362
+ "timestamp": datetime.now().isoformat(),
363
+ "security_score": score,
364
+ "security_grade": grade,
365
+ "summary": {
366
+ "files_scanned": result.metrics.get('files_scanned', 0),
367
+ "engines_executed": result.metrics.get('engines_run', 0),
368
+ "elapsed_seconds": result.metrics.get('elapsed_s', 0),
369
+ "total_findings": total,
370
+ "critical_count": critical,
371
+ "high_count": high,
372
+ "medium_count": medium,
373
+ "low_count": low,
374
+ "info_count": info,
375
+ },
376
+ "findings": [
377
+ {
378
+ "engine_code": f.engine,
379
+ "engine_product": ENGINE_MARKETING_METADATA.get(f.engine, {}).get("name", f.engine),
380
+ "contributing_engines": f.metadata.get("contributing_engines", [f.engine]),
381
+ "severity": f.severity,
382
+ "title": f.title,
383
+ "description": f.description,
384
+ "location": f.location,
385
+ "metadata": f.metadata
386
+ }
387
+ for f in result.findings
388
+ ]
389
+ }
390
+ with open(json_path, 'w', encoding='utf-8') as f:
391
+ json.dump(json_report, f, indent=2, default=str)
392
+
393
+ # TXT Report
394
+ with open(txt_path, 'w', encoding='utf-8') as fh:
395
+ fh.write(f"================================================================================\n")
396
+ fh.write(f" ORION ENGINE SECURITY AUDIT REPORT\n")
397
+ fh.write(f"================================================================================\n")
398
+ fh.write(f"Scan Type: {scan_type}\n")
399
+ fh.write(f"Target Path: {Path(target_path).resolve()}\n")
400
+ fh.write(f"Generated At: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
401
+ fh.write(f"Security Grade: {grade} (Score: {score}/100)\n")
402
+ fh.write(f"Files Scanned: {result.metrics.get('files_scanned', 0)}\n")
403
+ fh.write(f"Engines Run: {result.metrics.get('engines_run', 0)} passes\n")
404
+ fh.write(f"Time Elapsed: {result.metrics.get('elapsed_s', 0):.2f}s\n")
405
+ fh.write(f"Total Findings: {total} (Critical: {critical}, High: {high}, Medium: {medium}, Low: {low})\n")
406
+ fh.write(f"================================================================================\n\n")
407
+
408
+ severity_order = {"critical": 0, "high": 1, "medium": 2, "low": 3, "info": 4}
409
+ sorted_findings = sorted(result.findings, key=lambda f: severity_order.get(f.severity, 5))
410
+
411
+ from collections import defaultdict
412
+ by_severity = defaultdict(list)
413
+ for finding in sorted_findings:
414
+ by_severity[finding.severity].append(finding)
415
+
416
+ for sev in ["critical", "high", "medium", "low", "info"]:
417
+ if sev not in by_severity:
418
+ continue
419
+ fh.write(f"\n[{sev.upper()}] ({len(by_severity[sev])} issues)\n")
420
+ fh.write(f"{'-'*60}\n")
421
+ for finding in by_severity[sev]:
422
+ cwe = finding.metadata.get("cwe", "")
423
+ cwe_str = f" [{cwe}]" if cwe else ""
424
+ conf = finding.metadata.get("confidence", "N/A")
425
+ m_meta = ENGINE_MARKETING_METADATA.get(finding.engine, {})
426
+ eng_label = f"{m_meta.get('name', finding.engine)} ({finding.engine})"
427
+ fh.write(f" * {finding.title}{cwe_str}\n")
428
+ fh.write(f" Engine: {eng_label}\n")
429
+ fh.write(f" Location: {finding.location} (Confidence: {conf})\n")
430
+ if finding.description:
431
+ fh.write(f" Details: {finding.description}\n")
432
+ fh.write("\n")
433
+
434
+ # Executive HTML Report
435
+ with open(html_path, 'w', encoding='utf-8') as f:
436
+ f.write(f"""<!DOCTYPE html>
437
+ <html lang="en">
438
+ <head>
439
+ <meta charset="UTF-8">
440
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
441
+ <title>Orion Executive Security Report - {html.escape(Path(target_path).name or 'Workspace')}</title>
442
+ <link rel="preconnect" href="https://fonts.googleapis.com">
443
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
444
+ <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
445
+ <style>
446
+ :root {{
447
+ --bg-base: #06090e;
448
+ --bg-surface: #0c121e;
449
+ --bg-card: rgba(18, 26, 43, 0.85);
450
+ --border: rgba(255, 255, 255, 0.08);
451
+ --border-hover: rgba(99, 102, 241, 0.4);
452
+ --text-primary: #f8fafc;
453
+ --text-secondary: #94a3b8;
454
+ --text-tertiary: #64748b;
455
+ --critical: #ef4444;
456
+ --high: #f97316;
457
+ --medium: #eab308;
458
+ --low: #10b981;
459
+ --info: #38bdf8;
460
+ --accent: #6366f1;
461
+ --accent-gradient: linear-gradient(135deg, #6366f1, #8b5cf6, #d946ef);
462
+ }}
463
+ * {{ box-sizing: border-box; margin: 0; padding: 0; }}
464
+ body {{
465
+ font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
466
+ background: var(--bg-base);
467
+ color: var(--text-primary);
468
+ line-height: 1.6;
469
+ min-height: 100vh;
470
+ position: relative;
471
+ }}
472
+
473
+ @media print {{
474
+ body {{
475
+ background: #ffffff !important;
476
+ color: #0f172a !important;
477
+ font-size: 9.5pt;
478
+ }}
479
+ .no-print, .action-toolbar, .search-bar, .filter-pills, .footer-bar {{
480
+ display: none !important;
481
+ }}
482
+ .container {{
483
+ max-width: 100% !important;
484
+ padding: 0 !important;
485
+ position: relative;
486
+ z-index: 1;
487
+ }}
488
+ .executive-banner {{
489
+ background: #f8fafc !important;
490
+ border: 2px solid #cbd5e1 !important;
491
+ color: #0f172a !important;
492
+ box-shadow: none !important;
493
+ page-break-after: avoid;
494
+ }}
495
+ .executive-banner h1, .executive-banner p {{ color: #0f172a !important; }}
496
+ .grade-card {{
497
+ background: #ffffff !important;
498
+ border: 1px solid #cbd5e1 !important;
499
+ }}
500
+ .kpi-card {{
501
+ background: #f8fafc !important;
502
+ border: 1px solid #cbd5e1 !important;
503
+ color: #0f172a !important;
504
+ }}
505
+ .kpi-value {{ color: #0f172a !important; }}
506
+ .finding-card {{
507
+ background: #ffffff !important;
508
+ border: 1px solid #cbd5e1 !important;
509
+ color: #0f172a !important;
510
+ page-break-inside: avoid !important;
511
+ break-inside: avoid !important;
512
+ margin-bottom: 12pt !important;
513
+ }}
514
+ .finding-card-title {{ color: #0f172a !important; }}
515
+ .finding-body {{ display: block !important; }}
516
+ .code-snippet {{
517
+ background: #f1f5f9 !important;
518
+ color: #0f172a !important;
519
+ border: 1px solid #cbd5e1 !important;
520
+ }}
521
+ }}
522
+
523
+ .container {{
524
+ max-width: 1380px;
525
+ margin: 0 auto;
526
+ padding: 36px 32px 80px;
527
+ position: relative;
528
+ z-index: 1;
529
+ }}
530
+
531
+ .action-toolbar {{
532
+ display: flex;
533
+ justify-content: space-between;
534
+ align-items: center;
535
+ margin-bottom: 24px;
536
+ padding-bottom: 16px;
537
+ border-bottom: 1px solid var(--border);
538
+ }}
539
+ .brand-heading {{
540
+ display: flex; align-items: center; gap: 14px;
541
+ }}
542
+ .brand-logo-img {{
543
+ height: 48px;
544
+ width: auto;
545
+ object-fit: contain;
546
+ border-radius: 8px;
547
+ }}
548
+ .brand-title {{ font-size: 1.2rem; font-weight: 800; color: #fff; letter-spacing: -0.01em; }}
549
+ .brand-sub {{ font-size: 0.76rem; color: var(--text-secondary); font-weight: 500; }}
550
+
551
+ .print-btn {{
552
+ background: var(--accent-gradient);
553
+ color: #ffffff;
554
+ border: none;
555
+ padding: 10px 22px;
556
+ border-radius: 12px;
557
+ font-family: inherit;
558
+ font-weight: 700;
559
+ font-size: 0.88rem;
560
+ cursor: pointer;
561
+ display: inline-flex; align-items: center; gap: 10px;
562
+ box-shadow: 0 4px 16px rgba(99, 102, 241, 0.35);
563
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
564
+ }}
565
+ .print-btn:hover {{ transform: translateY(-2px); box-shadow: 0 8px 24px rgba(99, 102, 241, 0.55); }}
566
+
567
+ .executive-banner {{
568
+ background: linear-gradient(135deg, rgba(24, 30, 58, 0.9) 0%, rgba(12, 18, 30, 0.95) 100%);
569
+ border: 1px solid var(--border);
570
+ border-radius: 24px;
571
+ padding: 36px 44px;
572
+ display: flex;
573
+ justify-content: space-between;
574
+ align-items: center;
575
+ margin-bottom: 32px;
576
+ box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4);
577
+ position: relative;
578
+ overflow: hidden;
579
+ }}
580
+ .banner-info h1 {{ font-size: 2.1rem; font-weight: 800; letter-spacing: -0.03em; margin-bottom: 8px; }}
581
+ .banner-meta {{
582
+ display: flex; gap: 20px; flex-wrap: wrap;
583
+ font-size: 0.85rem; color: var(--text-secondary);
584
+ font-family: 'JetBrains Mono', monospace;
585
+ }}
586
+
587
+ .grade-card {{
588
+ display: flex; align-items: center; gap: 20px;
589
+ background: rgba(0, 0, 0, 0.45);
590
+ border: 1px solid var(--border);
591
+ border-radius: 20px;
592
+ padding: 16px 32px;
593
+ backdrop-filter: blur(12px);
594
+ }}
595
+ .grade-circle {{
596
+ font-size: 3.6rem; font-weight: 900; line-height: 1;
597
+ color: {grade_color};
598
+ text-shadow: 0 0 30px {grade_color}80;
599
+ }}
600
+ .grade-text-box h4 {{ font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-secondary); }}
601
+ .grade-text-box .score-val {{ font-size: 1.1rem; font-weight: 800; color: #fff; }}
602
+
603
+ .kpi-grid {{
604
+ display: grid;
605
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
606
+ gap: 16px;
607
+ margin-bottom: 36px;
608
+ }}
609
+ .kpi-card {{
610
+ background: var(--bg-card);
611
+ border: 1px solid var(--border);
612
+ border-radius: 18px;
613
+ padding: 22px;
614
+ text-align: center;
615
+ transition: all 0.2s;
616
+ backdrop-filter: blur(16px);
617
+ }}
618
+ .kpi-card:hover {{ transform: translateY(-3px); border-color: var(--border-hover); }}
619
+ .kpi-value {{ font-size: 2.6rem; font-weight: 800; line-height: 1; margin-bottom: 6px; }}
620
+ .kpi-label {{ font-size: 0.76rem; text-transform: uppercase; font-weight: 700; color: var(--text-secondary); letter-spacing: 0.08em; }}
621
+
622
+ .filter-section {{
623
+ background: var(--bg-surface);
624
+ border: 1px solid var(--border);
625
+ border-radius: 18px;
626
+ padding: 18px 24px;
627
+ margin-bottom: 32px;
628
+ display: flex; flex-wrap: wrap; gap: 16px;
629
+ align-items: center; justify-content: space-between;
630
+ }}
631
+ .search-box {{
632
+ background: rgba(0, 0, 0, 0.4);
633
+ border: 1px solid var(--border);
634
+ border-radius: 12px;
635
+ padding: 12px 20px;
636
+ color: #fff;
637
+ font-family: inherit;
638
+ font-size: 0.9rem;
639
+ width: 360px;
640
+ outline: none;
641
+ transition: border-color 0.2s;
642
+ }}
643
+ .search-box:focus {{ border-color: var(--accent); }}
644
+ .filter-pills {{ display: flex; gap: 8px; flex-wrap: wrap; }}
645
+ .pill-btn {{
646
+ background: transparent;
647
+ border: 1px solid var(--border);
648
+ color: var(--text-secondary);
649
+ padding: 8px 18px;
650
+ border-radius: 12px;
651
+ font-size: 0.84rem; font-weight: 700;
652
+ cursor: pointer; transition: all 0.2s;
653
+ }}
654
+ .pill-btn:hover, .pill-btn.active {{
655
+ background: rgba(99, 102, 241, 0.2);
656
+ color: #fff;
657
+ border-color: var(--accent);
658
+ }}
659
+
660
+ .findings-panel {{
661
+ background: var(--bg-surface);
662
+ border: 1px solid var(--border);
663
+ border-radius: 22px;
664
+ padding: 32px;
665
+ margin-bottom: 36px;
666
+ }}
667
+ .findings-panel h2 {{
668
+ font-size: 1.35rem; font-weight: 800; margin-bottom: 24px;
669
+ display: flex; align-items: center; justify-content: space-between;
670
+ }}
671
+
672
+ .finding-card {{
673
+ background: var(--bg-card);
674
+ border: 1px solid var(--border);
675
+ border-radius: 16px;
676
+ margin-bottom: 16px;
677
+ overflow: hidden;
678
+ transition: all 0.2s;
679
+ backdrop-filter: blur(12px);
680
+ }}
681
+ .finding-card:hover {{ border-color: var(--border-hover); }}
682
+ .finding-card.critical {{ border-left: 6px solid var(--critical); }}
683
+ .finding-card.high {{ border-left: 6px solid var(--high); }}
684
+ .finding-card.medium {{ border-left: 6px solid var(--medium); }}
685
+ .finding-card.low {{ border-left: 6px solid var(--low); }}
686
+ .finding-card.info {{ border-left: 6px solid var(--info); }}
687
+
688
+ .finding-header {{
689
+ padding: 20px 26px;
690
+ display: flex; justify-content: space-between; align-items: center;
691
+ gap: 18px; cursor: pointer; user-select: none;
692
+ }}
693
+ .finding-title-line {{ display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 6px; }}
694
+ .finding-card-title {{ font-size: 1.02rem; font-weight: 700; color: #fff; }}
695
+ .badge {{
696
+ padding: 4px 12px; border-radius: 20px;
697
+ font-size: 0.72rem; font-weight: 800; text-transform: uppercase;
698
+ letter-spacing: 0.08em;
699
+ }}
700
+ .badge.critical {{ background: rgba(239,68,68,0.2); color: #f87171; border: 1px solid rgba(239,68,68,0.4); }}
701
+ .badge.high {{ background: rgba(249,115,22,0.2); color: #fb923c; border: 1px solid rgba(249,115,22,0.4); }}
702
+ .badge.medium {{ background: rgba(234,179,8,0.2); color: #facc15; border: 1px solid rgba(234,179,8,0.4); }}
703
+ .badge.low {{ background: rgba(16,185,129,0.2); color: #34d399; border: 1px solid rgba(16,185,129,0.4); }}
704
+ .badge.info {{ background: rgba(56,189,248,0.2); color: #38bdf8; border: 1px solid rgba(56,189,248,0.4); }}
705
+ .badge.engine {{ background: rgba(99,102,241,0.2); color: #a5b4fc; border: 1px solid rgba(99,102,241,0.4); }}
706
+
707
+ .finding-meta-row {{
708
+ display: flex; gap: 20px; font-size: 0.84rem; color: var(--text-secondary);
709
+ font-family: 'JetBrains Mono', monospace;
710
+ }}
711
+ .finding-body {{
712
+ display: none;
713
+ padding: 0 26px 24px;
714
+ border-top: 1px solid rgba(255,255,255,0.06);
715
+ margin-top: 12px;
716
+ padding-top: 18px;
717
+ }}
718
+ .finding-body.open {{ display: block; }}
719
+ .code-snippet {{
720
+ background: #040711;
721
+ border: 1px solid var(--border);
722
+ border-radius: 12px;
723
+ padding: 16px 20px;
724
+ font-family: 'JetBrains Mono', monospace;
725
+ font-size: 0.84rem;
726
+ color: #38bdf8;
727
+ overflow-x: auto;
728
+ margin: 16px 0;
729
+ white-space: pre-wrap;
730
+ }}
731
+ .attributes-grid {{
732
+ display: grid;
733
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
734
+ gap: 12px;
735
+ background: rgba(0,0,0,0.35);
736
+ padding: 16px 20px;
737
+ border-radius: 12px;
738
+ font-size: 0.84rem;
739
+ }}
740
+
741
+ .engines-panel {{
742
+ background: var(--bg-surface);
743
+ border: 1px solid var(--border);
744
+ border-radius: 22px;
745
+ padding: 32px;
746
+ margin-bottom: 36px;
747
+ }}
748
+ .engines-grid {{
749
+ display: grid;
750
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
751
+ gap: 16px;
752
+ margin-top: 20px;
753
+ }}
754
+ .engine-card {{
755
+ background: rgba(0,0,0,0.35);
756
+ border: 1px solid var(--border);
757
+ border-radius: 14px;
758
+ padding: 18px 22px;
759
+ transition: all 0.2s;
760
+ }}
761
+ .engine-card:hover {{ border-color: var(--border-hover); transform: translateY(-2px); }}
762
+ .engine-header {{ display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }}
763
+ .engine-prod-name {{ font-size: 1.02rem; font-weight: 800; color: #fff; }}
764
+ .engine-category {{ font-size: 0.72rem; font-weight: 700; color: var(--accent); background: rgba(99,102,241,0.18); padding: 3px 10px; border-radius: 8px; }}
765
+ .engine-title {{ font-size: 0.84rem; font-weight: 600; color: var(--text-secondary); margin-bottom: 6px; }}
766
+ .engine-desc {{ font-size: 0.76rem; color: var(--text-tertiary); line-height: 1.4; }}
767
+
768
+ .footer-bar {{
769
+ text-align: center;
770
+ font-size: 0.84rem;
771
+ color: var(--text-tertiary);
772
+ padding-top: 32px;
773
+ border-top: 1px solid var(--border);
774
+ }}
775
+ </style>
776
+ </head>
777
+ <body>
778
+ <div class="container">
779
+ <header class="action-toolbar">
780
+ <div class="brand-heading">
781
+ {f'<img src="{logo_data_uri}" class="brand-logo-img" alt="Orion Logo">' if logo_data_uri else '<div style="background:var(--accent-gradient);width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-weight:800;color:#fff;">O</div>'}
782
+ <div>
783
+ <div class="brand-title">Orion Security Suite</div>
784
+ <div class="brand-sub">Proprietary In-House Security & Code Intelligence Suite</div>
785
+ </div>
786
+ </div>
787
+ <button class="print-btn" onclick="window.print()">
788
+ 🖨️ Export PDF / Print Report
789
+ </button>
790
+ </header>
791
+
792
+ <section class="executive-banner">
793
+ <div class="banner-info">
794
+ <h1>Executive Security Audit Report</h1>
795
+ <div class="banner-meta">
796
+ <span>Target: {html.escape(target_path)}</span>
797
+ <span>•</span>
798
+ <span>Audit Type: {html.escape(scan_type)}</span>
799
+ <span>•</span>
800
+ <span>Generated: {datetime.now().strftime('%B %d, %Y - %H:%M:%S')}</span>
801
+ </div>
802
+ </div>
803
+ <div class="grade-card">
804
+ <div class="grade-circle">{grade}</div>
805
+ <div class="grade-text-box">
806
+ <h4>Security Posture</h4>
807
+ <div class="score-val">{score}/100 Index</div>
808
+ </div>
809
+ </div>
810
+ </section>
811
+
812
+ <section class="kpi-grid">
813
+ <div class="kpi-card" style="border-top: 4px solid var(--critical);">
814
+ <div class="kpi-value" style="color: var(--critical);">{critical}</div>
815
+ <div class="kpi-label">Critical Risks</div>
816
+ </div>
817
+ <div class="kpi-card" style="border-top: 4px solid var(--high);">
818
+ <div class="kpi-value" style="color: var(--high);">{high}</div>
819
+ <div class="kpi-label">High Severity</div>
820
+ </div>
821
+ <div class="kpi-card" style="border-top: 4px solid var(--medium);">
822
+ <div class="kpi-value" style="color: var(--medium);">{medium}</div>
823
+ <div class="kpi-label">Medium Priority</div>
824
+ </div>
825
+ <div class="kpi-card" style="border-top: 4px solid var(--low);">
826
+ <div class="kpi-value" style="color: var(--low);">{low}</div>
827
+ <div class="kpi-label">Low / Standards</div>
828
+ </div>
829
+ <div class="kpi-card" style="border-top: 4px solid var(--info);">
830
+ <div class="kpi-value" style="color: var(--info);">{total}</div>
831
+ <div class="kpi-label">Total Findings</div>
832
+ </div>
833
+ <div class="kpi-card">
834
+ <div class="kpi-value" style="color: var(--accent);">{result.metrics.get('files_scanned', 0)}</div>
835
+ <div class="kpi-label">Files Audited</div>
836
+ </div>
837
+ </section>
838
+
839
+ <div class="filter-section no-print">
840
+ <input type="text" class="search-box" id="searchBox" placeholder="Search findings by title, CWE, path, or engine..." onkeyup="applyFilter()">
841
+ <div class="filter-pills">
842
+ <button class="pill-btn active" onclick="setSeverity('all', this)">All Severities</button>
843
+ <button class="pill-btn" onclick="setSeverity('critical', this)">Critical ({critical})</button>
844
+ <button class="pill-btn" onclick="setSeverity('high', this)">High ({high})</button>
845
+ <button class="pill-btn" onclick="setSeverity('medium', this)">Medium ({medium})</button>
846
+ <button class="pill-btn" onclick="setSeverity('low', this)">Low ({low})</button>
847
+ </div>
848
+ </div>
849
+ <div class="filter-section no-print" style="margin-top: -16px; padding: 12px 24px; background: rgba(12, 18, 30, 0.65);">
850
+ <span style="font-size: 0.8rem; font-weight: 700; color: var(--text-secondary); text-transform: uppercase;">Category:</span>
851
+ <div class="filter-pills">
852
+ <button class="pill-btn cat-btn active" onclick="setCategory('all', this)">All Categories</button>
853
+ <button class="pill-btn cat-btn" onclick="setCategory('security', this)">🛡️ Security & Vulnerabilities</button>
854
+ <button class="pill-btn cat-btn" onclick="setCategory('quality', this)">⚡ Code Quality & Standards</button>
855
+ <button class="pill-btn cat-btn" onclick="setCategory('architecture', this)">🏛️ Architecture & Dataflow</button>
856
+ <button class="pill-btn cat-btn" onclick="setCategory('supply', this)">📦 Supply Chain & Privacy</button>
857
+ </div>
858
+ </div>
859
+
860
+ <section class="findings-panel">
861
+ <h2>Findings Catalog ({total})</h2>
862
+ <div id="findingsContainer">
863
+ """)
864
+
865
+ sorted_findings = sorted(result.findings, key=lambda f: severity_order.get(f.severity, 5))
866
+ for finding in sorted_findings:
867
+ sev = finding.severity.lower()
868
+ title = html.escape(finding.title)
869
+ loc = html.escape(finding.location)
870
+ desc = html.escape(finding.description or "")
871
+ engine_code = finding.engine
872
+ m_meta = ENGINE_MARKETING_METADATA.get(engine_code, {})
873
+ engine_prod_name = html.escape(m_meta.get("name", engine_code))
874
+ raw_cat = m_meta.get("cat", "General")
875
+ engine_cat = html.escape(raw_cat)
876
+
877
+ # Slugify category
878
+ cat_slug = "quality"
879
+ if "Security" in raw_cat or "Threat" in raw_cat or "Cloud" in raw_cat:
880
+ cat_slug = "security"
881
+ elif "Architecture" in raw_cat or "Dataflow" in raw_cat:
882
+ cat_slug = "architecture"
883
+ elif "Supply" in raw_cat or "Compliance" in raw_cat or "Privacy" in raw_cat:
884
+ cat_slug = "supply"
885
+
886
+ cwe = html.escape(str(finding.metadata.get("cwe", "")))
887
+ cwe_badge = f'<span class="badge {sev}">{cwe}</span>' if cwe else ""
888
+ snippet = html.escape(str(finding.metadata.get("snippet", "")).strip())
889
+ conf = html.escape(str(finding.metadata.get("confidence", "N/A")))
890
+ contribs = finding.metadata.get("contributing_engines", [engine_code])
891
+ contrib_str = ", ".join(ENGINE_MARKETING_METADATA.get(e, {}).get("name", e) for e in contribs)
892
+
893
+ f.write(f"""
894
+ <div class="finding-card {sev}" data-severity="{sev}" data-category="{cat_slug}" data-search="{title.lower()} {loc.lower()} {engine_prod_name.lower()} {engine_code.lower()} {cwe.lower()} {engine_cat.lower()}">
895
+ <div class="finding-header" onclick="toggleDetails(this)">
896
+ <div style="flex: 1;">
897
+ <div class="finding-title-line">
898
+ <span class="badge {sev}">{sev.upper()}</span>
899
+ <span class="badge engine">{engine_prod_name}</span>
900
+ <span class="badge" style="background: rgba(255,255,255,0.08); color: var(--text-secondary);">{engine_cat}</span>
901
+ {cwe_badge}
902
+ <span class="finding-card-title">{title}</span>
903
+ </div>
904
+ <div class="finding-meta-row">
905
+ <span>Engine: {engine_prod_name} ({engine_code})</span>
906
+ <span>•</span>
907
+ <span>Location: {loc}</span>
908
+ <span>•</span>
909
+ <span>Confidence: {conf}</span>
910
+ </div>
911
+ </div>
912
+ </div>
913
+ <div class="finding-body">
914
+ {f'<p style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 12px;">{desc}</p>' if desc else ''}
915
+ {f'<div class="code-snippet">{snippet}</div>' if snippet else ''}
916
+ <div class="attributes-grid">
917
+ <div><strong>Engine:</strong> {engine_prod_name} ({engine_code})</div>
918
+ <div><strong>Category:</strong> {engine_cat}</div>
919
+ <div><strong>Contributing Scanners:</strong> {contrib_str}</div>
920
+ <div><strong>Location:</strong> {loc}</div>
921
+ <div><strong>Severity:</strong> {sev.upper()}</div>
922
+ <div><strong>Confidence:</strong> {conf}</div>
923
+ </div>
924
+ </div>
925
+ </div>
926
+ """)
927
+
928
+ f.write(f"""
929
+ </div>
930
+ </section>
931
+
932
+ <section class="engines-panel">
933
+ <h2>Proprietary In-House Auditing Engines</h2>
934
+ <p style="font-size: 0.88rem; color: var(--text-secondary);">Every scanner is 100% custom-built, running AST semantic analysis, Inter-Procedural Control Flow Graphs, Taint Propagation, and Cloud/IaC/AI Security Analyzers locally.</p>
935
+ <div class="engines-grid">
936
+ """)
937
+ for eng_key, meta in ENGINE_MARKETING_METADATA.items():
938
+ f.write(f"""
939
+ <div class="engine-card">
940
+ <div class="engine-header">
941
+ <span class="engine-prod-name">{meta['name']}</span>
942
+ <span class="engine-category">{meta['cat']}</span>
943
+ </div>
944
+ <div class="engine-title">{meta['title']}</div>
945
+ <div class="engine-desc">{meta['desc']}</div>
946
+ </div>
947
+ """)
948
+
949
+ f.write(f"""
950
+ </div>
951
+ </section>
952
+
953
+ <footer class="footer-bar no-print">
954
+ Generated by <strong>Orion Security Suite v0.1.0</strong> • Proprietary Code Intelligence & Security Suite
955
+ </footer>
956
+ </div>
957
+
958
+ <script>
959
+ let activeSeverity = 'all';
960
+ let activeCategory = 'all';
961
+
962
+ function toggleDetails(header) {{
963
+ const body = header.nextElementSibling;
964
+ body.classList.toggle('open');
965
+ }}
966
+
967
+ function setSeverity(sev, btn) {{
968
+ activeSeverity = sev;
969
+ document.querySelectorAll('.filter-pills button:not(.cat-btn)').forEach(b => b.classList.remove('active'));
970
+ btn.classList.add('active');
971
+ applyFilter();
972
+ }}
973
+
974
+ function setCategory(cat, btn) {{
975
+ activeCategory = cat;
976
+ document.querySelectorAll('.cat-btn').forEach(b => b.classList.remove('active'));
977
+ btn.classList.add('active');
978
+ applyFilter();
979
+ }}
980
+
981
+ function applyFilter() {{
982
+ const query = document.getElementById('searchBox').value.toLowerCase();
983
+ const cards = document.querySelectorAll('.finding-card');
984
+
985
+ cards.forEach(card => {{
986
+ const cardSev = card.getAttribute('data-severity');
987
+ const cardCat = card.getAttribute('data-category');
988
+ const cardSearch = card.getAttribute('data-search');
989
+ const matchesSev = (activeSeverity === 'all' || cardSev === activeSeverity);
990
+ const matchesCat = (activeCategory === 'all' || cardCat === activeCategory);
991
+ const matchesQuery = !query || cardSearch.includes(query);
992
+
993
+ if (matchesSev && matchesCat && matchesQuery) {{
994
+ card.style.display = 'block';
995
+ }} else {{
996
+ card.style.display = 'none';
997
+ }}
998
+ }});
999
+ }}
1000
+ </script>
1001
+ </body>
1002
+ </html>""")
1003
+
1004
+ print(f"\n {GREEN}{BOLD}✔ Latest Reports Generated in {REPORTS_DIR}/{RESET}")
1005
+ print(f" {CYAN}• Executive HTML (Print & PDF):{RESET} {WHITE}{html_path.name}{RESET}")
1006
+ print(f" {CYAN}• Validated JSON Findings:{RESET} {WHITE}{json_path.name}{RESET}")
1007
+ print(f" {CYAN}• Summary Text Report:{RESET} {WHITE}{txt_path.name}{RESET}\n")
1008
+
1009
+ return json_path, txt_path, html_path
1010
+
1011
+
1012
+ def print_results(result):
1013
+ """Print scan results in a beautifully styled, high-clarity CLI dashboard."""
1014
+ if not result:
1015
+ return 0
1016
+
1017
+ elapsed = result.metrics.get('elapsed_s', 0)
1018
+ files_count = result.metrics.get('files_scanned', 0)
1019
+ engines_count = result.metrics.get('engines_run', 0)
1020
+ total_findings = len(result.findings)
1021
+
1022
+ critical_count = sum(1 for f in result.findings if f.severity == "critical")
1023
+ high_count = sum(1 for f in result.findings if f.severity == "high")
1024
+ medium_count = sum(1 for f in result.findings if f.severity == "medium")
1025
+ low_count = sum(1 for f in result.findings if f.severity == "low")
1026
+ info_count = sum(1 for f in result.findings if f.severity == "info")
1027
+
1028
+ score = 100 - (critical_count * 15) - (high_count * 8) - (medium_count * 3) - (low_count * 1)
1029
+ score = max(0, score)
1030
+ if score >= 90: grade = "A"
1031
+ elif score >= 75: grade = "B"
1032
+ elif score >= 60: grade = "C"
1033
+ else: grade = "F"
1034
+
1035
+ grade_color = GREEN if grade in ("A", "B") else (YELLOW if grade == "C" else RED)
1036
+
1037
+ print(f"""
1038
+ {CYAN}┌───────────────────────────────────────────────────────────────────────────────────┐{RESET}
1039
+ {CYAN}│{RESET} {WHITE}{BOLD}AUDIT SUMMARY • ORION SECURITY SUITE{RESET} {CYAN}│{RESET}
1040
+ {CYAN}├─────────────────────┬─────────────────────┬───────────────────┬───────────────────┤{RESET}
1041
+ {CYAN}│{RESET} {DIM}Audited Workspace{RESET} {CYAN}│{RESET} {DIM}Files Scanned{RESET} {CYAN}│{RESET} {DIM}Engines Executed{RESET} {CYAN}│{RESET} {DIM}Analysis Time{RESET} {CYAN}│{RESET}
1042
+ {CYAN}│{RESET} {WHITE}{BOLD}{Path('.').resolve().name:<19}{RESET} {CYAN}│{RESET} {WHITE}{BOLD}{files_count:<3} files{RESET} {CYAN}│{RESET} {WHITE}{BOLD}{engines_count:<5} passes{RESET} {CYAN}│{RESET} {WHITE}{BOLD}{elapsed:.2f}s{RESET} {CYAN}│{RESET}
1043
+ {CYAN}├─────────────────────┴─────────────────────┴───────────────────┴───────────────────┤{RESET}
1044
+ {CYAN}│{RESET} {WHITE}{BOLD}SECURITY POSTURE:{RESET} {grade_color}{BOLD}GRADE {grade}{RESET} {DIM}({score}/100 Security Index){RESET} {CYAN}│{RESET}
1045
+ {CYAN}│{RESET} {RED}{BOLD}[ CRITICAL: {critical_count:<3} ]{RESET} {YELLOW}{BOLD}[ HIGH: {high_count:<3} ]{RESET} {YELLOW}[ MEDIUM: {medium_count:<3} ]{RESET} {GREEN}[ LOW: {low_count:<4} ]{RESET} {CYAN}│{RESET}
1046
+ {CYAN}└───────────────────────────────────────────────────────────────────────────────────┘{RESET}
1047
+ """)
1048
+
1049
+ if result.findings:
1050
+ severity_order = {"critical": 0, "high": 1, "medium": 2, "low": 3, "info": 4}
1051
+ sorted_findings = sorted(result.findings, key=lambda f: severity_order.get(f.severity, 5))
1052
+
1053
+ security_cats = {"Application Security", "Cloud & Infrastructure", "AI & Emerging Threats"}
1054
+ sec_findings = [f for f in sorted_findings if ENGINE_MARKETING_METADATA.get(f.engine, {}).get("cat") in security_cats]
1055
+ code_findings = [f for f in sorted_findings if ENGINE_MARKETING_METADATA.get(f.engine, {}).get("cat") not in security_cats]
1056
+
1057
+ # 1. Security & Vulnerability Highlights
1058
+ print(f" {WHITE}{BOLD}1. SECURITY & VULNERABILITY HIGHLIGHTS ({len(sec_findings)} issues):{RESET}")
1059
+ if sec_findings:
1060
+ for f in sec_findings[:6]:
1061
+ sev = f.severity.lower()
1062
+ color = RED if sev == "critical" else (YELLOW if sev == "high" else CYAN)
1063
+ cwe = f.metadata.get("cwe", "")
1064
+ cwe_str = f" {CYAN}[{cwe}]{RESET}" if cwe else ""
1065
+ conf = f.metadata.get("confidence", "N/A")
1066
+ m_meta = ENGINE_MARKETING_METADATA.get(f.engine, {})
1067
+ eng_name = m_meta.get("name", f.engine)
1068
+ print(f" {color}• [{sev.upper()}]{RESET} {WHITE}{BOLD}{f.title}{RESET}{cwe_str}")
1069
+ print(f" {DIM}Location:{RESET} {WHITE}{f.location}{RESET} {DIM}| Engine:{RESET} {CYAN}{eng_name}{RESET} {DIM}| Confidence:{RESET} {conf}")
1070
+ if len(sec_findings) > 6:
1071
+ print(f" {DIM}... and {len(sec_findings) - 6} more security findings in executive report{RESET}")
1072
+ else:
1073
+ print(f" {GREEN}✔ Zero critical or high security vulnerabilities detected.{RESET}")
1074
+
1075
+ # 2. Code Quality, Standards & Architecture Highlights
1076
+ print(f"\n {WHITE}{BOLD}2. CODE QUALITY, STANDARDS & ARCHITECTURE HIGHLIGHTS ({len(code_findings)} issues):{RESET}")
1077
+ if code_findings:
1078
+ for f in code_findings[:6]:
1079
+ sev = f.severity.lower()
1080
+ color = YELLOW if sev in ("medium", "high") else GREEN
1081
+ cwe = f.metadata.get("cwe", "")
1082
+ cwe_str = f" {CYAN}[{cwe}]{RESET}" if cwe else ""
1083
+ conf = f.metadata.get("confidence", "N/A")
1084
+ m_meta = ENGINE_MARKETING_METADATA.get(f.engine, {})
1085
+ eng_name = m_meta.get("name", f.engine)
1086
+ print(f" {color}• [{sev.upper()}]{RESET} {WHITE}{BOLD}{f.title}{RESET}{cwe_str}")
1087
+ print(f" {DIM}Location:{RESET} {WHITE}{f.location}{RESET} {DIM}| Engine:{RESET} {CYAN}{eng_name}{RESET} {DIM}| Confidence:{RESET} {conf}")
1088
+ if len(code_findings) > 6:
1089
+ print(f" {DIM}... and {len(code_findings) - 6} more code quality / architecture findings in report{RESET}")
1090
+ else:
1091
+ print(f" {GREEN}✔ Codebase adheres to all clean code and structural standards.{RESET}")
1092
+
1093
+ print(f"\n {CYAN}─────────────────────────────────────────────────────────────────────────────────────{RESET}")
1094
+ return critical_count + high_count
1095
+
1096
+
1097
+ def interactive_menu():
1098
+ """Run interactive menu loop."""
1099
+ config = EngineConfig()
1100
+ report_history = []
1101
+
1102
+ while True:
1103
+ clear_screen()
1104
+ print(BANNER)
1105
+ print(MENU)
1106
+ choice = input(f" {CYAN}{BOLD}Orion >> {RESET}").strip().upper()
1107
+
1108
+ if choice == "0":
1109
+ print(f"\n {CYAN}Session closed. Thank you for using Orion Security Suite!{RESET}\n")
1110
+ break
1111
+
1112
+ elif choice == "1":
1113
+ clear_screen()
1114
+ path = "."
1115
+ result = asyncio.run(scan_path(path, config))
1116
+ if result:
1117
+ report_history.append(("Quick Scan", path, result))
1118
+ print_results(result)
1119
+ generate_reports("Quick Scan", path, result)
1120
+
1121
+ elif choice == "2":
1122
+ clear_screen()
1123
+ path = "."
1124
+ result = asyncio.run(scan_path(path, config))
1125
+ if result:
1126
+ report_history.append(("Full Audit", path, result))
1127
+ print_results(result)
1128
+ generate_reports("Full Audit", path, result)
1129
+
1130
+ elif choice == "3":
1131
+ clear_screen()
1132
+ path = "."
1133
+ security_engines = ["sast", "secrets", "deps", "taint", "authorization", "sandbox_escape", "prompt_security"]
1134
+ result = asyncio.run(scan_path(path, config, security_engines))
1135
+ if result:
1136
+ report_history.append(("Security Scan", path, result))
1137
+ print_results(result)
1138
+ generate_reports("Security Scan", path, result)
1139
+
1140
+ elif choice == "4":
1141
+ clear_screen()
1142
+ path = "."
1143
+ iac_engines = ["iac_security", "container", "config_engine", "config_validation"]
1144
+ result = asyncio.run(scan_path(path, config, iac_engines))
1145
+ if result:
1146
+ report_history.append(("IaC Scan", path, result))
1147
+ print_results(result)
1148
+ generate_reports("IaC Scan", path, result)
1149
+
1150
+ elif choice == "5":
1151
+ clear_screen()
1152
+ path = "."
1153
+ ai_engines = ["llm_security", "prompt_security"]
1154
+ result = asyncio.run(scan_path(path, config, ai_engines))
1155
+ if result:
1156
+ report_history.append(("AI Security Scan", path, result))
1157
+ print_results(result)
1158
+ generate_reports("AI Security Scan", path, result)
1159
+
1160
+ elif choice == "6":
1161
+ clear_screen()
1162
+ path = "."
1163
+ crypto_engines = ["crypto_guard", "secrets"]
1164
+ result = asyncio.run(scan_path(path, config, crypto_engines))
1165
+ if result:
1166
+ report_history.append(("Crypto Scan", path, result))
1167
+ print_results(result)
1168
+ generate_reports("Crypto Scan", path, result)
1169
+
1170
+ elif choice == "7":
1171
+ clear_screen()
1172
+ path = "."
1173
+ quality_engines = ["complexity", "duplication", "error_handling", "logging_c", "lint", "test_coverage", "dead_import"]
1174
+ result = asyncio.run(scan_path(path, config, quality_engines))
1175
+ if result:
1176
+ report_history.append(("Quality Scan", path, result))
1177
+ print_results(result)
1178
+ generate_reports("Quality Scan", path, result)
1179
+
1180
+ elif choice == "8":
1181
+ clear_screen()
1182
+ path = "."
1183
+ sc_engines = ["supply_chain_sbom", "provenance", "compliance", "license", "deps"]
1184
+ result = asyncio.run(scan_path(path, config, sc_engines))
1185
+ if result:
1186
+ report_history.append(("Supply Chain Scan", path, result))
1187
+ print_results(result)
1188
+ generate_reports("Supply Chain Scan", path, result)
1189
+
1190
+ elif choice == "9":
1191
+ clear_screen()
1192
+ path = "."
1193
+ threat_engines = ["threat_model", "sensitive_data"]
1194
+ result = asyncio.run(scan_path(path, config, threat_engines))
1195
+ if result:
1196
+ report_history.append(("Threat & Privacy Scan", path, result))
1197
+ print_results(result)
1198
+ generate_reports("Threat & Privacy Scan", path, result)
1199
+
1200
+ elif choice in ("R", "REPORT"):
1201
+ clear_screen()
1202
+ html_rep = REPORTS_DIR / "orion_executive_security_report.html"
1203
+ print(f"\n {CYAN}{BOLD}Latest Executive Report Location:{RESET}")
1204
+ if html_rep.exists():
1205
+ print(f" {GREEN}✔{RESET} {WHITE}{html_rep.resolve()}{RESET}")
1206
+ print(f"\n {DIM}Tip: Open this file in your browser to inspect interactive graphs or export executive PDF.{RESET}")
1207
+ else:
1208
+ print(f" {DIM}No reports generated yet. Run option [1] or [2] first.{RESET}")
1209
+
1210
+ elif choice in ("S", "STATUS"):
1211
+ clear_screen()
1212
+ engine = OrionEngine()
1213
+ print(f"""
1214
+ {CYAN}┌─────────────────────────────────────────────────────────────────────────────────────────────┐{RESET}
1215
+ {CYAN}│{RESET} {WHITE}{BOLD}IN-HOUSE PROPRIETARY ENGINES ({engine.registered_count} ACTIVE){RESET} {CYAN}│{RESET}
1216
+ {CYAN}│{RESET} {DIM}100% Custom-Engineered Local Intellectual Property (Zero External Dependencies){RESET} {CYAN}│{RESET}
1217
+ {CYAN}├────┬──────────┬──────────────────────┬────────────────────────────┬───────────────────────────┤{RESET}
1218
+ {CYAN}│{RESET} {DIM}# {RESET} {CYAN}│{RESET} {DIM}STATUS {RESET} {CYAN}│{RESET} {DIM}PROPRIETARY ENGINE {RESET} {CYAN}│{RESET} {DIM}CATEGORY {RESET} {CYAN}│{RESET} {DIM}INTERNAL IDENTIFIER {RESET}{CYAN}│{RESET}
1219
+ {CYAN}├────┼──────────┼──────────────────────┼────────────────────────────┼───────────────────────────┤{RESET}""")
1220
+ for idx, name in enumerate(sorted(engine._engines.keys()), 1):
1221
+ try:
1222
+ cls = engine._engines[name]
1223
+ inst = cls()
1224
+ avail = asyncio.run(inst.check_availability())
1225
+ meta = ENGINE_MARKETING_METADATA.get(name, {"name": name, "title": name, "cat": "General"})
1226
+ m_name = meta["name"]
1227
+ m_cat = meta["cat"]
1228
+ status = f"{GREEN}ACTIVE{RESET}" if avail else f"{RED}OFFLINE{RESET}"
1229
+ print(f" {CYAN}│{RESET} {idx:02d} {CYAN}│{RESET} {status} {CYAN}│{RESET} {WHITE}{BOLD}{m_name:<20}{RESET} {CYAN}│{RESET} {DIM}{m_cat:<26}{RESET} {CYAN}│{RESET} {CYAN}{name:<25}{RESET} {CYAN}│{RESET}")
1230
+ except Exception as e:
1231
+ print(f" {CYAN}│{RESET} {idx:02d} {CYAN}│{RESET} {RED}ERROR {RESET} {CYAN}│{RESET} {WHITE}{name:<20}{RESET} {CYAN}│{RESET} {DIM}Error: {str(e)[:20]:<20}{RESET} {CYAN}│{RESET} {name:<25} {CYAN}│{RESET}")
1232
+ print(f" {CYAN}└────┴──────────┴──────────────────────┴────────────────────────────┴───────────────────────────┘{RESET}")
1233
+
1234
+ else:
1235
+ print(f"\n {RED}✖ Invalid selection. Please select an option from the menu.{RESET}")
1236
+
1237
+ input(f"\n {DIM}Press Enter to return to main menu...{RESET}")
1238
+
1239
+
1240
+ def main():
1241
+ if len(sys.argv) > 1:
1242
+ if "--version" in sys.argv or "-v" in sys.argv:
1243
+ print("Orion Engine Suite v0.1.0 (Security & Code Intelligence Platform)")
1244
+ sys.exit(0)
1245
+ if "--help" in sys.argv or "-h" in sys.argv:
1246
+ print("""Orion Engine Suite v0.1.0 - Enterprise Code Audit Platform
1247
+
1248
+ Usage:
1249
+ orion # Launch interactive terminal UI
1250
+ orion <path> # Scan file or directory
1251
+ orion . --security # Security, SAST & vulnerability engines
1252
+ orion . --iac # Infrastructure-as-Code & Cloud engines
1253
+ orion . --ai # LLM & AI Agent security engines
1254
+ orion . --crypto # Cryptographic flaw & key auditor
1255
+ orion . --quality # Code quality & standard engines
1256
+ orion . --arch # Architecture & dataflow engines
1257
+ orion . --threat # Threat modeling & privacy engines
1258
+ orion --version # Show version
1259
+ orion --help # Show help
1260
+ """)
1261
+ sys.exit(0)
1262
+
1263
+ target = sys.argv[1]
1264
+ config = None
1265
+
1266
+ if "--config-json" in sys.argv:
1267
+ idx = sys.argv.index("--config-json")
1268
+ if idx + 1 < len(sys.argv):
1269
+ config_data = json.loads(sys.argv[idx + 1])
1270
+ config = EngineConfig(**config_data)
1271
+
1272
+ engine_filter = None
1273
+ scan_type = "Full Audit"
1274
+ if "--security" in sys.argv:
1275
+ engine_filter = ["sast", "secrets", "deps", "taint", "authorization", "sandbox_escape", "prompt_security"]
1276
+ scan_type = "Security Scan"
1277
+ elif "--iac" in sys.argv:
1278
+ engine_filter = ["iac_security", "container", "config_engine", "config_validation"]
1279
+ scan_type = "IaC Scan"
1280
+ elif "--ai" in sys.argv:
1281
+ engine_filter = ["llm_security", "prompt_security"]
1282
+ scan_type = "AI Security Scan"
1283
+ elif "--crypto" in sys.argv:
1284
+ engine_filter = ["crypto_guard", "secrets"]
1285
+ scan_type = "Crypto Scan"
1286
+ elif "--quality" in sys.argv:
1287
+ engine_filter = ["complexity", "duplication", "error_handling", "logging_c", "lint", "test_coverage", "dead_import"]
1288
+ scan_type = "Quality Scan"
1289
+ elif "--arch" in sys.argv:
1290
+ engine_filter = ["callgraph", "cfg", "symbol", "dataflow", "architecture", "orphan", "wiring_trace"]
1291
+ scan_type = "Architecture Scan"
1292
+ elif "--threat" in sys.argv:
1293
+ engine_filter = ["threat_model", "sensitive_data"]
1294
+ scan_type = "Threat & Privacy Scan"
1295
+
1296
+ result = asyncio.run(scan_path(target, config or EngineConfig(), engine_filter))
1297
+ if result:
1298
+ critical_high = print_results(result)
1299
+ generate_reports(scan_type, target, result)
1300
+ sys.exit(1 if critical_high > 0 else 0)
1301
+ sys.exit(0)
1302
+
1303
+ try:
1304
+ interactive_menu()
1305
+ except KeyboardInterrupt:
1306
+ print("\n\n Session terminated by user. Goodbye!\n")
1307
+
1308
+
1309
+ if __name__ == "__main__":
1310
+ main()