codesecure-core 1.0.0b10__tar.gz

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 (71) hide show
  1. codesecure_core-1.0.0b10/LICENSE +21 -0
  2. codesecure_core-1.0.0b10/PKG-INFO +101 -0
  3. codesecure_core-1.0.0b10/README.md +69 -0
  4. codesecure_core-1.0.0b10/pyproject.toml +40 -0
  5. codesecure_core-1.0.0b10/setup.cfg +4 -0
  6. codesecure_core-1.0.0b10/setup.py +5 -0
  7. codesecure_core-1.0.0b10/src/codesecure/__init__.py +19 -0
  8. codesecure_core-1.0.0b10/src/codesecure/ai_providers/__init__.py +0 -0
  9. codesecure_core-1.0.0b10/src/codesecure/ai_providers/anthropic_provider.py +144 -0
  10. codesecure_core-1.0.0b10/src/codesecure/ai_providers/azure_cli.py +428 -0
  11. codesecure_core-1.0.0b10/src/codesecure/ai_providers/base.py +89 -0
  12. codesecure_core-1.0.0b10/src/codesecure/ai_providers/google_cli.py +195 -0
  13. codesecure_core-1.0.0b10/src/codesecure/ai_providers/guides.py +51 -0
  14. codesecure_core-1.0.0b10/src/codesecure/ai_providers/kiro_cli.py +421 -0
  15. codesecure_core-1.0.0b10/src/codesecure/ai_providers/manager.py +525 -0
  16. codesecure_core-1.0.0b10/src/codesecure/ai_providers/openai_provider.py +143 -0
  17. codesecure_core-1.0.0b10/src/codesecure/ai_providers/prompts.py +276 -0
  18. codesecure_core-1.0.0b10/src/codesecure/common/__init__.py +64 -0
  19. codesecure_core-1.0.0b10/src/codesecure/common/cloud_provider.py +208 -0
  20. codesecure_core-1.0.0b10/src/codesecure/common/config.py +78 -0
  21. codesecure_core-1.0.0b10/src/codesecure/common/config_manager.py +80 -0
  22. codesecure_core-1.0.0b10/src/codesecure/common/logging.py +205 -0
  23. codesecure_core-1.0.0b10/src/codesecure/common/models.py +247 -0
  24. codesecure_core-1.0.0b10/src/codesecure/common/performance.py +111 -0
  25. codesecure_core-1.0.0b10/src/codesecure/jobs/__init__.py +18 -0
  26. codesecure_core-1.0.0b10/src/codesecure/jobs/manager.py +421 -0
  27. codesecure_core-1.0.0b10/src/codesecure/reports/__init__.py +32 -0
  28. codesecure_core-1.0.0b10/src/codesecure/reports/generator.py +202 -0
  29. codesecure_core-1.0.0b10/src/codesecure/reports/html.py +766 -0
  30. codesecure_core-1.0.0b10/src/codesecure/reports/json.py +148 -0
  31. codesecure_core-1.0.0b10/src/codesecure/reports/markdown.py +293 -0
  32. codesecure_core-1.0.0b10/src/codesecure/reports/sarif.py +229 -0
  33. codesecure_core-1.0.0b10/src/codesecure/scanners/__init__.py +61 -0
  34. codesecure_core-1.0.0b10/src/codesecure/scanners/bandit.py +165 -0
  35. codesecure_core-1.0.0b10/src/codesecure/scanners/base.py +344 -0
  36. codesecure_core-1.0.0b10/src/codesecure/scanners/checkov.py +198 -0
  37. codesecure_core-1.0.0b10/src/codesecure/scanners/data_merger.py +270 -0
  38. codesecure_core-1.0.0b10/src/codesecure/scanners/deduplication_engine.py +282 -0
  39. codesecure_core-1.0.0b10/src/codesecure/scanners/detect_secrets.py +109 -0
  40. codesecure_core-1.0.0b10/src/codesecure/scanners/engine.py +351 -0
  41. codesecure_core-1.0.0b10/src/codesecure/scanners/framework_mapper.py +158 -0
  42. codesecure_core-1.0.0b10/src/codesecure/scanners/grype.py +124 -0
  43. codesecure_core-1.0.0b10/src/codesecure/scanners/npm_audit.py +134 -0
  44. codesecure_core-1.0.0b10/src/codesecure/scanners/pip_audit.py +149 -0
  45. codesecure_core-1.0.0b10/src/codesecure/scanners/pip_licenses.py +130 -0
  46. codesecure_core-1.0.0b10/src/codesecure/scanners/semgrep.py +123 -0
  47. codesecure_core-1.0.0b10/src/codesecure/scanners/syft.py +111 -0
  48. codesecure_core-1.0.0b10/src/codesecure/security/__init__.py +45 -0
  49. codesecure_core-1.0.0b10/src/codesecure/security/output_sanitizer.py +202 -0
  50. codesecure_core-1.0.0b10/src/codesecure/security/security_validator.py +300 -0
  51. codesecure_core-1.0.0b10/src/codesecure/security/subprocess_runner.py +366 -0
  52. codesecure_core-1.0.0b10/src/codesecure/security/validators.py +300 -0
  53. codesecure_core-1.0.0b10/src/codesecure/security_matrix/__init__.py +0 -0
  54. codesecure_core-1.0.0b10/src/codesecure/security_matrix/file_filter.py +0 -0
  55. codesecure_core-1.0.0b10/src/codesecure/security_matrix/neolifter.py +0 -0
  56. codesecure_core-1.0.0b10/src/codesecure/security_validate/__init__.py +0 -0
  57. codesecure_core-1.0.0b10/src/codesecure/security_validate/cdk.py +0 -0
  58. codesecure_core-1.0.0b10/src/codesecure/security_validate/cloudformation.py +0 -0
  59. codesecure_core-1.0.0b10/src/codesecure/security_validate/severity.py +0 -0
  60. codesecure_core-1.0.0b10/src/codesecure/security_validate/terraform.py +0 -0
  61. codesecure_core-1.0.0b10/src/codesecure/telemetry/__init__.py +3 -0
  62. codesecure_core-1.0.0b10/src/codesecure/telemetry/client.py +90 -0
  63. codesecure_core-1.0.0b10/src/codesecure/threat_model/__init__.py +0 -0
  64. codesecure_core-1.0.0b10/src/codesecure/threat_model/action_plan.py +0 -0
  65. codesecure_core-1.0.0b10/src/codesecure/threat_model/stride_engine.py +0 -0
  66. codesecure_core-1.0.0b10/src/codesecure_core.egg-info/PKG-INFO +101 -0
  67. codesecure_core-1.0.0b10/src/codesecure_core.egg-info/SOURCES.txt +69 -0
  68. codesecure_core-1.0.0b10/src/codesecure_core.egg-info/dependency_links.txt +1 -0
  69. codesecure_core-1.0.0b10/src/codesecure_core.egg-info/requires.txt +28 -0
  70. codesecure_core-1.0.0b10/src/codesecure_core.egg-info/top_level.txt +1 -0
  71. codesecure_core-1.0.0b10/tests/test_openai_provider.py +82 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 noviqtechnologies
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: codesecure-core
3
+ Version: 1.0.0b10
4
+ Summary: Enterprise-grade security analysis core engine
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: pydantic>=2.0.0
10
+ Requires-Dist: jinja2>=3.1.0
11
+ Requires-Dist: asyncio>=3.4.3
12
+ Requires-Dist: rich>=13.0.0
13
+ Requires-Dist: mermaid-py>=0.1.0
14
+ Requires-Dist: markdown>=3.5.2
15
+ Requires-Dist: pygments>=2.17.2
16
+ Requires-Dist: packaging>=24.0
17
+ Requires-Dist: bandit>=1.7.0
18
+ Requires-Dist: semgrep>=1.0.0; sys_platform != "win32"
19
+ Requires-Dist: checkov>=3.0.0
20
+ Requires-Dist: detect-secrets>=1.4.0
21
+ Requires-Dist: pip-audit>=2.0.0
22
+ Requires-Dist: pip-licenses>=4.0.0
23
+ Requires-Dist: pyyaml>=6.0
24
+ Provides-Extra: google
25
+ Requires-Dist: google-generativeai>=0.3.0; extra == "google"
26
+ Provides-Extra: openai
27
+ Requires-Dist: openai>=1.0.0; extra == "openai"
28
+ Provides-Extra: aws
29
+ Provides-Extra: all
30
+ Requires-Dist: codesecure-core[aws,google,openai]; extra == "all"
31
+ Dynamic: license-file
32
+
33
+ # CodeSecure Core (`codesecure-core`)
34
+
35
+ The `codesecure-core` package is the programmatic orchestration brain of the CodeSecure platform. It provides the centralized, stateless logic for executing security scanners, managing asynchronous jobs, and enriching findings with AI models.
36
+
37
+ ## 🎯 Module Purpose
38
+
39
+ This package encapsulates the strict business logic of the platform, adhering to a "Thin Client" architecture. It does not export command-line (CLI) applications or MCP Transport interfaces directly. Instead, it provides a stable Python API (Singletons) designed to be consumed by other packages in the CodeSecure monorepo, such as `codesecure-cli` and `codesecure-mcp`.
40
+
41
+ ## 📦 Local Installation
42
+
43
+ Because `core` has no dependency on the UI/CLI layer, it can be installed natively for programmatic API usage.
44
+
45
+ ```bash
46
+ cd packages/core
47
+ python -m venv .venv
48
+
49
+ # Install the core logic with basic SAST scanners
50
+ pip install -e .
51
+
52
+ # [Optional] Install AI providers (Google Gemini or Kiro CLI dependencies)
53
+ pip install -e .[google,aws]
54
+ ```
55
+
56
+ ## 🔌 Exported APIs & Features
57
+
58
+ The Core package exposes Manager classes via the Singleton pattern:
59
+
60
+ 1. **`ScannerEngine`**: Orchestrates local/container execution for Bandit, Semgrep, Checkov, detect-secrets, npm-audit, pip-audit, etc.
61
+ ```python
62
+ from codesecure.scanners.engine import get_scanner_engine
63
+ ```
64
+ 2. **`JobManager`**: Async execution tracking, lock management, TTL limits, and progress percentages.
65
+ ```python
66
+ from codesecure.jobs.manager import get_job_manager
67
+ ```
68
+ 3. **`AIProviderManager`**: Abstracts batch prompting against Gemini and Kiro. Calculates False Positive tracking dynamically.
69
+ ```python
70
+ from codesecure.ai_providers.manager import get_ai_manager
71
+ ```
72
+
73
+ ## 🛠️ Integration Example
74
+
75
+ Here is how a downstream module (like the MCP server) imports and utilizes the core library programmatically:
76
+
77
+ ```python
78
+ import asyncio
79
+ from pathlib import Path
80
+ from codesecure.common.models import ScanMode, CloudProvider
81
+ from codesecure.scanners.engine import get_scanner_engine
82
+
83
+ async def programmatically_scan(target_dir: str):
84
+ scan_path = Path(target_dir).resolve()
85
+ engine = get_scanner_engine()
86
+
87
+ # Check available scanners
88
+ available = engine.get_available_scanners(ScanMode.LOCAL)
89
+ print(f"Scanners ready: {available}")
90
+
91
+ # Run a unified scan seamlessly combining multiple tools
92
+ result = await engine.run_scan(
93
+ path=scan_path,
94
+ mode=ScanMode.LOCAL,
95
+ cloud_provider=CloudProvider.NONE
96
+ )
97
+
98
+ print(f"Total findings discovered: {len(result.findings)}")
99
+
100
+ asyncio.run(programmatically_scan("./my_project"))
101
+ ```
@@ -0,0 +1,69 @@
1
+ # CodeSecure Core (`codesecure-core`)
2
+
3
+ The `codesecure-core` package is the programmatic orchestration brain of the CodeSecure platform. It provides the centralized, stateless logic for executing security scanners, managing asynchronous jobs, and enriching findings with AI models.
4
+
5
+ ## 🎯 Module Purpose
6
+
7
+ This package encapsulates the strict business logic of the platform, adhering to a "Thin Client" architecture. It does not export command-line (CLI) applications or MCP Transport interfaces directly. Instead, it provides a stable Python API (Singletons) designed to be consumed by other packages in the CodeSecure monorepo, such as `codesecure-cli` and `codesecure-mcp`.
8
+
9
+ ## 📦 Local Installation
10
+
11
+ Because `core` has no dependency on the UI/CLI layer, it can be installed natively for programmatic API usage.
12
+
13
+ ```bash
14
+ cd packages/core
15
+ python -m venv .venv
16
+
17
+ # Install the core logic with basic SAST scanners
18
+ pip install -e .
19
+
20
+ # [Optional] Install AI providers (Google Gemini or Kiro CLI dependencies)
21
+ pip install -e .[google,aws]
22
+ ```
23
+
24
+ ## 🔌 Exported APIs & Features
25
+
26
+ The Core package exposes Manager classes via the Singleton pattern:
27
+
28
+ 1. **`ScannerEngine`**: Orchestrates local/container execution for Bandit, Semgrep, Checkov, detect-secrets, npm-audit, pip-audit, etc.
29
+ ```python
30
+ from codesecure.scanners.engine import get_scanner_engine
31
+ ```
32
+ 2. **`JobManager`**: Async execution tracking, lock management, TTL limits, and progress percentages.
33
+ ```python
34
+ from codesecure.jobs.manager import get_job_manager
35
+ ```
36
+ 3. **`AIProviderManager`**: Abstracts batch prompting against Gemini and Kiro. Calculates False Positive tracking dynamically.
37
+ ```python
38
+ from codesecure.ai_providers.manager import get_ai_manager
39
+ ```
40
+
41
+ ## 🛠️ Integration Example
42
+
43
+ Here is how a downstream module (like the MCP server) imports and utilizes the core library programmatically:
44
+
45
+ ```python
46
+ import asyncio
47
+ from pathlib import Path
48
+ from codesecure.common.models import ScanMode, CloudProvider
49
+ from codesecure.scanners.engine import get_scanner_engine
50
+
51
+ async def programmatically_scan(target_dir: str):
52
+ scan_path = Path(target_dir).resolve()
53
+ engine = get_scanner_engine()
54
+
55
+ # Check available scanners
56
+ available = engine.get_available_scanners(ScanMode.LOCAL)
57
+ print(f"Scanners ready: {available}")
58
+
59
+ # Run a unified scan seamlessly combining multiple tools
60
+ result = await engine.run_scan(
61
+ path=scan_path,
62
+ mode=ScanMode.LOCAL,
63
+ cloud_provider=CloudProvider.NONE
64
+ )
65
+
66
+ print(f"Total findings discovered: {len(result.findings)}")
67
+
68
+ asyncio.run(programmatically_scan("./my_project"))
69
+ ```
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "codesecure-core"
7
+ version = "1.0.0b10"
8
+ description = "Enterprise-grade security analysis core engine"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ dependencies = [
13
+ "pydantic>=2.0.0",
14
+ "jinja2>=3.1.0",
15
+ "asyncio>=3.4.3",
16
+ "rich>=13.0.0",
17
+ "mermaid-py>=0.1.0",
18
+ "markdown>=3.5.2",
19
+ "pygments>=2.17.2",
20
+ "packaging>=24.0",
21
+ # Scanners
22
+ "bandit>=1.7.0",
23
+ "semgrep>=1.0.0; sys_platform != 'win32'",
24
+ "checkov>=3.0.0",
25
+ "detect-secrets>=1.4.0",
26
+ "pip-audit>=2.0.0",
27
+ "pip-licenses>=4.0.0",
28
+ "pyyaml>=6.0",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ google = ["google-generativeai>=0.3.0"]
33
+ openai = ["openai>=1.0.0"]
34
+ # aws = ["kiro-cli>=1.0.0"] # Dependency not found on PyPI, needs custom registry or verification
35
+ aws = []
36
+ all = ["codesecure-core[google,openai,aws]"]
37
+
38
+ [tool.setuptools.packages.find]
39
+ where = ["src"]
40
+ include = ["codesecure*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ from setuptools import setup
2
+
3
+ # Delegate to pyproject.toml
4
+ if __name__ == "__main__":
5
+ setup()
@@ -0,0 +1,19 @@
1
+ """
2
+ CodeSecure - Enterprise Security Analysis Platform.
3
+ """
4
+
5
+ try:
6
+ from importlib.metadata import version, PackageNotFoundError
7
+ except ImportError:
8
+ # Fallback for Python < 3.8
9
+ try:
10
+ from importlib_metadata import version, PackageNotFoundError
11
+ except ImportError:
12
+ version = lambda _: "unknown"
13
+ PackageNotFoundError = Exception
14
+
15
+ try:
16
+ __version__ = version("codesecure-core")
17
+ except (PackageNotFoundError, NameError):
18
+ # Fallback for development where the package is not installed
19
+ __version__ = "1.0.0b9"
@@ -0,0 +1,144 @@
1
+ import asyncio
2
+ from typing import List, Dict, Any, Optional
3
+
4
+ from codesecure.common.models import Finding, EnhancedFinding
5
+ from codesecure.common.logging import get_logger
6
+ from codesecure.ai_providers.base import (
7
+ BaseAIProvider,
8
+ AIProviderType,
9
+ AIProviderStatus,
10
+ )
11
+ from codesecure.ai_providers.prompts import GenericPromptBuilder, GenericMarkdownParser
12
+ from codesecure.common.config import get_env
13
+
14
+ logger = get_logger(__name__)
15
+
16
+
17
+ class AnthropicWrapper(BaseAIProvider):
18
+ """Anthropic Provider Implementation"""
19
+
20
+ PROVIDER_TYPE = AIProviderType.AWS # Currently aliased/planned for AWS Bedrock or direct Anthropic
21
+
22
+ def __init__(self):
23
+ self.prompt_builder = GenericPromptBuilder()
24
+ self.parser = GenericMarkdownParser()
25
+ self._api_key = get_env("CODESECURE_ANTHROPIC_API_KEY", "")
26
+ self._model = get_env("CODESECURE_ANTHROPIC_MODEL", "claude-3-5-sonnet-20241022")
27
+
28
+ def _get_client(self):
29
+ try:
30
+ import anthropic
31
+ return anthropic.AsyncAnthropic(api_key=self._api_key)
32
+ except ImportError:
33
+ raise RuntimeError("anthropic SDK not installed")
34
+
35
+ def set_api_key(self, api_key: str):
36
+ self._api_key = api_key
37
+
38
+ def set_model(self, model: str):
39
+ self._model = model
40
+
41
+ @property
42
+ def is_available(self) -> bool:
43
+ try:
44
+ import anthropic
45
+ return bool(self._api_key)
46
+ except ImportError:
47
+ return False
48
+
49
+ async def check_availability(self) -> tuple[AIProviderStatus, str]:
50
+ try:
51
+ import anthropic
52
+ except ImportError:
53
+ return AIProviderStatus.UNAVAILABLE, "Anthropic SDK not found (install with 'pip install anthropic')"
54
+
55
+ if not self._api_key:
56
+ return AIProviderStatus.UNAVAILABLE, "CODESECURE_ANTHROPIC_API_KEY is not set"
57
+
58
+ return AIProviderStatus.AVAILABLE, "Ready"
59
+
60
+ def _classify_error(self, err_msg: str, status_code: Optional[int] = None) -> str:
61
+ err_lower = err_msg.lower()
62
+ if status_code in (401, 403) or any(w in err_lower for w in ["invalid x-api-key", "authentication"]):
63
+ return "auth"
64
+ if status_code == 429 or any(w in err_lower for w in ["rate_limit", "too many requests"]):
65
+ return "rate_limit"
66
+ return "other"
67
+
68
+ async def test_connection(self) -> tuple[AIProviderStatus, str]:
69
+ status, msg = await self.check_availability()
70
+ if status != AIProviderStatus.AVAILABLE:
71
+ return status, msg
72
+
73
+ try:
74
+ client = self._get_client()
75
+ logger.info("Validating Anthropic API key with model %s...", self._model)
76
+ await client.messages.create(
77
+ model=self._model,
78
+ messages=[{"role": "user", "content": "Reply with 'ok'"}],
79
+ max_tokens=5,
80
+ )
81
+ return AIProviderStatus.AVAILABLE, "Ready"
82
+ except Exception as e:
83
+ err_type = self._classify_error(str(e), getattr(e, "status_code", None))
84
+ if err_type == "auth":
85
+ return AIProviderStatus.ERROR, f"Anthropic Auth Error: {e}"
86
+ if err_type == "rate_limit":
87
+ return AIProviderStatus.ERROR, f"Anthropic Rate Limit Error: {e}"
88
+ return AIProviderStatus.ERROR, f"Anthropic Connection Failed: {str(e)}"
89
+
90
+ async def analyze_findings_batch(
91
+ self,
92
+ findings: List[Finding],
93
+ code_contexts: Dict[str, str],
94
+ batch_size: int = 10,
95
+ app_context: Optional[Dict[str, Any]] = None,
96
+ is_workspace_scan: bool = False
97
+ ) -> List[EnhancedFinding]:
98
+
99
+ if not findings:
100
+ return []
101
+
102
+ client = self._get_client()
103
+ prompt = self.prompt_builder.build_batch_prompt(findings, app_context=app_context, is_workspace_scan=is_workspace_scan)
104
+
105
+ system_prompt = (
106
+ "You are CodeSecure, an expert AI security assistant. "
107
+ "Analyze security findings and provide remediation in Markdown format. "
108
+ "Follow the ZERO-CHATTER RULE: remediation code blocks must contain "
109
+ "ONLY pure source code, no explanations."
110
+ )
111
+
112
+ try:
113
+ logger.info("Sending batch of %d findings to Anthropic (%s)...", len(findings), self._model)
114
+
115
+ response = await client.messages.create(
116
+ model=self._model,
117
+ system=system_prompt,
118
+ messages=[
119
+ {"role": "user", "content": prompt}
120
+ ],
121
+ temperature=0.2,
122
+ max_tokens=4096,
123
+ )
124
+
125
+ text = response.content[0].text if response.content else ""
126
+ logger.debug("Received AI response length: %d characters", len(text))
127
+
128
+ return self.parser.parse(text, findings)
129
+
130
+ except Exception as e:
131
+ err_type = self._classify_error(str(e), getattr(e, "status_code", None))
132
+ if err_type == "rate_limit":
133
+ raise RuntimeError(f"Anthropic Rate Limit Exceeded: {e}")
134
+ logger.exception("Anthropic Analysis failed: %s", e)
135
+ raise e
136
+
137
+ def enhance_finding(self, finding: Finding, analysis: Any) -> EnhancedFinding:
138
+ pass
139
+
140
+ async def generate_stride_analysis(self, repo_path: Any, category: str) -> Dict[str, Any]:
141
+ return {"error": "Not implemented"}
142
+
143
+ def get_anthropic_wrapper() -> AnthropicWrapper:
144
+ return AnthropicWrapper()