-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
165 lines (151 loc) · 5.43 KB
/
pyproject.toml
File metadata and controls
165 lines (151 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
[build-system]
requires = ["setuptools>=68", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "deep-code-security"
version = "1.0.0"
description = "Multi-language SAST tool with agentic verification via tree-sitter, sandbox exploit testing, and MCP interface"
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }
authors = [{ name = "deep-code-security contributors" }]
keywords = ["sast", "security", "static-analysis", "tree-sitter", "mcp"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Security",
]
dependencies = [
"tree-sitter>=0.23.0,<0.24.0",
"tree-sitter-python>=0.23.0,<0.24.0",
"tree-sitter-go>=0.23.0,<0.24.0",
"tree-sitter-c>=0.23.0,<0.23.5",
"pydantic>=2.0.0,<3.0.0",
"mcp>=1.26.0",
"pyyaml>=6.0",
"pathspec>=0.12.0",
"click>=8.0",
]
[project.optional-dependencies]
semgrep = ["semgrep>=1.50.0,<2.0.0"]
fuzz = [
"anthropic>=0.25.0,<1.0.0",
"coverage>=7.0.0",
"rich>=13.0.0",
]
tui = ["textual>=0.70.0"]
vertex = [
"deep-code-security[fuzz]",
"anthropic[vertex]>=0.25.0,<1.0.0",
"google-auth>=2.0.0",
]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
"pytest-cov>=5.0",
"pytest-mock>=3.12.0",
"ruff>=0.4.0",
"bandit[toml]>=1.7.0",
"pip-audit>=2.7.0",
]
test = [
"jsonschema>=4.0",
]
[project.scripts]
dcs = "deep_code_security.cli:cli"
[project.entry-points."deep_code_security.fuzzer_plugins"]
python = "deep_code_security.fuzzer.plugins.python_target:PythonTargetPlugin"
c = "deep_code_security.fuzzer.plugins.c_target:CTargetPlugin"
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
deep_code_security = [
"hunter/queries/*.scm",
"auditor/seccomp-profile.json",
"fuzzer/execution/_worker.py",
"fuzzer/execution/_c_worker.py",
]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
addopts = "-v"
markers = [
"integration: marks tests as integration tests (require Podman + built images)",
]
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP", "S", "B", "A", "C4", "T20"]
ignore = ["S101", "S603", "S607", "UP042", "S307", "S311"] # Allow assert, subprocess list, str+Enum, justified eval, non-crypto random
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["S", "T20", "E501"]
"*/fuzzer/execution/_worker.py" = ["S307", "T20", "N806", "E501"] # Justified eval(), print(), constant in func
"*/fuzzer/orchestrator.py" = ["T20"] # print() in dry-run mode
"*/fuzzer/ai/prompts.py" = ["E501"] # Long prompt template strings
"*/fuzzer/config.py" = ["S110"] # try-except-pass for config file loading
"*/fuzzer/consent.py" = ["S110"] # try-except-pass for consent file reading
"*/fuzzer/execution/sandbox.py" = ["S110"] # try-except-pass for rlimit failures
[tool.bandit]
exclude_dirs = ["tests"]
skips = ["B101", "B603", "B607", "B307"] # Allow assert, subprocess list, partial paths, justified eval in _worker.py
[tool.coverage.run]
source = ["src/deep_code_security"]
omit = [
"tests/*",
"*/mcp/shared/*",
# CLI and MCP entry-point are thin wrappers tested via integration
"*/cli.py",
"*/mcp/__main__.py",
# v1.1 stubs — no production logic
"*/hunter/call_graph.py",
"*/architect/impact_analyzer.py",
# Fuzzer execution worker runs in isolated subprocess (tested via test_worker_validation)
"*/fuzzer/execution/_worker.py",
# TUI Textual-dependent modules (require optional textual package)
"*/tui/app.py",
"*/tui/screens/*.py",
# Bridge __init__.py is a pure re-export
"*/bridge/__init__.py",
# Fuzzer __init__.py files are re-exports only
"*/fuzzer/__init__.py",
"*/fuzzer/ai/__init__.py",
"*/fuzzer/execution/__init__.py",
"*/fuzzer/corpus/__init__.py",
"*/fuzzer/coverage_tracking/__init__.py",
"*/fuzzer/plugins/__init__.py",
"*/fuzzer/reporting/__init__.py",
"*/fuzzer/replay/__init__.py",
# AI engine requires live API client (mocked in test_engine)
"*/fuzzer/ai/engine.py",
# Orchestrator requires full AI + plugin stack (integration test)
"*/fuzzer/orchestrator.py",
# Runner/sandbox need live subprocess with rlimits (integration test)
"*/fuzzer/execution/runner.py",
"*/fuzzer/execution/sandbox.py",
# Python target plugin needs live subprocess (integration test)
"*/fuzzer/plugins/python_target.py",
# Replay runner needs full plugin stack (integration test)
"*/fuzzer/replay/runner.py",
# Consent module does real filesystem I/O (tested in test_consent)
"*/fuzzer/consent.py",
# Corpus manager does real filesystem I/O (tested in test_manager)
"*/fuzzer/corpus/manager.py",
# Source analysis modules have many AST edge cases (partially tested)
"*/fuzzer/analyzer/source_reader.py",
"*/fuzzer/analyzer/signature_extractor.py",
# AI subsystem modules with complex logic tested via mocks
"*/fuzzer/ai/response_parser.py",
"*/fuzzer/ai/context_manager.py",
# Config has filesystem + env var interactions (tested in test_config)
"*/fuzzer/config.py",
# Corpus serialization has manual JSON logic (tested in test_serialization)
"*/fuzzer/corpus/serialization.py",
]
[tool.coverage.report]
fail_under = 90
show_missing = true