windows-exe-decompiler-mcp-server 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 (190) hide show
  1. package/CODEX_INSTALLATION.md +69 -0
  2. package/COPILOT_INSTALLATION.md +77 -0
  3. package/LICENSE +21 -0
  4. package/README.md +314 -0
  5. package/bin/windows-exe-decompiler-mcp-server.js +3 -0
  6. package/dist/analysis-provenance.d.ts +184 -0
  7. package/dist/analysis-provenance.js +74 -0
  8. package/dist/analysis-task-runner.d.ts +31 -0
  9. package/dist/analysis-task-runner.js +160 -0
  10. package/dist/artifact-inventory.d.ts +23 -0
  11. package/dist/artifact-inventory.js +175 -0
  12. package/dist/cache-manager.d.ts +128 -0
  13. package/dist/cache-manager.js +454 -0
  14. package/dist/confidence-semantics.d.ts +66 -0
  15. package/dist/confidence-semantics.js +122 -0
  16. package/dist/config.d.ts +335 -0
  17. package/dist/config.js +193 -0
  18. package/dist/database.d.ts +227 -0
  19. package/dist/database.js +601 -0
  20. package/dist/decompiler-worker.d.ts +441 -0
  21. package/dist/decompiler-worker.js +1962 -0
  22. package/dist/dynamic-trace.d.ts +95 -0
  23. package/dist/dynamic-trace.js +629 -0
  24. package/dist/env-validator.d.ts +15 -0
  25. package/dist/env-validator.js +249 -0
  26. package/dist/error-handler.d.ts +28 -0
  27. package/dist/error-handler.example.d.ts +22 -0
  28. package/dist/error-handler.example.js +141 -0
  29. package/dist/error-handler.js +139 -0
  30. package/dist/ghidra-analysis-status.d.ts +49 -0
  31. package/dist/ghidra-analysis-status.js +178 -0
  32. package/dist/ghidra-config.d.ts +134 -0
  33. package/dist/ghidra-config.js +464 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.js +200 -0
  36. package/dist/job-queue.d.ts +169 -0
  37. package/dist/job-queue.js +407 -0
  38. package/dist/logger.d.ts +106 -0
  39. package/dist/logger.js +176 -0
  40. package/dist/policy-guard.d.ts +115 -0
  41. package/dist/policy-guard.js +243 -0
  42. package/dist/process-output.d.ts +15 -0
  43. package/dist/process-output.js +90 -0
  44. package/dist/prompts/function-explanation-review.d.ts +5 -0
  45. package/dist/prompts/function-explanation-review.js +64 -0
  46. package/dist/prompts/semantic-name-review.d.ts +5 -0
  47. package/dist/prompts/semantic-name-review.js +63 -0
  48. package/dist/runtime-correlation.d.ts +34 -0
  49. package/dist/runtime-correlation.js +279 -0
  50. package/dist/runtime-paths.d.ts +3 -0
  51. package/dist/runtime-paths.js +11 -0
  52. package/dist/selection-diff.d.ts +667 -0
  53. package/dist/selection-diff.js +53 -0
  54. package/dist/semantic-name-suggestion-artifacts.d.ts +116 -0
  55. package/dist/semantic-name-suggestion-artifacts.js +314 -0
  56. package/dist/server.d.ts +129 -0
  57. package/dist/server.js +578 -0
  58. package/dist/tools/artifact-read.d.ts +235 -0
  59. package/dist/tools/artifact-read.js +317 -0
  60. package/dist/tools/artifacts-diff.d.ts +728 -0
  61. package/dist/tools/artifacts-diff.js +304 -0
  62. package/dist/tools/artifacts-list.d.ts +515 -0
  63. package/dist/tools/artifacts-list.js +389 -0
  64. package/dist/tools/attack-map.d.ts +290 -0
  65. package/dist/tools/attack-map.js +519 -0
  66. package/dist/tools/cache-observability.d.ts +4 -0
  67. package/dist/tools/cache-observability.js +36 -0
  68. package/dist/tools/code-function-cfg.d.ts +50 -0
  69. package/dist/tools/code-function-cfg.js +102 -0
  70. package/dist/tools/code-function-decompile.d.ts +55 -0
  71. package/dist/tools/code-function-decompile.js +103 -0
  72. package/dist/tools/code-function-disassemble.d.ts +43 -0
  73. package/dist/tools/code-function-disassemble.js +185 -0
  74. package/dist/tools/code-function-explain-apply.d.ts +255 -0
  75. package/dist/tools/code-function-explain-apply.js +225 -0
  76. package/dist/tools/code-function-explain-prepare.d.ts +535 -0
  77. package/dist/tools/code-function-explain-prepare.js +276 -0
  78. package/dist/tools/code-function-explain-review.d.ts +397 -0
  79. package/dist/tools/code-function-explain-review.js +589 -0
  80. package/dist/tools/code-function-rename-apply.d.ts +248 -0
  81. package/dist/tools/code-function-rename-apply.js +220 -0
  82. package/dist/tools/code-function-rename-prepare.d.ts +506 -0
  83. package/dist/tools/code-function-rename-prepare.js +279 -0
  84. package/dist/tools/code-function-rename-review.d.ts +574 -0
  85. package/dist/tools/code-function-rename-review.js +761 -0
  86. package/dist/tools/code-functions-list.d.ts +37 -0
  87. package/dist/tools/code-functions-list.js +91 -0
  88. package/dist/tools/code-functions-rank.d.ts +34 -0
  89. package/dist/tools/code-functions-rank.js +90 -0
  90. package/dist/tools/code-functions-reconstruct.d.ts +2725 -0
  91. package/dist/tools/code-functions-reconstruct.js +2807 -0
  92. package/dist/tools/code-functions-search.d.ts +39 -0
  93. package/dist/tools/code-functions-search.js +90 -0
  94. package/dist/tools/code-reconstruct-export.d.ts +1212 -0
  95. package/dist/tools/code-reconstruct-export.js +4002 -0
  96. package/dist/tools/code-reconstruct-plan.d.ts +274 -0
  97. package/dist/tools/code-reconstruct-plan.js +342 -0
  98. package/dist/tools/dotnet-metadata-extract.d.ts +541 -0
  99. package/dist/tools/dotnet-metadata-extract.js +355 -0
  100. package/dist/tools/dotnet-reconstruct-export.d.ts +567 -0
  101. package/dist/tools/dotnet-reconstruct-export.js +1151 -0
  102. package/dist/tools/dotnet-types-list.d.ts +325 -0
  103. package/dist/tools/dotnet-types-list.js +201 -0
  104. package/dist/tools/dynamic-dependencies.d.ts +115 -0
  105. package/dist/tools/dynamic-dependencies.js +213 -0
  106. package/dist/tools/dynamic-memory-import.d.ts +10 -0
  107. package/dist/tools/dynamic-memory-import.js +567 -0
  108. package/dist/tools/dynamic-trace-import.d.ts +10 -0
  109. package/dist/tools/dynamic-trace-import.js +235 -0
  110. package/dist/tools/entrypoint-fallback-disasm.d.ts +30 -0
  111. package/dist/tools/entrypoint-fallback-disasm.js +89 -0
  112. package/dist/tools/ghidra-analyze.d.ts +88 -0
  113. package/dist/tools/ghidra-analyze.js +208 -0
  114. package/dist/tools/ghidra-health.d.ts +37 -0
  115. package/dist/tools/ghidra-health.js +212 -0
  116. package/dist/tools/ioc-export.d.ts +209 -0
  117. package/dist/tools/ioc-export.js +542 -0
  118. package/dist/tools/packer-detect.d.ts +165 -0
  119. package/dist/tools/packer-detect.js +284 -0
  120. package/dist/tools/pe-exports-extract.d.ts +175 -0
  121. package/dist/tools/pe-exports-extract.js +253 -0
  122. package/dist/tools/pe-fingerprint.d.ts +234 -0
  123. package/dist/tools/pe-fingerprint.js +269 -0
  124. package/dist/tools/pe-imports-extract.d.ts +105 -0
  125. package/dist/tools/pe-imports-extract.js +245 -0
  126. package/dist/tools/report-generate.d.ts +157 -0
  127. package/dist/tools/report-generate.js +457 -0
  128. package/dist/tools/report-summarize.d.ts +2131 -0
  129. package/dist/tools/report-summarize.js +596 -0
  130. package/dist/tools/runtime-detect.d.ts +135 -0
  131. package/dist/tools/runtime-detect.js +247 -0
  132. package/dist/tools/sample-ingest.d.ts +94 -0
  133. package/dist/tools/sample-ingest.js +327 -0
  134. package/dist/tools/sample-profile-get.d.ts +183 -0
  135. package/dist/tools/sample-profile-get.js +121 -0
  136. package/dist/tools/sandbox-execute.d.ts +441 -0
  137. package/dist/tools/sandbox-execute.js +392 -0
  138. package/dist/tools/strings-extract.d.ts +375 -0
  139. package/dist/tools/strings-extract.js +314 -0
  140. package/dist/tools/strings-floss-decode.d.ts +143 -0
  141. package/dist/tools/strings-floss-decode.js +259 -0
  142. package/dist/tools/system-health.d.ts +434 -0
  143. package/dist/tools/system-health.js +446 -0
  144. package/dist/tools/task-cancel.d.ts +21 -0
  145. package/dist/tools/task-cancel.js +70 -0
  146. package/dist/tools/task-status.d.ts +27 -0
  147. package/dist/tools/task-status.js +106 -0
  148. package/dist/tools/task-sweep.d.ts +22 -0
  149. package/dist/tools/task-sweep.js +77 -0
  150. package/dist/tools/tool-help.d.ts +340 -0
  151. package/dist/tools/tool-help.js +261 -0
  152. package/dist/tools/yara-scan.d.ts +554 -0
  153. package/dist/tools/yara-scan.js +313 -0
  154. package/dist/types.d.ts +266 -0
  155. package/dist/types.js +41 -0
  156. package/dist/worker-pool.d.ts +204 -0
  157. package/dist/worker-pool.js +650 -0
  158. package/dist/workflows/deep-static.d.ts +104 -0
  159. package/dist/workflows/deep-static.js +276 -0
  160. package/dist/workflows/function-explanation-review.d.ts +655 -0
  161. package/dist/workflows/function-explanation-review.js +440 -0
  162. package/dist/workflows/reconstruct.d.ts +2053 -0
  163. package/dist/workflows/reconstruct.js +666 -0
  164. package/dist/workflows/semantic-name-review.d.ts +2418 -0
  165. package/dist/workflows/semantic-name-review.js +521 -0
  166. package/dist/workflows/triage.d.ts +659 -0
  167. package/dist/workflows/triage.js +1374 -0
  168. package/dist/workspace-manager.d.ts +150 -0
  169. package/dist/workspace-manager.js +411 -0
  170. package/ghidra_scripts/DecompileFunction.java +487 -0
  171. package/ghidra_scripts/DecompileFunction.py +150 -0
  172. package/ghidra_scripts/ExtractCFG.java +256 -0
  173. package/ghidra_scripts/ExtractCFG.py +233 -0
  174. package/ghidra_scripts/ExtractFunctions.java +442 -0
  175. package/ghidra_scripts/ExtractFunctions.py +101 -0
  176. package/ghidra_scripts/README.md +125 -0
  177. package/ghidra_scripts/SearchFunctionReferences.java +380 -0
  178. package/helpers/DotNetMetadataProbe/DotNetMetadataProbe.csproj +9 -0
  179. package/helpers/DotNetMetadataProbe/Program.cs +566 -0
  180. package/install-to-codex.ps1 +178 -0
  181. package/install-to-copilot.ps1 +303 -0
  182. package/package.json +101 -0
  183. package/requirements.txt +9 -0
  184. package/workers/requirements-dynamic.txt +11 -0
  185. package/workers/requirements.txt +8 -0
  186. package/workers/speakeasy_compat.py +175 -0
  187. package/workers/static_worker.py +5183 -0
  188. package/workers/yara_rules/default.yar +33 -0
  189. package/workers/yara_rules/malware_families.yar +93 -0
  190. package/workers/yara_rules/packers.yar +80 -0
@@ -0,0 +1,355 @@
1
+ /**
2
+ * dotnet.metadata.extract tool implementation
3
+ * Extract managed assembly metadata without executing the sample.
4
+ */
5
+ import { spawn } from 'child_process';
6
+ import path from 'path';
7
+ import { z } from 'zod';
8
+ import { generateCacheKey } from '../cache-manager.js';
9
+ import { getPackageRoot, resolvePackagePath } from '../runtime-paths.js';
10
+ import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
11
+ import { createRuntimeDetectHandler } from './runtime-detect.js';
12
+ const TOOL_NAME = 'dotnet.metadata.extract';
13
+ const TOOL_VERSION = '0.1.0';
14
+ const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
15
+ const DEFAULT_TIMEOUT_MS = 120000;
16
+ export const DotNetMetadataExtractInputSchema = z.object({
17
+ sample_id: z.string().describe('Sample ID (format: sha256:<hex>)'),
18
+ include_types: z
19
+ .boolean()
20
+ .default(true)
21
+ .describe('Include per-type rows from CLR metadata'),
22
+ include_methods: z
23
+ .boolean()
24
+ .default(true)
25
+ .describe('Include per-method rows for returned types'),
26
+ max_types: z
27
+ .number()
28
+ .int()
29
+ .min(1)
30
+ .max(400)
31
+ .default(80)
32
+ .describe('Maximum number of managed types to return'),
33
+ max_methods_per_type: z
34
+ .number()
35
+ .int()
36
+ .min(1)
37
+ .max(128)
38
+ .default(24)
39
+ .describe('Maximum number of methods returned per type'),
40
+ force_refresh: z
41
+ .boolean()
42
+ .default(false)
43
+ .describe('Bypass cache lookup and recompute from source sample'),
44
+ });
45
+ const DotNetMetadataMethodSchema = z.object({
46
+ name: z.string(),
47
+ token: z.string(),
48
+ rva: z.number().int().nonnegative(),
49
+ attributes: z.array(z.string()),
50
+ is_constructor: z.boolean(),
51
+ is_static: z.boolean(),
52
+ });
53
+ const DotNetMetadataTypeSchema = z.object({
54
+ token: z.string(),
55
+ namespace: z.string(),
56
+ name: z.string(),
57
+ full_name: z.string(),
58
+ kind: z.string(),
59
+ visibility: z.string(),
60
+ base_type: z.string().nullable(),
61
+ method_count: z.number().int().nonnegative(),
62
+ field_count: z.number().int().nonnegative(),
63
+ nested_type_count: z.number().int().nonnegative(),
64
+ flags: z.array(z.string()),
65
+ methods: z.array(DotNetMetadataMethodSchema),
66
+ });
67
+ const DotNetAssemblyReferenceSchema = z.object({
68
+ name: z.string(),
69
+ version: z.string(),
70
+ culture: z.string().nullable(),
71
+ });
72
+ const DotNetManifestResourceSchema = z.object({
73
+ name: z.string(),
74
+ attributes: z.string(),
75
+ implementation: z.string(),
76
+ });
77
+ const DotNetNamespaceSchema = z.object({
78
+ name: z.string(),
79
+ type_count: z.number().int().nonnegative(),
80
+ method_count: z.number().int().nonnegative(),
81
+ });
82
+ const DotNetMetadataSummarySchema = z.object({
83
+ type_count: z.number().int().nonnegative(),
84
+ method_count: z.number().int().nonnegative(),
85
+ namespace_count: z.number().int().nonnegative(),
86
+ assembly_reference_count: z.number().int().nonnegative(),
87
+ resource_count: z.number().int().nonnegative(),
88
+ });
89
+ export const DotNetMetadataExtractOutputSchema = z.object({
90
+ ok: z.boolean(),
91
+ data: z
92
+ .object({
93
+ is_dotnet: z.boolean(),
94
+ assembly_name: z.string().nullable(),
95
+ assembly_version: z.string().nullable(),
96
+ module_name: z.string().nullable(),
97
+ metadata_version: z.string().nullable(),
98
+ dotnet_version: z.string().nullable(),
99
+ target_framework: z.string().nullable(),
100
+ is_library: z.boolean(),
101
+ entry_point_token: z.string().nullable(),
102
+ assembly_references: z.array(DotNetAssemblyReferenceSchema),
103
+ resources: z.array(DotNetManifestResourceSchema),
104
+ namespaces: z.array(DotNetNamespaceSchema),
105
+ types: z.array(DotNetMetadataTypeSchema),
106
+ summary: DotNetMetadataSummarySchema,
107
+ })
108
+ .optional(),
109
+ warnings: z.array(z.string()).optional(),
110
+ errors: z.array(z.string()).optional(),
111
+ artifacts: z.array(z.any()).optional(),
112
+ metrics: z
113
+ .object({
114
+ elapsed_ms: z.number(),
115
+ tool: z.string(),
116
+ cached: z.boolean().optional(),
117
+ cache_key: z.string().optional(),
118
+ cache_tier: z.string().optional(),
119
+ cache_created_at: z.string().optional(),
120
+ cache_expires_at: z.string().optional(),
121
+ cache_hit_at: z.string().optional(),
122
+ })
123
+ .optional(),
124
+ });
125
+ export const dotNetMetadataExtractToolDefinition = {
126
+ name: TOOL_NAME,
127
+ description: 'Extract managed assembly metadata (assembly refs, types, methods, resources, DLL/EXE role) for .NET samples without executing them.',
128
+ inputSchema: DotNetMetadataExtractInputSchema,
129
+ outputSchema: DotNetMetadataExtractOutputSchema,
130
+ };
131
+ function normalizeError(error) {
132
+ if (error instanceof Error) {
133
+ return error.message;
134
+ }
135
+ return String(error);
136
+ }
137
+ function extractVersionFromTargetFramework(targetFramework) {
138
+ if (!targetFramework) {
139
+ return null;
140
+ }
141
+ const match = targetFramework.match(/Version=v?([0-9]+(?:\.[0-9]+)?)/i);
142
+ return match ? match[1] : null;
143
+ }
144
+ export async function runDotNetMetadataProbe(samplePath, options) {
145
+ return new Promise((resolve) => {
146
+ const projectPath = resolvePackagePath('helpers', 'DotNetMetadataProbe', 'DotNetMetadataProbe.csproj');
147
+ const args = [
148
+ 'run',
149
+ '--project',
150
+ projectPath,
151
+ '--configuration',
152
+ 'Release',
153
+ '--',
154
+ samplePath,
155
+ `--include-types=${options.includeTypes}`,
156
+ `--include-methods=${options.includeMethods}`,
157
+ `--max-types=${options.maxTypes}`,
158
+ `--max-methods-per-type=${options.maxMethodsPerType}`,
159
+ ];
160
+ const child = spawn('dotnet', args, {
161
+ cwd: getPackageRoot(),
162
+ stdio: ['ignore', 'pipe', 'pipe'],
163
+ windowsHide: true,
164
+ });
165
+ let stdout = '';
166
+ let stderr = '';
167
+ let settled = false;
168
+ const effectiveTimeoutMs = Math.max(10000, options.timeoutMs || DEFAULT_TIMEOUT_MS);
169
+ const finish = (result) => {
170
+ if (settled) {
171
+ return;
172
+ }
173
+ settled = true;
174
+ clearTimeout(timer);
175
+ resolve(result);
176
+ };
177
+ const timer = setTimeout(() => {
178
+ child.kill();
179
+ finish({
180
+ ok: false,
181
+ errors: [`dotnet metadata probe timed out after ${effectiveTimeoutMs}ms`],
182
+ });
183
+ }, effectiveTimeoutMs);
184
+ child.stdout.on('data', (chunk) => {
185
+ stdout += chunk.toString();
186
+ });
187
+ child.stderr.on('data', (chunk) => {
188
+ stderr += chunk.toString();
189
+ });
190
+ child.on('error', (error) => {
191
+ finish({
192
+ ok: false,
193
+ errors: [
194
+ error.code === 'ENOENT'
195
+ ? 'dotnet CLI is not available in PATH'
196
+ : `Failed to spawn dotnet metadata probe: ${error.message}`,
197
+ ],
198
+ });
199
+ });
200
+ child.on('close', (code) => {
201
+ const output = stdout.trim();
202
+ if (code !== 0 && output.length === 0) {
203
+ finish({
204
+ ok: false,
205
+ errors: [`dotnet metadata probe failed with exit code ${code ?? 'unknown'}: ${stderr.trim() || 'no stderr'}`],
206
+ });
207
+ return;
208
+ }
209
+ try {
210
+ const parsed = JSON.parse(output || '{}');
211
+ if (!parsed.ok && stderr.trim().length > 0) {
212
+ parsed.errors = [...(parsed.errors || []), stderr.trim()];
213
+ }
214
+ finish(parsed);
215
+ }
216
+ catch (error) {
217
+ finish({
218
+ ok: false,
219
+ errors: [
220
+ `Failed to parse dotnet metadata probe output: ${error.message}`,
221
+ stderr.trim() || stdout.trim() || 'no output',
222
+ ],
223
+ });
224
+ }
225
+ });
226
+ });
227
+ }
228
+ export function createDotNetMetadataExtractHandler(workspaceManager, database, cacheManager, dependencies) {
229
+ const runtimeDetectHandler = dependencies?.runtimeDetectHandler ||
230
+ createRuntimeDetectHandler(workspaceManager, database, cacheManager);
231
+ const probeRunner = dependencies?.probeRunner || runDotNetMetadataProbe;
232
+ return async (args) => {
233
+ const input = DotNetMetadataExtractInputSchema.parse(args);
234
+ const startTime = Date.now();
235
+ try {
236
+ const sample = database.findSample(input.sample_id);
237
+ if (!sample) {
238
+ return {
239
+ ok: false,
240
+ errors: [`Sample not found: ${input.sample_id}`],
241
+ };
242
+ }
243
+ const runtimeResult = await runtimeDetectHandler({ sample_id: input.sample_id });
244
+ const runtimeData = (runtimeResult.ok ? runtimeResult.data : undefined);
245
+ if (!runtimeResult.ok || runtimeData?.is_dotnet !== true) {
246
+ const suspected = (runtimeData?.suspected || [])
247
+ .map((item) => `${item.runtime}(${item.confidence.toFixed(2)})`)
248
+ .join(', ');
249
+ return {
250
+ ok: false,
251
+ errors: ['Target sample is not recognized as a .NET assembly.'],
252
+ warnings: suspected.length > 0
253
+ ? [`runtime.detect suspected: ${suspected}`]
254
+ : runtimeResult.warnings,
255
+ metrics: {
256
+ elapsed_ms: Date.now() - startTime,
257
+ tool: TOOL_NAME,
258
+ },
259
+ };
260
+ }
261
+ const cacheKey = generateCacheKey({
262
+ sampleSha256: sample.sha256,
263
+ toolName: TOOL_NAME,
264
+ toolVersion: TOOL_VERSION,
265
+ args: {
266
+ include_types: input.include_types,
267
+ include_methods: input.include_methods,
268
+ max_types: input.max_types,
269
+ max_methods_per_type: input.max_methods_per_type,
270
+ dotnet_version: runtimeData.dotnet_version || null,
271
+ target_framework: runtimeData.target_framework || null,
272
+ },
273
+ });
274
+ if (!input.force_refresh) {
275
+ const cachedLookup = await lookupCachedResult(cacheManager, cacheKey);
276
+ if (cachedLookup) {
277
+ return {
278
+ ok: true,
279
+ data: cachedLookup.data,
280
+ warnings: ['Result from cache', formatCacheWarning(cachedLookup.metadata)],
281
+ metrics: {
282
+ elapsed_ms: Date.now() - startTime,
283
+ tool: TOOL_NAME,
284
+ cached: true,
285
+ cache_key: cachedLookup.metadata.key,
286
+ cache_tier: cachedLookup.metadata.tier,
287
+ cache_created_at: cachedLookup.metadata.createdAt,
288
+ cache_expires_at: cachedLookup.metadata.expiresAt,
289
+ cache_hit_at: cachedLookup.metadata.fetchedAt,
290
+ },
291
+ };
292
+ }
293
+ }
294
+ const workspace = await workspaceManager.getWorkspace(input.sample_id);
295
+ const files = await (await import('fs/promises')).readdir(workspace.original);
296
+ if (files.length === 0) {
297
+ return {
298
+ ok: false,
299
+ errors: ['Sample file not found in workspace'],
300
+ metrics: {
301
+ elapsed_ms: Date.now() - startTime,
302
+ tool: TOOL_NAME,
303
+ },
304
+ };
305
+ }
306
+ const samplePath = path.join(workspace.original, files[0]);
307
+ const probeResult = await probeRunner(samplePath, {
308
+ includeTypes: input.include_types,
309
+ includeMethods: input.include_methods,
310
+ maxTypes: input.max_types,
311
+ maxMethodsPerType: input.max_methods_per_type,
312
+ });
313
+ if (!probeResult.ok || !probeResult.data) {
314
+ return {
315
+ ok: false,
316
+ errors: probeResult.errors || ['dotnet metadata probe failed'],
317
+ warnings: probeResult.warnings,
318
+ metrics: {
319
+ elapsed_ms: Date.now() - startTime,
320
+ tool: TOOL_NAME,
321
+ },
322
+ };
323
+ }
324
+ const data = {
325
+ ...probeResult.data,
326
+ dotnet_version: runtimeData.dotnet_version || null,
327
+ target_framework: runtimeData.target_framework || probeResult.data.target_framework || null,
328
+ };
329
+ if (!data.dotnet_version) {
330
+ data.dotnet_version = extractVersionFromTargetFramework(data.target_framework);
331
+ }
332
+ await cacheManager.setCachedResult(cacheKey, data, CACHE_TTL_MS, sample.sha256);
333
+ return {
334
+ ok: true,
335
+ data,
336
+ warnings: probeResult.warnings?.length ? probeResult.warnings : runtimeResult.warnings,
337
+ metrics: {
338
+ elapsed_ms: Date.now() - startTime,
339
+ tool: TOOL_NAME,
340
+ },
341
+ };
342
+ }
343
+ catch (error) {
344
+ return {
345
+ ok: false,
346
+ errors: [normalizeError(error)],
347
+ metrics: {
348
+ elapsed_ms: Date.now() - startTime,
349
+ tool: TOOL_NAME,
350
+ },
351
+ };
352
+ }
353
+ };
354
+ }
355
+ //# sourceMappingURL=dotnet-metadata-extract.js.map