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.
- package/CODEX_INSTALLATION.md +69 -0
- package/COPILOT_INSTALLATION.md +77 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/bin/windows-exe-decompiler-mcp-server.js +3 -0
- package/dist/analysis-provenance.d.ts +184 -0
- package/dist/analysis-provenance.js +74 -0
- package/dist/analysis-task-runner.d.ts +31 -0
- package/dist/analysis-task-runner.js +160 -0
- package/dist/artifact-inventory.d.ts +23 -0
- package/dist/artifact-inventory.js +175 -0
- package/dist/cache-manager.d.ts +128 -0
- package/dist/cache-manager.js +454 -0
- package/dist/confidence-semantics.d.ts +66 -0
- package/dist/confidence-semantics.js +122 -0
- package/dist/config.d.ts +335 -0
- package/dist/config.js +193 -0
- package/dist/database.d.ts +227 -0
- package/dist/database.js +601 -0
- package/dist/decompiler-worker.d.ts +441 -0
- package/dist/decompiler-worker.js +1962 -0
- package/dist/dynamic-trace.d.ts +95 -0
- package/dist/dynamic-trace.js +629 -0
- package/dist/env-validator.d.ts +15 -0
- package/dist/env-validator.js +249 -0
- package/dist/error-handler.d.ts +28 -0
- package/dist/error-handler.example.d.ts +22 -0
- package/dist/error-handler.example.js +141 -0
- package/dist/error-handler.js +139 -0
- package/dist/ghidra-analysis-status.d.ts +49 -0
- package/dist/ghidra-analysis-status.js +178 -0
- package/dist/ghidra-config.d.ts +134 -0
- package/dist/ghidra-config.js +464 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +200 -0
- package/dist/job-queue.d.ts +169 -0
- package/dist/job-queue.js +407 -0
- package/dist/logger.d.ts +106 -0
- package/dist/logger.js +176 -0
- package/dist/policy-guard.d.ts +115 -0
- package/dist/policy-guard.js +243 -0
- package/dist/process-output.d.ts +15 -0
- package/dist/process-output.js +90 -0
- package/dist/prompts/function-explanation-review.d.ts +5 -0
- package/dist/prompts/function-explanation-review.js +64 -0
- package/dist/prompts/semantic-name-review.d.ts +5 -0
- package/dist/prompts/semantic-name-review.js +63 -0
- package/dist/runtime-correlation.d.ts +34 -0
- package/dist/runtime-correlation.js +279 -0
- package/dist/runtime-paths.d.ts +3 -0
- package/dist/runtime-paths.js +11 -0
- package/dist/selection-diff.d.ts +667 -0
- package/dist/selection-diff.js +53 -0
- package/dist/semantic-name-suggestion-artifacts.d.ts +116 -0
- package/dist/semantic-name-suggestion-artifacts.js +314 -0
- package/dist/server.d.ts +129 -0
- package/dist/server.js +578 -0
- package/dist/tools/artifact-read.d.ts +235 -0
- package/dist/tools/artifact-read.js +317 -0
- package/dist/tools/artifacts-diff.d.ts +728 -0
- package/dist/tools/artifacts-diff.js +304 -0
- package/dist/tools/artifacts-list.d.ts +515 -0
- package/dist/tools/artifacts-list.js +389 -0
- package/dist/tools/attack-map.d.ts +290 -0
- package/dist/tools/attack-map.js +519 -0
- package/dist/tools/cache-observability.d.ts +4 -0
- package/dist/tools/cache-observability.js +36 -0
- package/dist/tools/code-function-cfg.d.ts +50 -0
- package/dist/tools/code-function-cfg.js +102 -0
- package/dist/tools/code-function-decompile.d.ts +55 -0
- package/dist/tools/code-function-decompile.js +103 -0
- package/dist/tools/code-function-disassemble.d.ts +43 -0
- package/dist/tools/code-function-disassemble.js +185 -0
- package/dist/tools/code-function-explain-apply.d.ts +255 -0
- package/dist/tools/code-function-explain-apply.js +225 -0
- package/dist/tools/code-function-explain-prepare.d.ts +535 -0
- package/dist/tools/code-function-explain-prepare.js +276 -0
- package/dist/tools/code-function-explain-review.d.ts +397 -0
- package/dist/tools/code-function-explain-review.js +589 -0
- package/dist/tools/code-function-rename-apply.d.ts +248 -0
- package/dist/tools/code-function-rename-apply.js +220 -0
- package/dist/tools/code-function-rename-prepare.d.ts +506 -0
- package/dist/tools/code-function-rename-prepare.js +279 -0
- package/dist/tools/code-function-rename-review.d.ts +574 -0
- package/dist/tools/code-function-rename-review.js +761 -0
- package/dist/tools/code-functions-list.d.ts +37 -0
- package/dist/tools/code-functions-list.js +91 -0
- package/dist/tools/code-functions-rank.d.ts +34 -0
- package/dist/tools/code-functions-rank.js +90 -0
- package/dist/tools/code-functions-reconstruct.d.ts +2725 -0
- package/dist/tools/code-functions-reconstruct.js +2807 -0
- package/dist/tools/code-functions-search.d.ts +39 -0
- package/dist/tools/code-functions-search.js +90 -0
- package/dist/tools/code-reconstruct-export.d.ts +1212 -0
- package/dist/tools/code-reconstruct-export.js +4002 -0
- package/dist/tools/code-reconstruct-plan.d.ts +274 -0
- package/dist/tools/code-reconstruct-plan.js +342 -0
- package/dist/tools/dotnet-metadata-extract.d.ts +541 -0
- package/dist/tools/dotnet-metadata-extract.js +355 -0
- package/dist/tools/dotnet-reconstruct-export.d.ts +567 -0
- package/dist/tools/dotnet-reconstruct-export.js +1151 -0
- package/dist/tools/dotnet-types-list.d.ts +325 -0
- package/dist/tools/dotnet-types-list.js +201 -0
- package/dist/tools/dynamic-dependencies.d.ts +115 -0
- package/dist/tools/dynamic-dependencies.js +213 -0
- package/dist/tools/dynamic-memory-import.d.ts +10 -0
- package/dist/tools/dynamic-memory-import.js +567 -0
- package/dist/tools/dynamic-trace-import.d.ts +10 -0
- package/dist/tools/dynamic-trace-import.js +235 -0
- package/dist/tools/entrypoint-fallback-disasm.d.ts +30 -0
- package/dist/tools/entrypoint-fallback-disasm.js +89 -0
- package/dist/tools/ghidra-analyze.d.ts +88 -0
- package/dist/tools/ghidra-analyze.js +208 -0
- package/dist/tools/ghidra-health.d.ts +37 -0
- package/dist/tools/ghidra-health.js +212 -0
- package/dist/tools/ioc-export.d.ts +209 -0
- package/dist/tools/ioc-export.js +542 -0
- package/dist/tools/packer-detect.d.ts +165 -0
- package/dist/tools/packer-detect.js +284 -0
- package/dist/tools/pe-exports-extract.d.ts +175 -0
- package/dist/tools/pe-exports-extract.js +253 -0
- package/dist/tools/pe-fingerprint.d.ts +234 -0
- package/dist/tools/pe-fingerprint.js +269 -0
- package/dist/tools/pe-imports-extract.d.ts +105 -0
- package/dist/tools/pe-imports-extract.js +245 -0
- package/dist/tools/report-generate.d.ts +157 -0
- package/dist/tools/report-generate.js +457 -0
- package/dist/tools/report-summarize.d.ts +2131 -0
- package/dist/tools/report-summarize.js +596 -0
- package/dist/tools/runtime-detect.d.ts +135 -0
- package/dist/tools/runtime-detect.js +247 -0
- package/dist/tools/sample-ingest.d.ts +94 -0
- package/dist/tools/sample-ingest.js +327 -0
- package/dist/tools/sample-profile-get.d.ts +183 -0
- package/dist/tools/sample-profile-get.js +121 -0
- package/dist/tools/sandbox-execute.d.ts +441 -0
- package/dist/tools/sandbox-execute.js +392 -0
- package/dist/tools/strings-extract.d.ts +375 -0
- package/dist/tools/strings-extract.js +314 -0
- package/dist/tools/strings-floss-decode.d.ts +143 -0
- package/dist/tools/strings-floss-decode.js +259 -0
- package/dist/tools/system-health.d.ts +434 -0
- package/dist/tools/system-health.js +446 -0
- package/dist/tools/task-cancel.d.ts +21 -0
- package/dist/tools/task-cancel.js +70 -0
- package/dist/tools/task-status.d.ts +27 -0
- package/dist/tools/task-status.js +106 -0
- package/dist/tools/task-sweep.d.ts +22 -0
- package/dist/tools/task-sweep.js +77 -0
- package/dist/tools/tool-help.d.ts +340 -0
- package/dist/tools/tool-help.js +261 -0
- package/dist/tools/yara-scan.d.ts +554 -0
- package/dist/tools/yara-scan.js +313 -0
- package/dist/types.d.ts +266 -0
- package/dist/types.js +41 -0
- package/dist/worker-pool.d.ts +204 -0
- package/dist/worker-pool.js +650 -0
- package/dist/workflows/deep-static.d.ts +104 -0
- package/dist/workflows/deep-static.js +276 -0
- package/dist/workflows/function-explanation-review.d.ts +655 -0
- package/dist/workflows/function-explanation-review.js +440 -0
- package/dist/workflows/reconstruct.d.ts +2053 -0
- package/dist/workflows/reconstruct.js +666 -0
- package/dist/workflows/semantic-name-review.d.ts +2418 -0
- package/dist/workflows/semantic-name-review.js +521 -0
- package/dist/workflows/triage.d.ts +659 -0
- package/dist/workflows/triage.js +1374 -0
- package/dist/workspace-manager.d.ts +150 -0
- package/dist/workspace-manager.js +411 -0
- package/ghidra_scripts/DecompileFunction.java +487 -0
- package/ghidra_scripts/DecompileFunction.py +150 -0
- package/ghidra_scripts/ExtractCFG.java +256 -0
- package/ghidra_scripts/ExtractCFG.py +233 -0
- package/ghidra_scripts/ExtractFunctions.java +442 -0
- package/ghidra_scripts/ExtractFunctions.py +101 -0
- package/ghidra_scripts/README.md +125 -0
- package/ghidra_scripts/SearchFunctionReferences.java +380 -0
- package/helpers/DotNetMetadataProbe/DotNetMetadataProbe.csproj +9 -0
- package/helpers/DotNetMetadataProbe/Program.cs +566 -0
- package/install-to-codex.ps1 +178 -0
- package/install-to-copilot.ps1 +303 -0
- package/package.json +101 -0
- package/requirements.txt +9 -0
- package/workers/requirements-dynamic.txt +11 -0
- package/workers/requirements.txt +8 -0
- package/workers/speakeasy_compat.py +175 -0
- package/workers/static_worker.py +5183 -0
- package/workers/yara_rules/default.yar +33 -0
- package/workers/yara_rules/malware_families.yar +93 -0
- package/workers/yara_rules/packers.yar +80 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workflow.function_explanation_review
|
|
3
|
+
* High-level orchestration for function explanation review plus optional reconstruct export refresh.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { createCodeFunctionExplainReviewHandler } from '../tools/code-function-explain-review.js';
|
|
7
|
+
import { createReconstructWorkflowHandler } from './reconstruct.js';
|
|
8
|
+
const TOOL_NAME = 'workflow.function_explanation_review';
|
|
9
|
+
export const functionExplanationReviewWorkflowInputSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
sample_id: z.string().describe('Sample ID (format: sha256:<hex>)'),
|
|
12
|
+
address: z.string().optional().describe('Optional specific function address'),
|
|
13
|
+
symbol: z.string().optional().describe('Optional specific function symbol'),
|
|
14
|
+
topk: z
|
|
15
|
+
.number()
|
|
16
|
+
.int()
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(20)
|
|
19
|
+
.default(6)
|
|
20
|
+
.describe('When address/symbol not provided, review up to top-K functions'),
|
|
21
|
+
max_functions: z
|
|
22
|
+
.number()
|
|
23
|
+
.int()
|
|
24
|
+
.min(1)
|
|
25
|
+
.max(20)
|
|
26
|
+
.default(6)
|
|
27
|
+
.describe('Maximum number of functions included in the explanation review bundle'),
|
|
28
|
+
include_resolved: z
|
|
29
|
+
.boolean()
|
|
30
|
+
.default(true)
|
|
31
|
+
.describe('Include already resolved functions so the external LLM can explain stable and unresolved ones together'),
|
|
32
|
+
analysis_goal: z
|
|
33
|
+
.string()
|
|
34
|
+
.min(1)
|
|
35
|
+
.max(400)
|
|
36
|
+
.default('Explain the prepared functions in plain language and propose evidence-grounded rewrite guidance.')
|
|
37
|
+
.describe('Human-readable analysis goal injected into the MCP prompt and sampling request'),
|
|
38
|
+
session_tag: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe('Optional semantic explanation session tag used for artifact grouping'),
|
|
42
|
+
evidence_scope: z
|
|
43
|
+
.enum(['all', 'latest', 'session'])
|
|
44
|
+
.default('all')
|
|
45
|
+
.describe('Runtime evidence scope forwarded to review and optional reconstruct/export refresh'),
|
|
46
|
+
evidence_session_tag: z
|
|
47
|
+
.string()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Optional runtime evidence session selector used when evidence_scope=session or to narrow all/latest results'),
|
|
50
|
+
semantic_scope: z
|
|
51
|
+
.enum(['all', 'latest', 'session'])
|
|
52
|
+
.default('all')
|
|
53
|
+
.describe('Semantic artifact scope used when refreshing reconstruct/export output after apply'),
|
|
54
|
+
semantic_session_tag: z
|
|
55
|
+
.string()
|
|
56
|
+
.optional()
|
|
57
|
+
.describe('Optional semantic review session selector used when semantic_scope=session or to narrow all/latest results'),
|
|
58
|
+
persist_artifact: z
|
|
59
|
+
.boolean()
|
|
60
|
+
.default(true)
|
|
61
|
+
.describe('Persist the prepare bundle artifact before requesting external explanation review'),
|
|
62
|
+
auto_apply: z
|
|
63
|
+
.boolean()
|
|
64
|
+
.default(true)
|
|
65
|
+
.describe('Persist accepted explanations automatically via code.function.explain.apply'),
|
|
66
|
+
temperature: z
|
|
67
|
+
.number()
|
|
68
|
+
.min(0)
|
|
69
|
+
.max(1)
|
|
70
|
+
.default(0.2)
|
|
71
|
+
.describe('Sampling temperature passed to the connected MCP client'),
|
|
72
|
+
max_tokens: z
|
|
73
|
+
.number()
|
|
74
|
+
.int()
|
|
75
|
+
.min(200)
|
|
76
|
+
.max(8000)
|
|
77
|
+
.default(2200)
|
|
78
|
+
.describe('Maximum sampling tokens requested from the connected MCP client'),
|
|
79
|
+
include_context: z
|
|
80
|
+
.enum(['none', 'thisServer', 'allServers'])
|
|
81
|
+
.default('none')
|
|
82
|
+
.describe('Requested MCP sampling context scope; clients may ignore this preference'),
|
|
83
|
+
model_hint: z
|
|
84
|
+
.string()
|
|
85
|
+
.min(1)
|
|
86
|
+
.max(120)
|
|
87
|
+
.optional()
|
|
88
|
+
.describe('Optional advisory model-family hint for client-mediated MCP sampling'),
|
|
89
|
+
cost_priority: z
|
|
90
|
+
.number()
|
|
91
|
+
.min(0)
|
|
92
|
+
.max(1)
|
|
93
|
+
.default(0.1)
|
|
94
|
+
.describe('Advisory model selection preference for sampling cost'),
|
|
95
|
+
speed_priority: z
|
|
96
|
+
.number()
|
|
97
|
+
.min(0)
|
|
98
|
+
.max(1)
|
|
99
|
+
.default(0.2)
|
|
100
|
+
.describe('Advisory model selection preference for sampling latency'),
|
|
101
|
+
intelligence_priority: z
|
|
102
|
+
.number()
|
|
103
|
+
.min(0)
|
|
104
|
+
.max(1)
|
|
105
|
+
.default(0.95)
|
|
106
|
+
.describe('Advisory model selection preference for reasoning quality'),
|
|
107
|
+
system_prompt: z
|
|
108
|
+
.string()
|
|
109
|
+
.min(1)
|
|
110
|
+
.max(800)
|
|
111
|
+
.optional()
|
|
112
|
+
.describe('Optional extra system prompt for the client-mediated explanation review'),
|
|
113
|
+
rerun_export: z
|
|
114
|
+
.boolean()
|
|
115
|
+
.default(true)
|
|
116
|
+
.describe('After successful apply, rerun workflow.reconstruct to refresh rewrite/export output'),
|
|
117
|
+
export_path: z
|
|
118
|
+
.enum(['auto', 'native', 'dotnet'])
|
|
119
|
+
.default('auto')
|
|
120
|
+
.describe('Routing strategy used when rerun_export=true'),
|
|
121
|
+
export_topk: z
|
|
122
|
+
.number()
|
|
123
|
+
.int()
|
|
124
|
+
.min(1)
|
|
125
|
+
.max(40)
|
|
126
|
+
.default(12)
|
|
127
|
+
.describe('Top-K high-value functions used for optional reconstruct/export refresh'),
|
|
128
|
+
export_name: z
|
|
129
|
+
.string()
|
|
130
|
+
.min(1)
|
|
131
|
+
.max(64)
|
|
132
|
+
.optional()
|
|
133
|
+
.describe('Optional export folder name used for the refresh run'),
|
|
134
|
+
include_plan: z
|
|
135
|
+
.boolean()
|
|
136
|
+
.default(false)
|
|
137
|
+
.describe('Include code.reconstruct.plan when rerun_export=true'),
|
|
138
|
+
include_obfuscation_fallback: z
|
|
139
|
+
.boolean()
|
|
140
|
+
.default(true)
|
|
141
|
+
.describe('When routing to .NET path, generate IL fallback notes when needed'),
|
|
142
|
+
fallback_on_error: z
|
|
143
|
+
.boolean()
|
|
144
|
+
.default(true)
|
|
145
|
+
.describe('When primary export path fails, automatically try the alternative path'),
|
|
146
|
+
allow_partial: z
|
|
147
|
+
.boolean()
|
|
148
|
+
.default(true)
|
|
149
|
+
.describe('When all export paths fail, still return runtime/plan as partial output'),
|
|
150
|
+
validate_build: z
|
|
151
|
+
.boolean()
|
|
152
|
+
.default(false)
|
|
153
|
+
.describe('Compile the refreshed native reconstruction when rerun_export=true'),
|
|
154
|
+
run_harness: z
|
|
155
|
+
.boolean()
|
|
156
|
+
.default(false)
|
|
157
|
+
.describe('Execute reconstruct_harness after a successful refreshed native build'),
|
|
158
|
+
compiler_path: z
|
|
159
|
+
.string()
|
|
160
|
+
.min(1)
|
|
161
|
+
.max(260)
|
|
162
|
+
.optional()
|
|
163
|
+
.describe('Optional explicit clang compiler path for the refresh run'),
|
|
164
|
+
build_timeout_ms: z
|
|
165
|
+
.number()
|
|
166
|
+
.int()
|
|
167
|
+
.min(5000)
|
|
168
|
+
.max(300000)
|
|
169
|
+
.default(60000)
|
|
170
|
+
.describe('Timeout for native clang build validation in milliseconds'),
|
|
171
|
+
run_timeout_ms: z
|
|
172
|
+
.number()
|
|
173
|
+
.int()
|
|
174
|
+
.min(5000)
|
|
175
|
+
.max(300000)
|
|
176
|
+
.default(30000)
|
|
177
|
+
.describe('Timeout for reconstruct_harness execution in milliseconds'),
|
|
178
|
+
reuse_cached: z
|
|
179
|
+
.boolean()
|
|
180
|
+
.default(true)
|
|
181
|
+
.describe('Reuse cached reconstruct workflow results for the optional refresh run'),
|
|
182
|
+
})
|
|
183
|
+
.refine((value) => value.evidence_scope !== 'session' || Boolean(value.evidence_session_tag?.trim()), {
|
|
184
|
+
message: 'evidence_session_tag is required when evidence_scope=session',
|
|
185
|
+
path: ['evidence_session_tag'],
|
|
186
|
+
})
|
|
187
|
+
.refine((value) => value.semantic_scope !== 'session' || Boolean(value.semantic_session_tag?.trim()), {
|
|
188
|
+
message: 'semantic_session_tag is required when semantic_scope=session',
|
|
189
|
+
path: ['semantic_session_tag'],
|
|
190
|
+
});
|
|
191
|
+
export const functionExplanationReviewWorkflowOutputSchema = z.object({
|
|
192
|
+
ok: z.boolean(),
|
|
193
|
+
data: z
|
|
194
|
+
.object({
|
|
195
|
+
sample_id: z.string(),
|
|
196
|
+
review: z.object({
|
|
197
|
+
review_status: z.string(),
|
|
198
|
+
prompt_name: z.string(),
|
|
199
|
+
client: z.object({
|
|
200
|
+
name: z.string().nullable(),
|
|
201
|
+
version: z.string().nullable(),
|
|
202
|
+
sampling_available: z.boolean(),
|
|
203
|
+
}),
|
|
204
|
+
prepare: z.object({
|
|
205
|
+
prepared_count: z.number().int().nonnegative(),
|
|
206
|
+
artifact_id: z.string().nullable(),
|
|
207
|
+
}),
|
|
208
|
+
sampling: z.object({
|
|
209
|
+
attempted: z.boolean(),
|
|
210
|
+
model: z.string().nullable(),
|
|
211
|
+
stop_reason: z.string().nullable(),
|
|
212
|
+
parsed_explanation_count: z.number().int().nonnegative(),
|
|
213
|
+
}),
|
|
214
|
+
apply: z.object({
|
|
215
|
+
attempted: z.boolean(),
|
|
216
|
+
accepted_count: z.number().int().nonnegative(),
|
|
217
|
+
rejected_count: z.number().int().nonnegative(),
|
|
218
|
+
artifact_id: z.string().nullable(),
|
|
219
|
+
}),
|
|
220
|
+
confidence_policy: z.object({
|
|
221
|
+
calibrated: z.boolean(),
|
|
222
|
+
explanation_scores_are_heuristic: z.boolean(),
|
|
223
|
+
meaning: z.string(),
|
|
224
|
+
}),
|
|
225
|
+
}),
|
|
226
|
+
export: z.object({
|
|
227
|
+
attempted: z.boolean(),
|
|
228
|
+
status: z.enum(['completed', 'failed', 'skipped']),
|
|
229
|
+
selected_path: z.enum(['native', 'dotnet']).nullable(),
|
|
230
|
+
export_tool: z.string().nullable(),
|
|
231
|
+
export_root: z.string().nullable(),
|
|
232
|
+
manifest_path: z.string().nullable(),
|
|
233
|
+
build_validation_status: z.string().nullable(),
|
|
234
|
+
harness_validation_status: z.string().nullable(),
|
|
235
|
+
notes: z.array(z.string()),
|
|
236
|
+
}),
|
|
237
|
+
next_steps: z.array(z.string()),
|
|
238
|
+
})
|
|
239
|
+
.optional(),
|
|
240
|
+
warnings: z.array(z.string()).optional(),
|
|
241
|
+
errors: z.array(z.string()).optional(),
|
|
242
|
+
artifacts: z.array(z.any()).optional(),
|
|
243
|
+
metrics: z
|
|
244
|
+
.object({
|
|
245
|
+
elapsed_ms: z.number(),
|
|
246
|
+
tool: z.string(),
|
|
247
|
+
})
|
|
248
|
+
.optional(),
|
|
249
|
+
});
|
|
250
|
+
export const functionExplanationReviewWorkflowToolDefinition = {
|
|
251
|
+
name: TOOL_NAME,
|
|
252
|
+
description: 'Run function explanation review end-to-end for any MCP-capable LLM client, then optionally refresh reconstruct/export output with the applied explanations.',
|
|
253
|
+
inputSchema: functionExplanationReviewWorkflowInputSchema,
|
|
254
|
+
outputSchema: functionExplanationReviewWorkflowOutputSchema,
|
|
255
|
+
};
|
|
256
|
+
export function createFunctionExplanationReviewWorkflowHandler(workspaceManager, database, cacheManager, mcpServer, dependencies) {
|
|
257
|
+
const explainReviewHandler = dependencies?.explainReviewHandler ||
|
|
258
|
+
createCodeFunctionExplainReviewHandler(workspaceManager, database, cacheManager, mcpServer);
|
|
259
|
+
const reconstructWorkflowHandler = dependencies?.reconstructWorkflowHandler ||
|
|
260
|
+
createReconstructWorkflowHandler(workspaceManager, database, cacheManager);
|
|
261
|
+
return async (args) => {
|
|
262
|
+
const startTime = Date.now();
|
|
263
|
+
const warnings = [];
|
|
264
|
+
const errors = [];
|
|
265
|
+
const artifacts = [];
|
|
266
|
+
try {
|
|
267
|
+
const input = functionExplanationReviewWorkflowInputSchema.parse(args);
|
|
268
|
+
const reviewResult = await explainReviewHandler({
|
|
269
|
+
sample_id: input.sample_id,
|
|
270
|
+
address: input.address,
|
|
271
|
+
symbol: input.symbol,
|
|
272
|
+
topk: input.topk,
|
|
273
|
+
max_functions: input.max_functions,
|
|
274
|
+
include_resolved: input.include_resolved,
|
|
275
|
+
analysis_goal: input.analysis_goal,
|
|
276
|
+
session_tag: input.session_tag,
|
|
277
|
+
evidence_scope: input.evidence_scope,
|
|
278
|
+
evidence_session_tag: input.evidence_session_tag,
|
|
279
|
+
persist_artifact: input.persist_artifact,
|
|
280
|
+
auto_apply: input.auto_apply,
|
|
281
|
+
temperature: input.temperature,
|
|
282
|
+
max_tokens: input.max_tokens,
|
|
283
|
+
include_context: input.include_context,
|
|
284
|
+
model_hint: input.model_hint,
|
|
285
|
+
cost_priority: input.cost_priority,
|
|
286
|
+
speed_priority: input.speed_priority,
|
|
287
|
+
intelligence_priority: input.intelligence_priority,
|
|
288
|
+
system_prompt: input.system_prompt,
|
|
289
|
+
});
|
|
290
|
+
warnings.push(...(reviewResult.warnings || []));
|
|
291
|
+
artifacts.push(...(reviewResult.artifacts || []));
|
|
292
|
+
if (!reviewResult.ok) {
|
|
293
|
+
return {
|
|
294
|
+
ok: false,
|
|
295
|
+
errors: reviewResult.errors || ['code.function.explain.review failed'],
|
|
296
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
297
|
+
artifacts: artifacts.length > 0 ? artifacts : undefined,
|
|
298
|
+
metrics: {
|
|
299
|
+
elapsed_ms: Date.now() - startTime,
|
|
300
|
+
tool: TOOL_NAME,
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const reviewData = (reviewResult.data || {});
|
|
305
|
+
const acceptedCount = Number(reviewData?.apply?.accepted_count || 0);
|
|
306
|
+
const canRefreshExport = input.rerun_export &&
|
|
307
|
+
reviewData.review_status === 'sampled_and_applied' &&
|
|
308
|
+
acceptedCount > 0;
|
|
309
|
+
let exportSummary = {
|
|
310
|
+
attempted: false,
|
|
311
|
+
status: 'skipped',
|
|
312
|
+
selected_path: null,
|
|
313
|
+
export_tool: null,
|
|
314
|
+
export_root: null,
|
|
315
|
+
manifest_path: null,
|
|
316
|
+
build_validation_status: null,
|
|
317
|
+
harness_validation_status: null,
|
|
318
|
+
notes: [],
|
|
319
|
+
};
|
|
320
|
+
if (canRefreshExport) {
|
|
321
|
+
const exportResult = await reconstructWorkflowHandler({
|
|
322
|
+
sample_id: input.sample_id,
|
|
323
|
+
path: input.export_path,
|
|
324
|
+
topk: input.export_topk,
|
|
325
|
+
export_name: input.export_name,
|
|
326
|
+
validate_build: input.validate_build,
|
|
327
|
+
run_harness: input.run_harness,
|
|
328
|
+
compiler_path: input.compiler_path,
|
|
329
|
+
build_timeout_ms: input.build_timeout_ms,
|
|
330
|
+
run_timeout_ms: input.run_timeout_ms,
|
|
331
|
+
evidence_scope: input.evidence_scope,
|
|
332
|
+
evidence_session_tag: input.evidence_session_tag,
|
|
333
|
+
semantic_scope: input.semantic_scope === 'all' && input.session_tag ? 'session' : input.semantic_scope,
|
|
334
|
+
semantic_session_tag: input.semantic_session_tag || input.session_tag,
|
|
335
|
+
include_plan: input.include_plan,
|
|
336
|
+
include_obfuscation_fallback: input.include_obfuscation_fallback,
|
|
337
|
+
fallback_on_error: input.fallback_on_error,
|
|
338
|
+
allow_partial: input.allow_partial,
|
|
339
|
+
reuse_cached: input.reuse_cached,
|
|
340
|
+
});
|
|
341
|
+
warnings.push(...(exportResult.warnings || []));
|
|
342
|
+
artifacts.push(...(exportResult.artifacts || []));
|
|
343
|
+
if (!exportResult.ok) {
|
|
344
|
+
errors.push(...(exportResult.errors || ['workflow.reconstruct failed during export refresh']));
|
|
345
|
+
exportSummary = {
|
|
346
|
+
attempted: true,
|
|
347
|
+
status: 'failed',
|
|
348
|
+
selected_path: null,
|
|
349
|
+
export_tool: null,
|
|
350
|
+
export_root: null,
|
|
351
|
+
manifest_path: null,
|
|
352
|
+
build_validation_status: null,
|
|
353
|
+
harness_validation_status: null,
|
|
354
|
+
notes: ['Refresh export failed after function explanation apply.'],
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
const exportData = (exportResult.data || {});
|
|
359
|
+
exportSummary = {
|
|
360
|
+
attempted: true,
|
|
361
|
+
status: 'completed',
|
|
362
|
+
selected_path: exportData.selected_path || null,
|
|
363
|
+
export_tool: exportData.export?.tool || null,
|
|
364
|
+
export_root: exportData.export?.export_root || null,
|
|
365
|
+
manifest_path: exportData.export?.manifest_path || null,
|
|
366
|
+
build_validation_status: exportData.export?.build_validation_status || null,
|
|
367
|
+
harness_validation_status: exportData.export?.harness_validation_status || null,
|
|
368
|
+
notes: Array.isArray(exportData.notes) ? exportData.notes : [],
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
else if (input.rerun_export) {
|
|
373
|
+
exportSummary.notes.push(reviewData.review_status === 'prompt_contract_only'
|
|
374
|
+
? 'Refresh export skipped because no sampled explanations were applied yet.'
|
|
375
|
+
: 'Refresh export skipped because no explanation artifacts were applied.');
|
|
376
|
+
}
|
|
377
|
+
const nextSteps = [
|
|
378
|
+
...(Array.isArray(reviewData.next_steps) ? reviewData.next_steps : []),
|
|
379
|
+
...exportSummary.notes,
|
|
380
|
+
];
|
|
381
|
+
return {
|
|
382
|
+
ok: errors.length === 0,
|
|
383
|
+
data: {
|
|
384
|
+
sample_id: input.sample_id,
|
|
385
|
+
review: {
|
|
386
|
+
review_status: reviewData.review_status || 'unknown',
|
|
387
|
+
prompt_name: reviewData.prompt_name || 'reverse.function_explanation_review',
|
|
388
|
+
client: {
|
|
389
|
+
name: reviewData.client?.name || null,
|
|
390
|
+
version: reviewData.client?.version || null,
|
|
391
|
+
sampling_available: Boolean(reviewData.client?.sampling_available),
|
|
392
|
+
},
|
|
393
|
+
prepare: {
|
|
394
|
+
prepared_count: Number(reviewData.prepare?.prepared_count || 0),
|
|
395
|
+
artifact_id: reviewData.prepare?.artifact_id || null,
|
|
396
|
+
},
|
|
397
|
+
sampling: {
|
|
398
|
+
attempted: Boolean(reviewData.sampling?.attempted),
|
|
399
|
+
model: reviewData.sampling?.model || null,
|
|
400
|
+
stop_reason: reviewData.sampling?.stop_reason || null,
|
|
401
|
+
parsed_explanation_count: Number(reviewData.sampling?.parsed_explanation_count || 0),
|
|
402
|
+
},
|
|
403
|
+
apply: {
|
|
404
|
+
attempted: Boolean(reviewData.apply?.attempted),
|
|
405
|
+
accepted_count: acceptedCount,
|
|
406
|
+
rejected_count: Number(reviewData.apply?.rejected_count || 0),
|
|
407
|
+
artifact_id: reviewData.apply?.artifact_id || null,
|
|
408
|
+
},
|
|
409
|
+
confidence_policy: {
|
|
410
|
+
calibrated: Boolean(reviewData.confidence_policy?.calibrated),
|
|
411
|
+
explanation_scores_are_heuristic: reviewData.confidence_policy?.explanation_scores_are_heuristic !== false,
|
|
412
|
+
meaning: String(reviewData.confidence_policy?.meaning ||
|
|
413
|
+
'Explanation confidence remains heuristic and should be read as evidence support strength, not proof of source-equivalent recovery.'),
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
export: exportSummary,
|
|
417
|
+
next_steps: nextSteps,
|
|
418
|
+
},
|
|
419
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
420
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
421
|
+
artifacts: artifacts.length > 0 ? artifacts : undefined,
|
|
422
|
+
metrics: {
|
|
423
|
+
elapsed_ms: Date.now() - startTime,
|
|
424
|
+
tool: TOOL_NAME,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
catch (error) {
|
|
429
|
+
return {
|
|
430
|
+
ok: false,
|
|
431
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
432
|
+
metrics: {
|
|
433
|
+
elapsed_ms: Date.now() - startTime,
|
|
434
|
+
tool: TOOL_NAME,
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
//# sourceMappingURL=function-explanation-review.js.map
|