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,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* runtime.detect tool implementation
|
|
3
|
+
* Detects PE file runtime type (.NET, C++, etc.)
|
|
4
|
+
* Requirements: 6.1, 6.2, 6.3, 6.4
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { ToolDefinition, ToolArgs, WorkerResult } from '../types.js';
|
|
8
|
+
import type { WorkspaceManager } from '../workspace-manager.js';
|
|
9
|
+
import type { DatabaseManager } from '../database.js';
|
|
10
|
+
import type { CacheManager } from '../cache-manager.js';
|
|
11
|
+
/**
|
|
12
|
+
* Input schema for runtime.detect tool
|
|
13
|
+
* Requirements: 6.1
|
|
14
|
+
*/
|
|
15
|
+
export declare const RuntimeDetectInputSchema: z.ZodObject<{
|
|
16
|
+
sample_id: z.ZodString;
|
|
17
|
+
force_refresh: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
sample_id: string;
|
|
20
|
+
force_refresh: boolean;
|
|
21
|
+
}, {
|
|
22
|
+
sample_id: string;
|
|
23
|
+
force_refresh?: boolean | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
export type RuntimeDetectInput = z.infer<typeof RuntimeDetectInputSchema>;
|
|
26
|
+
/**
|
|
27
|
+
* Output schema for runtime.detect tool
|
|
28
|
+
* Requirements: 6.1, 6.2, 6.3, 6.4, 6.5
|
|
29
|
+
*/
|
|
30
|
+
export declare const RuntimeDetectOutputSchema: z.ZodObject<{
|
|
31
|
+
ok: z.ZodBoolean;
|
|
32
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
is_dotnet: z.ZodBoolean;
|
|
34
|
+
dotnet_version: z.ZodNullable<z.ZodString>;
|
|
35
|
+
target_framework: z.ZodNullable<z.ZodString>;
|
|
36
|
+
suspected: z.ZodArray<z.ZodObject<{
|
|
37
|
+
runtime: z.ZodString;
|
|
38
|
+
confidence: z.ZodNumber;
|
|
39
|
+
evidence: z.ZodArray<z.ZodString, "many">;
|
|
40
|
+
}, "strip", z.ZodTypeAny, {
|
|
41
|
+
confidence: number;
|
|
42
|
+
evidence: string[];
|
|
43
|
+
runtime: string;
|
|
44
|
+
}, {
|
|
45
|
+
confidence: number;
|
|
46
|
+
evidence: string[];
|
|
47
|
+
runtime: string;
|
|
48
|
+
}>, "many">;
|
|
49
|
+
import_dlls: z.ZodArray<z.ZodString, "many">;
|
|
50
|
+
}, "strip", z.ZodTypeAny, {
|
|
51
|
+
is_dotnet: boolean;
|
|
52
|
+
dotnet_version: string | null;
|
|
53
|
+
target_framework: string | null;
|
|
54
|
+
suspected: {
|
|
55
|
+
confidence: number;
|
|
56
|
+
evidence: string[];
|
|
57
|
+
runtime: string;
|
|
58
|
+
}[];
|
|
59
|
+
import_dlls: string[];
|
|
60
|
+
}, {
|
|
61
|
+
is_dotnet: boolean;
|
|
62
|
+
dotnet_version: string | null;
|
|
63
|
+
target_framework: string | null;
|
|
64
|
+
suspected: {
|
|
65
|
+
confidence: number;
|
|
66
|
+
evidence: string[];
|
|
67
|
+
runtime: string;
|
|
68
|
+
}[];
|
|
69
|
+
import_dlls: string[];
|
|
70
|
+
}>>;
|
|
71
|
+
warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
72
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
73
|
+
artifacts: z.ZodOptional<z.ZodArray<z.ZodAny, "many">>;
|
|
74
|
+
metrics: z.ZodOptional<z.ZodObject<{
|
|
75
|
+
elapsed_ms: z.ZodNumber;
|
|
76
|
+
tool: z.ZodString;
|
|
77
|
+
}, "strip", z.ZodTypeAny, {
|
|
78
|
+
elapsed_ms: number;
|
|
79
|
+
tool: string;
|
|
80
|
+
}, {
|
|
81
|
+
elapsed_ms: number;
|
|
82
|
+
tool: string;
|
|
83
|
+
}>>;
|
|
84
|
+
}, "strip", z.ZodTypeAny, {
|
|
85
|
+
ok: boolean;
|
|
86
|
+
metrics?: {
|
|
87
|
+
elapsed_ms: number;
|
|
88
|
+
tool: string;
|
|
89
|
+
} | undefined;
|
|
90
|
+
data?: {
|
|
91
|
+
is_dotnet: boolean;
|
|
92
|
+
dotnet_version: string | null;
|
|
93
|
+
target_framework: string | null;
|
|
94
|
+
suspected: {
|
|
95
|
+
confidence: number;
|
|
96
|
+
evidence: string[];
|
|
97
|
+
runtime: string;
|
|
98
|
+
}[];
|
|
99
|
+
import_dlls: string[];
|
|
100
|
+
} | undefined;
|
|
101
|
+
warnings?: string[] | undefined;
|
|
102
|
+
errors?: string[] | undefined;
|
|
103
|
+
artifacts?: any[] | undefined;
|
|
104
|
+
}, {
|
|
105
|
+
ok: boolean;
|
|
106
|
+
metrics?: {
|
|
107
|
+
elapsed_ms: number;
|
|
108
|
+
tool: string;
|
|
109
|
+
} | undefined;
|
|
110
|
+
data?: {
|
|
111
|
+
is_dotnet: boolean;
|
|
112
|
+
dotnet_version: string | null;
|
|
113
|
+
target_framework: string | null;
|
|
114
|
+
suspected: {
|
|
115
|
+
confidence: number;
|
|
116
|
+
evidence: string[];
|
|
117
|
+
runtime: string;
|
|
118
|
+
}[];
|
|
119
|
+
import_dlls: string[];
|
|
120
|
+
} | undefined;
|
|
121
|
+
warnings?: string[] | undefined;
|
|
122
|
+
errors?: string[] | undefined;
|
|
123
|
+
artifacts?: any[] | undefined;
|
|
124
|
+
}>;
|
|
125
|
+
export type RuntimeDetectOutput = z.infer<typeof RuntimeDetectOutputSchema>;
|
|
126
|
+
/**
|
|
127
|
+
* Tool definition for runtime.detect
|
|
128
|
+
*/
|
|
129
|
+
export declare const runtimeDetectToolDefinition: ToolDefinition;
|
|
130
|
+
/**
|
|
131
|
+
* Create runtime.detect tool handler
|
|
132
|
+
* Requirements: 6.1, 6.2, 6.3, 6.4
|
|
133
|
+
*/
|
|
134
|
+
export declare function createRuntimeDetectHandler(workspaceManager: WorkspaceManager, database: DatabaseManager, cacheManager: CacheManager): (args: ToolArgs) => Promise<WorkerResult>;
|
|
135
|
+
//# sourceMappingURL=runtime-detect.d.ts.map
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* runtime.detect tool implementation
|
|
3
|
+
* Detects PE file runtime type (.NET, C++, etc.)
|
|
4
|
+
* Requirements: 6.1, 6.2, 6.3, 6.4
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
10
|
+
import { generateCacheKey } from '../cache-manager.js';
|
|
11
|
+
import { resolvePackagePath } from '../runtime-paths.js';
|
|
12
|
+
import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
const TOOL_NAME = 'runtime.detect';
|
|
17
|
+
const TOOL_VERSION = '1.0.0';
|
|
18
|
+
const CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Input/Output Schemas
|
|
21
|
+
// ============================================================================
|
|
22
|
+
/**
|
|
23
|
+
* Input schema for runtime.detect tool
|
|
24
|
+
* Requirements: 6.1
|
|
25
|
+
*/
|
|
26
|
+
export const RuntimeDetectInputSchema = z.object({
|
|
27
|
+
sample_id: z.string().describe('Sample ID (format: sha256:<hex>)'),
|
|
28
|
+
force_refresh: z
|
|
29
|
+
.boolean()
|
|
30
|
+
.optional()
|
|
31
|
+
.default(false)
|
|
32
|
+
.describe('Bypass cache lookup and recompute from source sample'),
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Output schema for runtime.detect tool
|
|
36
|
+
* Requirements: 6.1, 6.2, 6.3, 6.4, 6.5
|
|
37
|
+
*/
|
|
38
|
+
export const RuntimeDetectOutputSchema = z.object({
|
|
39
|
+
ok: z.boolean(),
|
|
40
|
+
data: z.object({
|
|
41
|
+
is_dotnet: z.boolean(),
|
|
42
|
+
dotnet_version: z.string().nullable(),
|
|
43
|
+
target_framework: z.string().nullable(),
|
|
44
|
+
suspected: z.array(z.object({
|
|
45
|
+
runtime: z.string(),
|
|
46
|
+
confidence: z.number(),
|
|
47
|
+
evidence: z.array(z.string()),
|
|
48
|
+
})),
|
|
49
|
+
import_dlls: z.array(z.string()),
|
|
50
|
+
}).optional(),
|
|
51
|
+
warnings: z.array(z.string()).optional(),
|
|
52
|
+
errors: z.array(z.string()).optional(),
|
|
53
|
+
artifacts: z.array(z.any()).optional(),
|
|
54
|
+
metrics: z.object({
|
|
55
|
+
elapsed_ms: z.number(),
|
|
56
|
+
tool: z.string(),
|
|
57
|
+
}).optional(),
|
|
58
|
+
});
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Tool Definition
|
|
61
|
+
// ============================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Tool definition for runtime.detect
|
|
64
|
+
*/
|
|
65
|
+
export const runtimeDetectToolDefinition = {
|
|
66
|
+
name: TOOL_NAME,
|
|
67
|
+
description: '自动检测 PE 文件的运行时类型(.NET、C++、Go 等),解析 CLR 头部并返回置信度分数',
|
|
68
|
+
inputSchema: RuntimeDetectInputSchema,
|
|
69
|
+
outputSchema: RuntimeDetectOutputSchema,
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Spawn Python Static Worker and communicate via stdin/stdout JSON protocol
|
|
73
|
+
*
|
|
74
|
+
* Requirements: Worker communication
|
|
75
|
+
*
|
|
76
|
+
* @param request - Worker request object
|
|
77
|
+
* @returns Worker response object
|
|
78
|
+
*/
|
|
79
|
+
async function callStaticWorker(request) {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
// Get Python worker path
|
|
82
|
+
const workerPath = resolvePackagePath('workers', 'static_worker.py');
|
|
83
|
+
// Spawn Python process
|
|
84
|
+
const pythonCommand = process.platform === 'win32' ? 'python' : 'python3';
|
|
85
|
+
const pythonProcess = spawn(pythonCommand, [workerPath], {
|
|
86
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
87
|
+
});
|
|
88
|
+
let stdout = '';
|
|
89
|
+
let stderr = '';
|
|
90
|
+
// Collect stdout
|
|
91
|
+
pythonProcess.stdout.on('data', (data) => {
|
|
92
|
+
stdout += data.toString();
|
|
93
|
+
});
|
|
94
|
+
// Collect stderr
|
|
95
|
+
pythonProcess.stderr.on('data', (data) => {
|
|
96
|
+
stderr += data.toString();
|
|
97
|
+
});
|
|
98
|
+
// Handle process exit
|
|
99
|
+
pythonProcess.on('close', (code) => {
|
|
100
|
+
if (code !== 0) {
|
|
101
|
+
reject(new Error(`Python worker exited with code ${code}. stderr: ${stderr}`));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Parse response from stdout
|
|
105
|
+
try {
|
|
106
|
+
const lines = stdout.trim().split('\n');
|
|
107
|
+
const lastLine = lines[lines.length - 1];
|
|
108
|
+
const response = JSON.parse(lastLine);
|
|
109
|
+
resolve(response);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
reject(new Error(`Failed to parse worker response: ${error.message}. stdout: ${stdout}`));
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
// Handle process error
|
|
116
|
+
pythonProcess.on('error', (error) => {
|
|
117
|
+
reject(new Error(`Failed to spawn Python worker: ${error.message}`));
|
|
118
|
+
});
|
|
119
|
+
// Send request to worker via stdin
|
|
120
|
+
try {
|
|
121
|
+
pythonProcess.stdin.write(JSON.stringify(request) + '\n');
|
|
122
|
+
pythonProcess.stdin.end();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
reject(new Error(`Failed to write to worker stdin: ${error.message}`));
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Tool Handler
|
|
131
|
+
// ============================================================================
|
|
132
|
+
/**
|
|
133
|
+
* Create runtime.detect tool handler
|
|
134
|
+
* Requirements: 6.1, 6.2, 6.3, 6.4
|
|
135
|
+
*/
|
|
136
|
+
export function createRuntimeDetectHandler(workspaceManager, database, cacheManager) {
|
|
137
|
+
return async (args) => {
|
|
138
|
+
const input = args;
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
try {
|
|
141
|
+
// 1. Generate cache key
|
|
142
|
+
const sample = database.findSample(input.sample_id);
|
|
143
|
+
if (!sample) {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
errors: [`Sample not found: ${input.sample_id}`],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const cacheKey = generateCacheKey({
|
|
150
|
+
sampleSha256: sample.sha256,
|
|
151
|
+
toolName: TOOL_NAME,
|
|
152
|
+
toolVersion: TOOL_VERSION,
|
|
153
|
+
args: {},
|
|
154
|
+
});
|
|
155
|
+
// 2. Check cache
|
|
156
|
+
if (!input.force_refresh) {
|
|
157
|
+
const cachedLookup = await lookupCachedResult(cacheManager, cacheKey);
|
|
158
|
+
if (cachedLookup) {
|
|
159
|
+
return {
|
|
160
|
+
ok: true,
|
|
161
|
+
data: cachedLookup.data,
|
|
162
|
+
warnings: ['Result from cache', formatCacheWarning(cachedLookup.metadata)],
|
|
163
|
+
metrics: {
|
|
164
|
+
elapsed_ms: Date.now() - startTime,
|
|
165
|
+
tool: TOOL_NAME,
|
|
166
|
+
cached: true,
|
|
167
|
+
cache_key: cachedLookup.metadata.key,
|
|
168
|
+
cache_tier: cachedLookup.metadata.tier,
|
|
169
|
+
cache_created_at: cachedLookup.metadata.createdAt,
|
|
170
|
+
cache_expires_at: cachedLookup.metadata.expiresAt,
|
|
171
|
+
cache_hit_at: cachedLookup.metadata.fetchedAt,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// 3. Get sample path from workspace
|
|
177
|
+
const workspace = await workspaceManager.getWorkspace(input.sample_id);
|
|
178
|
+
// Find the sample file in the original directory
|
|
179
|
+
const fs = await import('fs/promises');
|
|
180
|
+
const files = await fs.readdir(workspace.original);
|
|
181
|
+
if (files.length === 0) {
|
|
182
|
+
return {
|
|
183
|
+
ok: false,
|
|
184
|
+
errors: ['Sample file not found in workspace'],
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
const samplePath = path.join(workspace.original, files[0]);
|
|
188
|
+
// 4. Prepare worker request
|
|
189
|
+
const workerRequest = {
|
|
190
|
+
job_id: uuidv4(),
|
|
191
|
+
tool: TOOL_NAME,
|
|
192
|
+
sample: {
|
|
193
|
+
sample_id: input.sample_id,
|
|
194
|
+
path: samplePath,
|
|
195
|
+
},
|
|
196
|
+
args: {},
|
|
197
|
+
context: {
|
|
198
|
+
request_time_utc: new Date().toISOString(),
|
|
199
|
+
policy: {
|
|
200
|
+
allow_dynamic: false,
|
|
201
|
+
allow_network: false,
|
|
202
|
+
},
|
|
203
|
+
versions: {
|
|
204
|
+
tool_version: TOOL_VERSION,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
// 5. Call Static Worker
|
|
209
|
+
// Requirements: 6.1, 6.2, 6.3, 6.4
|
|
210
|
+
const workerResponse = await callStaticWorker(workerRequest);
|
|
211
|
+
if (!workerResponse.ok) {
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
errors: workerResponse.errors,
|
|
215
|
+
warnings: workerResponse.warnings,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// 6. Cache result
|
|
219
|
+
await cacheManager.setCachedResult(cacheKey, workerResponse.data, CACHE_TTL_MS);
|
|
220
|
+
// 7. Return result
|
|
221
|
+
return {
|
|
222
|
+
ok: true,
|
|
223
|
+
data: workerResponse.data,
|
|
224
|
+
warnings: input.force_refresh
|
|
225
|
+
? ['force_refresh=true; bypassed cache lookup', ...(workerResponse.warnings || [])]
|
|
226
|
+
: workerResponse.warnings,
|
|
227
|
+
errors: workerResponse.errors,
|
|
228
|
+
artifacts: workerResponse.artifacts,
|
|
229
|
+
metrics: {
|
|
230
|
+
...workerResponse.metrics,
|
|
231
|
+
elapsed_ms: Date.now() - startTime,
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
return {
|
|
237
|
+
ok: false,
|
|
238
|
+
errors: [error.message],
|
|
239
|
+
metrics: {
|
|
240
|
+
elapsed_ms: Date.now() - startTime,
|
|
241
|
+
tool: TOOL_NAME,
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=runtime-detect.js.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sample.ingest tool implementation
|
|
3
|
+
* Uploads and registers new samples to the system
|
|
4
|
+
* Requirements: 1.1, 1.2, 1.3, 1.4, 1.5
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { ToolDefinition, ToolArgs, WorkerResult } from '../types.js';
|
|
8
|
+
import type { WorkspaceManager } from '../workspace-manager.js';
|
|
9
|
+
import type { DatabaseManager } from '../database.js';
|
|
10
|
+
import type { PolicyGuard } from '../policy-guard.js';
|
|
11
|
+
/**
|
|
12
|
+
* Input schema for sample.ingest tool
|
|
13
|
+
* Requirements: 1.1
|
|
14
|
+
*/
|
|
15
|
+
export declare const SampleIngestInputSchema: z.ZodEffects<z.ZodObject<{
|
|
16
|
+
path: z.ZodOptional<z.ZodString>;
|
|
17
|
+
bytes_b64: z.ZodOptional<z.ZodString>;
|
|
18
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
19
|
+
source: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
path?: string | undefined;
|
|
22
|
+
source?: string | undefined;
|
|
23
|
+
bytes_b64?: string | undefined;
|
|
24
|
+
filename?: string | undefined;
|
|
25
|
+
}, {
|
|
26
|
+
path?: string | undefined;
|
|
27
|
+
source?: string | undefined;
|
|
28
|
+
bytes_b64?: string | undefined;
|
|
29
|
+
filename?: string | undefined;
|
|
30
|
+
}>, {
|
|
31
|
+
path?: string | undefined;
|
|
32
|
+
source?: string | undefined;
|
|
33
|
+
bytes_b64?: string | undefined;
|
|
34
|
+
filename?: string | undefined;
|
|
35
|
+
}, {
|
|
36
|
+
path?: string | undefined;
|
|
37
|
+
source?: string | undefined;
|
|
38
|
+
bytes_b64?: string | undefined;
|
|
39
|
+
filename?: string | undefined;
|
|
40
|
+
}>;
|
|
41
|
+
export type SampleIngestInput = z.infer<typeof SampleIngestInputSchema>;
|
|
42
|
+
/**
|
|
43
|
+
* Output schema for sample.ingest tool
|
|
44
|
+
* Requirements: 1.5
|
|
45
|
+
*/
|
|
46
|
+
export declare const SampleIngestOutputSchema: z.ZodObject<{
|
|
47
|
+
ok: z.ZodBoolean;
|
|
48
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
49
|
+
sample_id: z.ZodString;
|
|
50
|
+
size: z.ZodNumber;
|
|
51
|
+
file_type: z.ZodOptional<z.ZodString>;
|
|
52
|
+
existed: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
}, "strip", z.ZodTypeAny, {
|
|
54
|
+
sample_id: string;
|
|
55
|
+
size: number;
|
|
56
|
+
file_type?: string | undefined;
|
|
57
|
+
existed?: boolean | undefined;
|
|
58
|
+
}, {
|
|
59
|
+
sample_id: string;
|
|
60
|
+
size: number;
|
|
61
|
+
file_type?: string | undefined;
|
|
62
|
+
existed?: boolean | undefined;
|
|
63
|
+
}>>;
|
|
64
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
65
|
+
}, "strip", z.ZodTypeAny, {
|
|
66
|
+
ok: boolean;
|
|
67
|
+
data?: {
|
|
68
|
+
sample_id: string;
|
|
69
|
+
size: number;
|
|
70
|
+
file_type?: string | undefined;
|
|
71
|
+
existed?: boolean | undefined;
|
|
72
|
+
} | undefined;
|
|
73
|
+
errors?: string[] | undefined;
|
|
74
|
+
}, {
|
|
75
|
+
ok: boolean;
|
|
76
|
+
data?: {
|
|
77
|
+
sample_id: string;
|
|
78
|
+
size: number;
|
|
79
|
+
file_type?: string | undefined;
|
|
80
|
+
existed?: boolean | undefined;
|
|
81
|
+
} | undefined;
|
|
82
|
+
errors?: string[] | undefined;
|
|
83
|
+
}>;
|
|
84
|
+
export type SampleIngestOutput = z.infer<typeof SampleIngestOutputSchema>;
|
|
85
|
+
/**
|
|
86
|
+
* Tool definition for sample.ingest
|
|
87
|
+
*/
|
|
88
|
+
export declare const sampleIngestToolDefinition: ToolDefinition;
|
|
89
|
+
/**
|
|
90
|
+
* Create sample.ingest tool handler
|
|
91
|
+
* Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
|
|
92
|
+
*/
|
|
93
|
+
export declare function createSampleIngestHandler(workspaceManager: WorkspaceManager, database: DatabaseManager, policyGuard: PolicyGuard): (args: ToolArgs) => Promise<WorkerResult>;
|
|
94
|
+
//# sourceMappingURL=sample-ingest.d.ts.map
|