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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
//! Language support contract shared by every registered language.
//!
//! drep analyzes a file in two layers, and this module is what keeps them free of
//! per-language conditionals:
//!
//! - **Deterministic**: the project's own tools (ruff, eslint, gofmt, clippy).
//! They are precise, so their findings can gate a commit.
//! - **Semantic**: the LLM, told which language it is looking at. It reads any
//! language without a parser, so it needs no per-language machinery beyond a
//! prompt - which is why adding a language here is a data change, not a
//! refactor.
//!
//! Deliberately free of heavyweight drep imports: the registry is consulted by
//! file discovery (`drep.core.file_targets`), which analyzer packages import.
pub const DEFAULT_TOOL_TIMEOUT_SECS: u64 = 120;
/// How to parse the tool's diagnostics into findings.
///
/// A fieldless enum rather than a string: `parse_output` dispatches on it, so
/// a misspelling is a compile error at the definition site instead of a
/// runtime "no parser for output format" surfacing only when the tool runs.
/// No `#[non_exhaustive]` - this crate is the only consumer, and the
/// wildcard arm it forces is exactly the silent-fallback hole the enum
/// exists to close.
/// Which process stream carries a tool's diagnostics.
///
/// `go vet` writes to stderr, so reading only stdout would report every Go
/// file clean. An enum because the runner compares it exactly once: a typo'd
/// string silently selected stdout, which is that same failure.
/// A deterministic checker for one language.
///
/// Attributes:
/// name: Tool name, used in logs and finding provenance.
/// command: argv to run, minus the files. The first element is resolved
/// against local_paths before PATH.
/// local_paths: Repo-relative locations to prefer over PATH, so a project
/// gets the version its own CI runs (node_modules/.bin/eslint rather
/// than whatever is installed globally).
/// config_files: Repo-relative paths that mean "this project has opted
/// into this tool". A tool with none of them present is skipped: its
/// defaults are not the project's chosen style, so running it anyway
/// would invent findings the project never asked for.
/// config_flag: Flag that hands the discovered config file to the tool,
/// for the checkers that will not look for it themselves.
/// output_format: How to parse the tool's diagnostics into findings.
/// diagnostics_stream: Which stream carries them. `go vet` writes to
/// stderr, so reading only stdout would report every Go file clean.
/// Everything drep needs to know about one language.
///
/// Attributes:
/// name: Registry key (lowercase, e.g. "typescript").
/// display_name: How the language is named to the LLM and to users.
/// extensions: Lowercased suffixes this language owns, including the dot.
/// filenames: Whole file names this language owns, for extensionless files
/// such as `Dockerfile` and `Gemfile`.
/// tools: Deterministic checkers, in the order they should run.
/// conventions: Language-specific guidance appended to the analysis
/// prompt - the part that used to be hardcoded as PEP 8.
/// vendored_dirs: Dependency and build directories this language creates,
/// never descended into. Declared here rather than in a global list
/// so adding a language stays a single-file change.