@mcpilotx/intentorch 0.5.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/LICENSE +201 -0
- package/README.md +545 -0
- package/dist/ai/ai.d.ts +205 -0
- package/dist/ai/ai.js +1200 -0
- package/dist/ai/cloud-intent-engine.d.ts +270 -0
- package/dist/ai/cloud-intent-engine.js +956 -0
- package/dist/ai/command.d.ts +59 -0
- package/dist/ai/command.js +285 -0
- package/dist/ai/config.d.ts +66 -0
- package/dist/ai/config.js +211 -0
- package/dist/ai/enhanced-intent.d.ts +17 -0
- package/dist/ai/enhanced-intent.js +32 -0
- package/dist/ai/index.d.ts +29 -0
- package/dist/ai/index.js +44 -0
- package/dist/ai/intent.d.ts +16 -0
- package/dist/ai/intent.js +30 -0
- package/dist/core/ai-config.d.ts +25 -0
- package/dist/core/ai-config.js +326 -0
- package/dist/core/config-manager.d.ts +36 -0
- package/dist/core/config-manager.js +400 -0
- package/dist/core/config-validator.d.ts +9 -0
- package/dist/core/config-validator.js +184 -0
- package/dist/core/constants.d.ts +34 -0
- package/dist/core/constants.js +37 -0
- package/dist/core/error-ai.d.ts +23 -0
- package/dist/core/error-ai.js +217 -0
- package/dist/core/error-handler.d.ts +197 -0
- package/dist/core/error-handler.js +467 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +17 -0
- package/dist/core/logger.d.ts +27 -0
- package/dist/core/logger.js +108 -0
- package/dist/core/performance-monitor.d.ts +74 -0
- package/dist/core/performance-monitor.js +260 -0
- package/dist/core/providers.d.ts +36 -0
- package/dist/core/providers.js +304 -0
- package/dist/core/retry-manager.d.ts +41 -0
- package/dist/core/retry-manager.js +204 -0
- package/dist/core/types.d.ts +155 -0
- package/dist/core/types.js +2 -0
- package/dist/daemon/index.d.ts +10 -0
- package/dist/daemon/index.js +15 -0
- package/dist/daemon/intent-engine.d.ts +22 -0
- package/dist/daemon/intent-engine.js +50 -0
- package/dist/daemon/orchestrator.d.ts +24 -0
- package/dist/daemon/orchestrator.js +100 -0
- package/dist/daemon/pm.d.ts +33 -0
- package/dist/daemon/pm.js +127 -0
- package/dist/daemon/process.d.ts +11 -0
- package/dist/daemon/process.js +49 -0
- package/dist/daemon/server.d.ts +17 -0
- package/dist/daemon/server.js +435 -0
- package/dist/daemon/service.d.ts +36 -0
- package/dist/daemon/service.js +278 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +36 -0
- package/dist/mcp/client.d.ts +51 -0
- package/dist/mcp/client.js +276 -0
- package/dist/mcp/index.d.ts +162 -0
- package/dist/mcp/index.js +199 -0
- package/dist/mcp/tool-registry.d.ts +71 -0
- package/dist/mcp/tool-registry.js +308 -0
- package/dist/mcp/transport.d.ts +83 -0
- package/dist/mcp/transport.js +515 -0
- package/dist/mcp/types.d.ts +136 -0
- package/dist/mcp/types.js +31 -0
- package/dist/runtime/adapter-advanced.d.ts +184 -0
- package/dist/runtime/adapter-advanced.js +160 -0
- package/dist/runtime/adapter.d.ts +9 -0
- package/dist/runtime/adapter.js +2 -0
- package/dist/runtime/detector-advanced.d.ts +59 -0
- package/dist/runtime/detector-advanced.js +487 -0
- package/dist/runtime/detector.d.ts +5 -0
- package/dist/runtime/detector.js +56 -0
- package/dist/runtime/docker-adapter.d.ts +18 -0
- package/dist/runtime/docker-adapter.js +170 -0
- package/dist/runtime/docker.d.ts +17 -0
- package/dist/runtime/docker.js +71 -0
- package/dist/runtime/executable-analyzer.d.ts +56 -0
- package/dist/runtime/executable-analyzer.js +391 -0
- package/dist/runtime/go-adapter.d.ts +19 -0
- package/dist/runtime/go-adapter.js +190 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.js +10 -0
- package/dist/runtime/node-adapter.d.ts +10 -0
- package/dist/runtime/node-adapter.js +23 -0
- package/dist/runtime/node.d.ts +20 -0
- package/dist/runtime/node.js +86 -0
- package/dist/runtime/python-adapter.d.ts +11 -0
- package/dist/runtime/python-adapter.js +102 -0
- package/dist/runtime/python.d.ts +17 -0
- package/dist/runtime/python.js +72 -0
- package/dist/runtime/rust-adapter.d.ts +21 -0
- package/dist/runtime/rust-adapter.js +267 -0
- package/dist/sdk.d.ts +500 -0
- package/dist/sdk.js +904 -0
- package/docs/README.ZH_CN.md +545 -0
- package/docs/api.md +888 -0
- package/docs/architecture.md +731 -0
- package/docs/development.md +744 -0
- package/package.json +112 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { RuntimeDetector } from './detector.js';
|
|
4
|
+
import { ExecutableAnalyzer } from './executable-analyzer.js';
|
|
5
|
+
import { logger } from '../core/logger.js';
|
|
6
|
+
export class EnhancedRuntimeDetector {
|
|
7
|
+
/**
|
|
8
|
+
* Run both old and new detectors in parallel, select the best result
|
|
9
|
+
*/
|
|
10
|
+
static async detect(servicePath) {
|
|
11
|
+
if (!fs.existsSync(servicePath)) {
|
|
12
|
+
throw new Error(`Service path does not exist: ${servicePath}`);
|
|
13
|
+
}
|
|
14
|
+
logger.info(`Detecting runtime for: ${servicePath}`);
|
|
15
|
+
// Run detectors in parallel
|
|
16
|
+
const [legacyResult, enhancedResult] = await Promise.all([
|
|
17
|
+
this.runLegacyDetector(servicePath),
|
|
18
|
+
this.runEnhancedDetection(servicePath),
|
|
19
|
+
]);
|
|
20
|
+
// Record detection results
|
|
21
|
+
logger.debug('Detection results:', {
|
|
22
|
+
legacy: { runtime: legacyResult.runtime, confidence: legacyResult.confidence },
|
|
23
|
+
enhanced: { runtime: enhancedResult.runtime, confidence: enhancedResult.confidence },
|
|
24
|
+
});
|
|
25
|
+
// Select best result (based on confidence)
|
|
26
|
+
let finalResult;
|
|
27
|
+
if (enhancedResult.confidence >= 0.7) {
|
|
28
|
+
// Enhanced detector has high confidence, use its result
|
|
29
|
+
finalResult = enhancedResult;
|
|
30
|
+
}
|
|
31
|
+
else if (legacyResult.confidence >= 0.5) {
|
|
32
|
+
// Traditional detector has some confidence, but add warning
|
|
33
|
+
finalResult = {
|
|
34
|
+
...legacyResult,
|
|
35
|
+
source: 'legacy',
|
|
36
|
+
warning: 'Using traditional detector, suggest manual verification or use --runtime parameter to explicitly specify',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Both have low confidence, require user to explicitly specify
|
|
41
|
+
finalResult = {
|
|
42
|
+
runtime: 'binary', // Safe default value
|
|
43
|
+
confidence: Math.max(legacyResult.confidence, enhancedResult.confidence),
|
|
44
|
+
evidence: {
|
|
45
|
+
fileExtensions: {
|
|
46
|
+
extensions: [],
|
|
47
|
+
confidence: 0,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
source: 'enhanced',
|
|
51
|
+
warning: this.generateLowConfidenceWarning(legacyResult, enhancedResult),
|
|
52
|
+
suggestions: this.generateRuntimeSuggestions(servicePath),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
logger.info(`Final detection result: ${finalResult.runtime} (confidence: ${finalResult.confidence.toFixed(2)}, source: ${finalResult.source})`);
|
|
56
|
+
if (finalResult.warning) {
|
|
57
|
+
logger.warn(finalResult.warning);
|
|
58
|
+
}
|
|
59
|
+
return finalResult;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Run traditional detector
|
|
63
|
+
*/
|
|
64
|
+
static runLegacyDetector(servicePath) {
|
|
65
|
+
try {
|
|
66
|
+
const runtime = RuntimeDetector.detect(servicePath);
|
|
67
|
+
// Traditional detector confidence is based on detection method reliability
|
|
68
|
+
let confidence = 0.5; // Base confidence
|
|
69
|
+
const evidence = {
|
|
70
|
+
fileExtensions: {
|
|
71
|
+
extensions: [],
|
|
72
|
+
confidence: 0.3,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
// Adjust confidence based on detected runtime type
|
|
76
|
+
switch (runtime) {
|
|
77
|
+
case 'docker':
|
|
78
|
+
confidence = 0.8; // Dockerfile is usually clear
|
|
79
|
+
evidence.projectFiles = {
|
|
80
|
+
files: ['Dockerfile'],
|
|
81
|
+
confidence: 0.8,
|
|
82
|
+
};
|
|
83
|
+
break;
|
|
84
|
+
case 'node':
|
|
85
|
+
confidence = 0.7; // package.json is usually clear
|
|
86
|
+
evidence.projectFiles = {
|
|
87
|
+
files: ['package.json'],
|
|
88
|
+
confidence: 0.7,
|
|
89
|
+
};
|
|
90
|
+
break;
|
|
91
|
+
case 'go':
|
|
92
|
+
confidence = 0.7; // go.mod is usually clear
|
|
93
|
+
evidence.projectFiles = {
|
|
94
|
+
files: ['go.mod'],
|
|
95
|
+
confidence: 0.7,
|
|
96
|
+
};
|
|
97
|
+
break;
|
|
98
|
+
case 'rust':
|
|
99
|
+
confidence = 0.7; // Cargo.toml is usually clear
|
|
100
|
+
evidence.projectFiles = {
|
|
101
|
+
files: ['Cargo.toml'],
|
|
102
|
+
confidence: 0.7,
|
|
103
|
+
};
|
|
104
|
+
break;
|
|
105
|
+
case 'python':
|
|
106
|
+
confidence = 0.6; // May have multiple configuration files
|
|
107
|
+
evidence.projectFiles = {
|
|
108
|
+
files: this.findPythonConfigFiles(servicePath),
|
|
109
|
+
confidence: 0.6,
|
|
110
|
+
};
|
|
111
|
+
break;
|
|
112
|
+
case 'java':
|
|
113
|
+
confidence = 0.6; // May have multiple build systems
|
|
114
|
+
evidence.projectFiles = {
|
|
115
|
+
files: this.findJavaConfigFiles(servicePath),
|
|
116
|
+
confidence: 0.6,
|
|
117
|
+
};
|
|
118
|
+
break;
|
|
119
|
+
default:
|
|
120
|
+
// binary or other, lower confidence
|
|
121
|
+
confidence = 0.4;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
runtime,
|
|
125
|
+
confidence,
|
|
126
|
+
evidence,
|
|
127
|
+
source: 'legacy',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
logger.error(`Legacy detector failed: ${error.message}`);
|
|
132
|
+
return {
|
|
133
|
+
runtime: 'binary',
|
|
134
|
+
confidence: 0.1,
|
|
135
|
+
evidence: {},
|
|
136
|
+
source: 'legacy',
|
|
137
|
+
warning: `Traditional detector failed: ${error.message}`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Run enhanced detection
|
|
143
|
+
*/
|
|
144
|
+
static runEnhancedDetection(servicePath) {
|
|
145
|
+
try {
|
|
146
|
+
const evidence = {};
|
|
147
|
+
let totalWeight = 0;
|
|
148
|
+
let weightedSum = 0;
|
|
149
|
+
// 1. Executable file analysis (weight: 0.4)
|
|
150
|
+
const executableAnalysis = this.analyzeExecutables(servicePath);
|
|
151
|
+
if (executableAnalysis) {
|
|
152
|
+
evidence.executableAnalysis = executableAnalysis;
|
|
153
|
+
weightedSum += 0.4 * executableAnalysis.confidence;
|
|
154
|
+
totalWeight += 0.4;
|
|
155
|
+
}
|
|
156
|
+
// 2. Project configuration file analysis (weight: 0.3)
|
|
157
|
+
const projectFilesAnalysis = this.analyzeProjectFiles(servicePath);
|
|
158
|
+
if (projectFilesAnalysis) {
|
|
159
|
+
evidence.projectFiles = projectFilesAnalysis;
|
|
160
|
+
weightedSum += 0.3 * projectFilesAnalysis.confidence;
|
|
161
|
+
totalWeight += 0.3;
|
|
162
|
+
}
|
|
163
|
+
// 3. File statistics (weight: 0.2)
|
|
164
|
+
const fileStatsAnalysis = this.analyzeFileStatistics(servicePath);
|
|
165
|
+
if (fileStatsAnalysis) {
|
|
166
|
+
evidence.fileStatistics = fileStatsAnalysis;
|
|
167
|
+
weightedSum += 0.2 * fileStatsAnalysis.confidence;
|
|
168
|
+
totalWeight += 0.2;
|
|
169
|
+
}
|
|
170
|
+
// 4. File extensions (weight: 0.1)
|
|
171
|
+
const extensionAnalysis = this.analyzeFileExtensions(servicePath);
|
|
172
|
+
if (extensionAnalysis) {
|
|
173
|
+
evidence.fileExtensions = extensionAnalysis;
|
|
174
|
+
weightedSum += 0.1 * extensionAnalysis.confidence;
|
|
175
|
+
totalWeight += 0.1;
|
|
176
|
+
}
|
|
177
|
+
// Calculate final confidence and runtime type
|
|
178
|
+
const confidence = totalWeight > 0 ? weightedSum / totalWeight : 0;
|
|
179
|
+
const runtime = this.determineRuntimeFromEvidence(evidence, confidence);
|
|
180
|
+
// If confidence is too low, add warning
|
|
181
|
+
let warning;
|
|
182
|
+
if (confidence < 0.4) {
|
|
183
|
+
warning = 'Detection confidence too low, suggest using --runtime parameter to explicitly specify';
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
runtime,
|
|
187
|
+
confidence,
|
|
188
|
+
evidence,
|
|
189
|
+
source: 'enhanced',
|
|
190
|
+
warning,
|
|
191
|
+
suggestions: this.generateRuntimeSuggestions(servicePath),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
logger.error(`Enhanced detector failed: ${error.message}`);
|
|
196
|
+
return {
|
|
197
|
+
runtime: 'binary',
|
|
198
|
+
confidence: 0.1,
|
|
199
|
+
evidence: {},
|
|
200
|
+
source: 'enhanced',
|
|
201
|
+
warning: `Enhanced detector failed: ${error.message}`,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Analyze executable files
|
|
207
|
+
*/
|
|
208
|
+
static analyzeExecutables(servicePath) {
|
|
209
|
+
const executables = ExecutableAnalyzer.findExecutables(servicePath);
|
|
210
|
+
if (executables.length === 0) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
// Analyze main executable file
|
|
214
|
+
const primaryExecutable = ExecutableAnalyzer.getPrimaryExecutable(servicePath);
|
|
215
|
+
if (!primaryExecutable) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const analysis = ExecutableAnalyzer.analyze(primaryExecutable);
|
|
219
|
+
if (!analysis) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
type: analysis.type,
|
|
224
|
+
confidence: analysis.confidence,
|
|
225
|
+
details: analysis.details,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Analyze project configuration files
|
|
230
|
+
*/
|
|
231
|
+
static analyzeProjectFiles(servicePath) {
|
|
232
|
+
const configFiles = [];
|
|
233
|
+
// Check various configuration files
|
|
234
|
+
const configPatterns = [
|
|
235
|
+
'Dockerfile', 'docker-compose.yml', 'docker-compose.yaml',
|
|
236
|
+
'package.json', 'package-lock.json', 'yarn.lock', 'bun.lock',
|
|
237
|
+
'go.mod', 'go.sum',
|
|
238
|
+
'Cargo.toml', 'Cargo.lock',
|
|
239
|
+
'requirements.txt', 'setup.py', 'pyproject.toml', 'Pipfile',
|
|
240
|
+
'pom.xml', 'build.gradle', 'build.gradle.kts',
|
|
241
|
+
'Makefile', 'CMakeLists.txt',
|
|
242
|
+
'mcp-service.json', // Custom configuration file
|
|
243
|
+
];
|
|
244
|
+
for (const pattern of configPatterns) {
|
|
245
|
+
const filePath = path.join(servicePath, pattern);
|
|
246
|
+
if (fs.existsSync(filePath)) {
|
|
247
|
+
configFiles.push(pattern);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (configFiles.length === 0) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
// Calculate confidence based on quantity and quality of configuration files
|
|
254
|
+
let confidence = 0.5;
|
|
255
|
+
if (configFiles.includes('Dockerfile')) {
|
|
256
|
+
confidence = 0.9; // Dockerfile is very clear
|
|
257
|
+
}
|
|
258
|
+
else if (configFiles.includes('package.json')) {
|
|
259
|
+
confidence = 0.8; // Node.js project clear
|
|
260
|
+
}
|
|
261
|
+
else if (configFiles.includes('go.mod')) {
|
|
262
|
+
confidence = 0.8; // Go project clear
|
|
263
|
+
}
|
|
264
|
+
else if (configFiles.includes('Cargo.toml')) {
|
|
265
|
+
confidence = 0.8; // Rust project clear
|
|
266
|
+
}
|
|
267
|
+
else if (configFiles.length >= 2) {
|
|
268
|
+
confidence = 0.7; // Multiple configuration files increase confidence
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
files: configFiles,
|
|
272
|
+
confidence,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Analyze file statistics
|
|
277
|
+
*/
|
|
278
|
+
static analyzeFileStatistics(servicePath) {
|
|
279
|
+
try {
|
|
280
|
+
const files = fs.readdirSync(servicePath);
|
|
281
|
+
const extensions = {};
|
|
282
|
+
for (const file of files) {
|
|
283
|
+
const filePath = path.join(servicePath, file);
|
|
284
|
+
const stat = fs.statSync(filePath);
|
|
285
|
+
if (stat.isFile()) {
|
|
286
|
+
const ext = path.extname(file).toLowerCase();
|
|
287
|
+
if (ext) {
|
|
288
|
+
extensions[ext] = (extensions[ext] || 0) + 1;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (Object.keys(extensions).length === 0) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
// Calculate confidence based on main file type
|
|
296
|
+
const totalFiles = Object.values(extensions).reduce((a, b) => a + b, 0);
|
|
297
|
+
const mainExtensions = Object.entries(extensions)
|
|
298
|
+
.sort((a, b) => b[1] - a[1])
|
|
299
|
+
.slice(0, 3);
|
|
300
|
+
let confidence = 0.4;
|
|
301
|
+
const mainExtension = mainExtensions[0];
|
|
302
|
+
if (mainExtension && mainExtension[1] / totalFiles > 0.5) {
|
|
303
|
+
// If one extension dominates, increase confidence
|
|
304
|
+
confidence = 0.6;
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
extensions,
|
|
308
|
+
confidence,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Analyze file extensions
|
|
317
|
+
*/
|
|
318
|
+
static analyzeFileExtensions(servicePath) {
|
|
319
|
+
try {
|
|
320
|
+
const files = fs.readdirSync(servicePath);
|
|
321
|
+
const extensions = [];
|
|
322
|
+
for (const file of files) {
|
|
323
|
+
const ext = path.extname(file).toLowerCase();
|
|
324
|
+
if (ext && !extensions.includes(ext)) {
|
|
325
|
+
extensions.push(ext);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (extensions.length === 0) {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
// File extensions have lower confidence
|
|
332
|
+
return {
|
|
333
|
+
extensions,
|
|
334
|
+
confidence: 0.3,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Determine runtime type from evidence
|
|
343
|
+
*/
|
|
344
|
+
static determineRuntimeFromEvidence(evidence, confidence) {
|
|
345
|
+
// Prefer executable file analysis results
|
|
346
|
+
if (evidence.executableAnalysis && evidence.executableAnalysis.confidence > 0.7) {
|
|
347
|
+
// Convert string to RuntimeType
|
|
348
|
+
const type = evidence.executableAnalysis.type;
|
|
349
|
+
const runtimeTypes = ['node', 'python', 'docker', 'java', 'go', 'rust', 'binary'];
|
|
350
|
+
if (runtimeTypes.includes(type)) {
|
|
351
|
+
return type;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Then use project configuration files
|
|
355
|
+
if (evidence.projectFiles) {
|
|
356
|
+
const files = evidence.projectFiles.files;
|
|
357
|
+
if (files.includes('Dockerfile')) {
|
|
358
|
+
return 'docker';
|
|
359
|
+
}
|
|
360
|
+
if (files.includes('package.json')) {
|
|
361
|
+
return 'node';
|
|
362
|
+
}
|
|
363
|
+
if (files.includes('go.mod')) {
|
|
364
|
+
return 'go';
|
|
365
|
+
}
|
|
366
|
+
if (files.includes('Cargo.toml')) {
|
|
367
|
+
return 'rust';
|
|
368
|
+
}
|
|
369
|
+
if (files.some(f => f.includes('python') || f.endsWith('.py'))) {
|
|
370
|
+
return 'python';
|
|
371
|
+
}
|
|
372
|
+
if (files.includes('pom.xml') || files.includes('build.gradle')) {
|
|
373
|
+
return 'java';
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// Finally use file statistics
|
|
377
|
+
if (evidence.fileStatistics) {
|
|
378
|
+
const extensions = evidence.fileStatistics.extensions;
|
|
379
|
+
const extensionMap = {
|
|
380
|
+
'.js': 'node',
|
|
381
|
+
'.ts': 'node',
|
|
382
|
+
'.py': 'python',
|
|
383
|
+
'.go': 'go',
|
|
384
|
+
'.rs': 'rust',
|
|
385
|
+
'.java': 'java',
|
|
386
|
+
'.class': 'java',
|
|
387
|
+
};
|
|
388
|
+
for (const [ext, runtime] of Object.entries(extensionMap)) {
|
|
389
|
+
if (extensions[ext] && extensions[ext] > 0) {
|
|
390
|
+
return runtime;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// Default value
|
|
395
|
+
return 'binary';
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Generate low confidence warning
|
|
399
|
+
*/
|
|
400
|
+
static generateLowConfidenceWarning(legacyResult, enhancedResult) {
|
|
401
|
+
return 'Cannot reliably determine runtime type.\n' +
|
|
402
|
+
`Traditional detector result: ${legacyResult.runtime} (confidence: ${legacyResult.confidence.toFixed(2)})\n` +
|
|
403
|
+
`Enhanced detector result: ${enhancedResult.runtime} (confidence: ${enhancedResult.confidence.toFixed(2)})\n` +
|
|
404
|
+
'Please use --runtime parameter to explicitly specify runtime type.\n' +
|
|
405
|
+
'Available options: node, python, docker, go, rust, java, binary';
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Generate runtime suggestions
|
|
409
|
+
*/
|
|
410
|
+
static generateRuntimeSuggestions(servicePath) {
|
|
411
|
+
const suggestions = [];
|
|
412
|
+
// Check common patterns
|
|
413
|
+
if (fs.existsSync(path.join(servicePath, 'index.js')) ||
|
|
414
|
+
fs.existsSync(path.join(servicePath, 'app.js'))) {
|
|
415
|
+
suggestions.push('Detected JavaScript file, may be Node.js service');
|
|
416
|
+
}
|
|
417
|
+
if (fs.existsSync(path.join(servicePath, 'main.py')) ||
|
|
418
|
+
fs.existsSync(path.join(servicePath, 'app.py'))) {
|
|
419
|
+
suggestions.push('Detected Python file, may be Python service');
|
|
420
|
+
}
|
|
421
|
+
const executables = ExecutableAnalyzer.findExecutables(servicePath);
|
|
422
|
+
if (executables.length > 0) {
|
|
423
|
+
suggestions.push(`Found ${executables.length} executable files, may be binary service`);
|
|
424
|
+
}
|
|
425
|
+
return suggestions;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Find Python configuration files
|
|
429
|
+
*/
|
|
430
|
+
static findPythonConfigFiles(servicePath) {
|
|
431
|
+
const files = [];
|
|
432
|
+
const pythonConfigs = ['requirements.txt', 'setup.py', 'pyproject.toml', 'Pipfile'];
|
|
433
|
+
for (const config of pythonConfigs) {
|
|
434
|
+
if (fs.existsSync(path.join(servicePath, config))) {
|
|
435
|
+
files.push(config);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return files;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Find Java configuration files
|
|
442
|
+
*/
|
|
443
|
+
static findJavaConfigFiles(servicePath) {
|
|
444
|
+
const files = [];
|
|
445
|
+
const javaConfigs = ['pom.xml', 'build.gradle', 'build.gradle.kts'];
|
|
446
|
+
for (const config of javaConfigs) {
|
|
447
|
+
if (fs.existsSync(path.join(servicePath, config))) {
|
|
448
|
+
files.push(config);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return files;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Quick detection (for CLI interaction)
|
|
455
|
+
*/
|
|
456
|
+
static quickDetect(servicePath) {
|
|
457
|
+
try {
|
|
458
|
+
// First check explicit configuration files
|
|
459
|
+
if (fs.existsSync(path.join(servicePath, 'Dockerfile'))) {
|
|
460
|
+
return { runtime: 'docker', confidence: 0.9 };
|
|
461
|
+
}
|
|
462
|
+
if (fs.existsSync(path.join(servicePath, 'package.json'))) {
|
|
463
|
+
return { runtime: 'node', confidence: 0.8 };
|
|
464
|
+
}
|
|
465
|
+
if (fs.existsSync(path.join(servicePath, 'go.mod'))) {
|
|
466
|
+
return { runtime: 'go', confidence: 0.8 };
|
|
467
|
+
}
|
|
468
|
+
if (fs.existsSync(path.join(servicePath, 'Cargo.toml'))) {
|
|
469
|
+
return { runtime: 'rust', confidence: 0.8 };
|
|
470
|
+
}
|
|
471
|
+
// Check executable files
|
|
472
|
+
const primaryExecutable = ExecutableAnalyzer.getPrimaryExecutable(servicePath);
|
|
473
|
+
if (primaryExecutable) {
|
|
474
|
+
const analysis = ExecutableAnalyzer.analyze(primaryExecutable);
|
|
475
|
+
if (analysis && analysis.confidence > 0.6) {
|
|
476
|
+
return { runtime: analysis.type, confidence: analysis.confidence };
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
// Default
|
|
480
|
+
return { runtime: 'binary', confidence: 0.3 };
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
return { runtime: 'binary', confidence: 0.1 };
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
//# sourceMappingURL=detector-advanced.js.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
export class RuntimeDetector {
|
|
4
|
+
static detect(servicePath) {
|
|
5
|
+
// 1. Detect Docker
|
|
6
|
+
if (fs.existsSync(path.join(servicePath, 'Dockerfile'))) {
|
|
7
|
+
return 'docker';
|
|
8
|
+
}
|
|
9
|
+
// 2. Detect Node.js
|
|
10
|
+
if (fs.existsSync(path.join(servicePath, 'package.json'))) {
|
|
11
|
+
return 'node';
|
|
12
|
+
}
|
|
13
|
+
// 3. Detect Python
|
|
14
|
+
if (fs.existsSync(path.join(servicePath, 'requirements.txt')) ||
|
|
15
|
+
fs.existsSync(path.join(servicePath, 'setup.py')) ||
|
|
16
|
+
fs.existsSync(path.join(servicePath, 'pyproject.toml'))) {
|
|
17
|
+
return 'python';
|
|
18
|
+
}
|
|
19
|
+
// 4. Detect Go
|
|
20
|
+
if (fs.existsSync(path.join(servicePath, 'go.mod'))) {
|
|
21
|
+
return 'go';
|
|
22
|
+
}
|
|
23
|
+
// 5. Detect Rust
|
|
24
|
+
if (fs.existsSync(path.join(servicePath, 'Cargo.toml'))) {
|
|
25
|
+
return 'rust';
|
|
26
|
+
}
|
|
27
|
+
// 6. Detect Java (Maven/Gradle)
|
|
28
|
+
if (fs.existsSync(path.join(servicePath, 'pom.xml')) ||
|
|
29
|
+
fs.existsSync(path.join(servicePath, 'build.gradle'))) {
|
|
30
|
+
return 'java';
|
|
31
|
+
}
|
|
32
|
+
// 7. Check file extensions
|
|
33
|
+
const files = fs.readdirSync(servicePath);
|
|
34
|
+
for (const file of files) {
|
|
35
|
+
const filePath = path.join(servicePath, file);
|
|
36
|
+
const stat = fs.statSync(filePath);
|
|
37
|
+
if (stat.isFile()) {
|
|
38
|
+
if (file.endsWith('.go')) {
|
|
39
|
+
return 'go';
|
|
40
|
+
}
|
|
41
|
+
if (file.endsWith('.rs')) {
|
|
42
|
+
return 'rust';
|
|
43
|
+
}
|
|
44
|
+
if (file.endsWith('.py')) {
|
|
45
|
+
return 'python';
|
|
46
|
+
}
|
|
47
|
+
if (file.endsWith('.js') || file.endsWith('.ts')) {
|
|
48
|
+
return 'node';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 8. Default to binary or script
|
|
53
|
+
return 'binary';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RuntimeAdapter } from './adapter';
|
|
2
|
+
import { ServiceConfig } from '../core/types';
|
|
3
|
+
import { type ChildProcess } from 'child_process';
|
|
4
|
+
export declare class DockerAdapter implements RuntimeAdapter {
|
|
5
|
+
private process;
|
|
6
|
+
private containerName;
|
|
7
|
+
constructor();
|
|
8
|
+
getSpawnArgs(config: ServiceConfig): {
|
|
9
|
+
command: string;
|
|
10
|
+
args: string[];
|
|
11
|
+
};
|
|
12
|
+
setup(config: ServiceConfig): Promise<void>;
|
|
13
|
+
startContainer(config: ServiceConfig): Promise<ChildProcess>;
|
|
14
|
+
stopContainer(): Promise<void>;
|
|
15
|
+
getContainerStatus(): Promise<string>;
|
|
16
|
+
getContainerLogs(tail?: number): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=docker-adapter.d.ts.map
|