@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,391 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { logger } from '../core/logger.js';
|
|
5
|
+
export class ExecutableAnalyzer {
|
|
6
|
+
/**
|
|
7
|
+
* Analyze executable file type
|
|
8
|
+
*/
|
|
9
|
+
static analyze(filePath) {
|
|
10
|
+
if (!fs.existsSync(filePath)) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const stats = fs.statSync(filePath);
|
|
14
|
+
if (!stats.isFile()) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
// Check if file is executable
|
|
18
|
+
if (!this.isExecutable(filePath)) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
// Try different detection methods (by priority)
|
|
22
|
+
const analyses = [
|
|
23
|
+
this.analyzeWithFileCommand(filePath),
|
|
24
|
+
this.analyzeWithMagicNumbers(filePath),
|
|
25
|
+
this.analyzeShebang(filePath),
|
|
26
|
+
this.analyzeByPermissions(filePath),
|
|
27
|
+
this.analyzeByExtension(filePath),
|
|
28
|
+
].filter(analysis => analysis !== null);
|
|
29
|
+
if (analyses.length === 0) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// Select analysis result with highest confidence
|
|
33
|
+
const bestAnalysis = analyses.reduce((best, current) => current.confidence > best.confidence ? current : best);
|
|
34
|
+
logger.debug(`Executable analysis for ${filePath}:`, {
|
|
35
|
+
type: bestAnalysis.type,
|
|
36
|
+
confidence: bestAnalysis.confidence,
|
|
37
|
+
method: bestAnalysis.details.method,
|
|
38
|
+
});
|
|
39
|
+
return bestAnalysis;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Use file command to detect file type (highest priority)
|
|
43
|
+
*/
|
|
44
|
+
static analyzeWithFileCommand(filePath) {
|
|
45
|
+
try {
|
|
46
|
+
const output = execSync(`file -b "${filePath}"`, { encoding: 'utf-8' }).trim();
|
|
47
|
+
let type = 'binary';
|
|
48
|
+
let confidence = 0.8;
|
|
49
|
+
let details = '';
|
|
50
|
+
if (output.includes('ELF')) {
|
|
51
|
+
type = 'binary';
|
|
52
|
+
confidence = 0.9;
|
|
53
|
+
details = 'ELF executable';
|
|
54
|
+
}
|
|
55
|
+
else if (output.includes('Mach-O')) {
|
|
56
|
+
type = 'binary';
|
|
57
|
+
confidence = 0.9;
|
|
58
|
+
details = 'Mach-O executable';
|
|
59
|
+
}
|
|
60
|
+
else if (output.includes('PE32+') || output.includes('PE32')) {
|
|
61
|
+
type = 'binary';
|
|
62
|
+
confidence = 0.9;
|
|
63
|
+
details = 'Windows PE executable';
|
|
64
|
+
}
|
|
65
|
+
else if (output.includes('Node.js')) {
|
|
66
|
+
type = 'node';
|
|
67
|
+
confidence = 0.95;
|
|
68
|
+
details = 'Node.js script';
|
|
69
|
+
}
|
|
70
|
+
else if (output.includes('Python')) {
|
|
71
|
+
type = 'python';
|
|
72
|
+
confidence = 0.95;
|
|
73
|
+
details = 'Python script';
|
|
74
|
+
}
|
|
75
|
+
else if (output.includes('Bourne-Again shell script')) {
|
|
76
|
+
type = 'binary';
|
|
77
|
+
confidence = 0.85;
|
|
78
|
+
details = 'Bash script';
|
|
79
|
+
}
|
|
80
|
+
else if (output.includes('POSIX shell script')) {
|
|
81
|
+
type = 'binary';
|
|
82
|
+
confidence = 0.85;
|
|
83
|
+
details = 'Shell script';
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Unrecognized type
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
type,
|
|
91
|
+
confidence,
|
|
92
|
+
details: {
|
|
93
|
+
method: 'fileCommand',
|
|
94
|
+
result: details,
|
|
95
|
+
rawOutput: output,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
// file command unavailable or failed
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Detect file type via magic numbers
|
|
106
|
+
*/
|
|
107
|
+
static analyzeWithMagicNumbers(filePath) {
|
|
108
|
+
try {
|
|
109
|
+
const buffer = fs.readFileSync(filePath, { flag: 'r' });
|
|
110
|
+
// Only read first few bytes for magic number detection
|
|
111
|
+
const header = buffer.slice(0, 16);
|
|
112
|
+
const hex = header.toString('hex');
|
|
113
|
+
// ELF file: 7f 45 4c 46
|
|
114
|
+
if (hex.startsWith('7f454c46')) {
|
|
115
|
+
return {
|
|
116
|
+
type: 'binary',
|
|
117
|
+
confidence: 0.85,
|
|
118
|
+
details: {
|
|
119
|
+
method: 'magicNumber',
|
|
120
|
+
result: 'ELF executable',
|
|
121
|
+
rawOutput: hex.substring(0, 8),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// Mach-O (64-bit): cf fa ed fe
|
|
126
|
+
// Mach-O (32-bit): ce fa ed fe
|
|
127
|
+
if (hex.startsWith('cffaedfe') || hex.startsWith('cefaedfe')) {
|
|
128
|
+
return {
|
|
129
|
+
type: 'binary',
|
|
130
|
+
confidence: 0.85,
|
|
131
|
+
details: {
|
|
132
|
+
method: 'magicNumber',
|
|
133
|
+
result: 'Mach-O executable',
|
|
134
|
+
rawOutput: hex.substring(0, 8),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// PE file: 4d 5a (MZ)
|
|
139
|
+
if (hex.startsWith('4d5a')) {
|
|
140
|
+
return {
|
|
141
|
+
type: 'binary',
|
|
142
|
+
confidence: 0.85,
|
|
143
|
+
details: {
|
|
144
|
+
method: 'magicNumber',
|
|
145
|
+
result: 'Windows PE executable',
|
|
146
|
+
rawOutput: hex.substring(0, 4),
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Java class file: ca fe ba be
|
|
151
|
+
if (hex.startsWith('cafebabe')) {
|
|
152
|
+
return {
|
|
153
|
+
type: 'java',
|
|
154
|
+
confidence: 0.9,
|
|
155
|
+
details: {
|
|
156
|
+
method: 'magicNumber',
|
|
157
|
+
result: 'Java class file',
|
|
158
|
+
rawOutput: hex.substring(0, 8),
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Analyze Shebang line
|
|
170
|
+
*/
|
|
171
|
+
static analyzeShebang(filePath) {
|
|
172
|
+
try {
|
|
173
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
174
|
+
const firstLine = content.split('\n')[0].trim();
|
|
175
|
+
if (!firstLine.startsWith('#!')) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
const shebang = firstLine.substring(2).toLowerCase();
|
|
179
|
+
let type = 'binary';
|
|
180
|
+
let confidence = 0.8;
|
|
181
|
+
if (shebang.includes('node') || shebang.includes('bun')) {
|
|
182
|
+
type = 'node';
|
|
183
|
+
confidence = 0.9;
|
|
184
|
+
}
|
|
185
|
+
else if (shebang.includes('python')) {
|
|
186
|
+
type = 'python';
|
|
187
|
+
confidence = 0.9;
|
|
188
|
+
}
|
|
189
|
+
else if (shebang.includes('bash') || shebang.includes('sh')) {
|
|
190
|
+
type = 'binary';
|
|
191
|
+
confidence = 0.85;
|
|
192
|
+
}
|
|
193
|
+
else if (shebang.includes('perl')) {
|
|
194
|
+
type = 'binary';
|
|
195
|
+
confidence = 0.8;
|
|
196
|
+
}
|
|
197
|
+
else if (shebang.includes('ruby')) {
|
|
198
|
+
type = 'binary';
|
|
199
|
+
confidence = 0.8;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// Unknown interpreter
|
|
203
|
+
type = 'binary';
|
|
204
|
+
confidence = 0.7;
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
type,
|
|
208
|
+
confidence,
|
|
209
|
+
details: {
|
|
210
|
+
method: 'shebang',
|
|
211
|
+
result: shebang,
|
|
212
|
+
rawOutput: firstLine,
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
// File may not be a text file
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Detect by file permissions
|
|
223
|
+
*/
|
|
224
|
+
static analyzeByPermissions(filePath) {
|
|
225
|
+
try {
|
|
226
|
+
const stats = fs.statSync(filePath);
|
|
227
|
+
const mode = stats.mode;
|
|
228
|
+
const isExecutable = (mode & 0o111) !== 0;
|
|
229
|
+
if (isExecutable) {
|
|
230
|
+
return {
|
|
231
|
+
type: 'binary',
|
|
232
|
+
confidence: 0.6,
|
|
233
|
+
details: {
|
|
234
|
+
method: 'permissions',
|
|
235
|
+
result: 'Executable file',
|
|
236
|
+
rawOutput: `mode: 0o${mode.toString(8)}`,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Detect by file extension (last resort)
|
|
248
|
+
*/
|
|
249
|
+
static analyzeByExtension(filePath) {
|
|
250
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
251
|
+
const extensionMap = {
|
|
252
|
+
'.exe': { type: 'binary', confidence: 0.7 },
|
|
253
|
+
'.bin': { type: 'binary', confidence: 0.7 },
|
|
254
|
+
'.app': { type: 'binary', confidence: 0.7 },
|
|
255
|
+
'.out': { type: 'binary', confidence: 0.6 },
|
|
256
|
+
'.js': { type: 'node', confidence: 0.5 },
|
|
257
|
+
'.ts': { type: 'node', confidence: 0.5 },
|
|
258
|
+
'.py': { type: 'python', confidence: 0.5 },
|
|
259
|
+
'.go': { type: 'go', confidence: 0.5 },
|
|
260
|
+
'.rs': { type: 'rust', confidence: 0.5 },
|
|
261
|
+
'.java': { type: 'java', confidence: 0.5 },
|
|
262
|
+
'.class': { type: 'java', confidence: 0.6 },
|
|
263
|
+
'.jar': { type: 'java', confidence: 0.6 },
|
|
264
|
+
};
|
|
265
|
+
const mapping = extensionMap[ext];
|
|
266
|
+
if (mapping) {
|
|
267
|
+
return {
|
|
268
|
+
type: mapping.type,
|
|
269
|
+
confidence: mapping.confidence,
|
|
270
|
+
details: {
|
|
271
|
+
method: 'extension',
|
|
272
|
+
result: `File extension: ${ext}`,
|
|
273
|
+
rawOutput: ext,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Check if file is executable
|
|
281
|
+
*/
|
|
282
|
+
static isExecutable(filePath) {
|
|
283
|
+
try {
|
|
284
|
+
const stats = fs.statSync(filePath);
|
|
285
|
+
// Check Unix execution permissions
|
|
286
|
+
if (process.platform !== 'win32') {
|
|
287
|
+
const mode = stats.mode;
|
|
288
|
+
const isExecutable = (mode & 0o111) !== 0;
|
|
289
|
+
if (isExecutable) {
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Check file extensions (Windows)
|
|
294
|
+
if (process.platform === 'win32') {
|
|
295
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
296
|
+
const executableExtensions = ['.exe', '.bat', '.cmd', '.ps1', '.com'];
|
|
297
|
+
if (executableExtensions.includes(ext)) {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// Check shebang (script files)
|
|
302
|
+
try {
|
|
303
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
304
|
+
if (content.startsWith('#!')) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
// File may not be a text file
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Find executable files in directory
|
|
319
|
+
*/
|
|
320
|
+
static findExecutables(dirPath) {
|
|
321
|
+
if (!fs.existsSync(dirPath)) {
|
|
322
|
+
return [];
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
const files = fs.readdirSync(dirPath);
|
|
326
|
+
const executables = [];
|
|
327
|
+
for (const file of files) {
|
|
328
|
+
const filePath = path.join(dirPath, file);
|
|
329
|
+
try {
|
|
330
|
+
const stats = fs.statSync(filePath);
|
|
331
|
+
if (!stats.isFile()) {
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (this.isExecutable(filePath)) {
|
|
335
|
+
executables.push(filePath);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
// Ignore inaccessible files
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return executables;
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
return [];
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Get the most likely executable file in directory
|
|
351
|
+
*/
|
|
352
|
+
static getPrimaryExecutable(dirPath) {
|
|
353
|
+
const executables = this.findExecutables(dirPath);
|
|
354
|
+
if (executables.length === 0) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
// Prefer files without extensions (Unix convention)
|
|
358
|
+
const noExtension = executables.filter(p => path.extname(p) === '');
|
|
359
|
+
if (noExtension.length > 0) {
|
|
360
|
+
return noExtension[0];
|
|
361
|
+
}
|
|
362
|
+
// Then choose common executable extensions
|
|
363
|
+
const commonExtensions = ['.exe', '.bin', '.app', '.out'];
|
|
364
|
+
for (const ext of commonExtensions) {
|
|
365
|
+
const withExt = executables.filter(p => path.extname(p).toLowerCase() === ext);
|
|
366
|
+
if (withExt.length > 0) {
|
|
367
|
+
return withExt[0];
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Return first executable file
|
|
371
|
+
return executables[0];
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Batch analyze executable files in directory
|
|
375
|
+
*/
|
|
376
|
+
static analyzeDirectory(dirPath) {
|
|
377
|
+
const executables = this.findExecutables(dirPath);
|
|
378
|
+
const results = [];
|
|
379
|
+
for (const executable of executables) {
|
|
380
|
+
const analysis = this.analyze(executable);
|
|
381
|
+
if (analysis) {
|
|
382
|
+
results.push({
|
|
383
|
+
file: path.relative(dirPath, executable),
|
|
384
|
+
analysis,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return results;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=executable-analyzer.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RuntimeAdapter } from './adapter';
|
|
2
|
+
import { ServiceConfig } from '../core/types';
|
|
3
|
+
import { type ChildProcess } from 'child_process';
|
|
4
|
+
export declare class GoAdapter implements RuntimeAdapter {
|
|
5
|
+
private process;
|
|
6
|
+
getSpawnArgs(config: ServiceConfig): {
|
|
7
|
+
command: string;
|
|
8
|
+
args: string[];
|
|
9
|
+
};
|
|
10
|
+
setup(config: ServiceConfig): Promise<void>;
|
|
11
|
+
private findGoBinary;
|
|
12
|
+
private isExecutable;
|
|
13
|
+
startService(config: ServiceConfig): Promise<ChildProcess>;
|
|
14
|
+
stopService(): Promise<void>;
|
|
15
|
+
getServiceStatus(): Promise<string>;
|
|
16
|
+
compile(config: ServiceConfig): Promise<boolean>;
|
|
17
|
+
test(config: ServiceConfig): Promise<boolean>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=go-adapter.d.ts.map
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
export class GoAdapter {
|
|
5
|
+
process = null;
|
|
6
|
+
getSpawnArgs(config) {
|
|
7
|
+
const goPath = this.findGoBinary(config);
|
|
8
|
+
return {
|
|
9
|
+
command: goPath,
|
|
10
|
+
args: ['run', config.entry, ...(config.args || [])],
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
async setup(config) {
|
|
14
|
+
console.log(`[Go] Setting up service: ${config.name}`);
|
|
15
|
+
// Check if Go is installed
|
|
16
|
+
try {
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
execSync('go version', { stdio: 'ignore' });
|
|
19
|
+
console.log('[Go] Go is installed');
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error('Go is not installed or not in PATH. Please install Go from https://golang.org/dl/');
|
|
23
|
+
}
|
|
24
|
+
const servicePath = config.path || '.';
|
|
25
|
+
// Check go.mod file
|
|
26
|
+
const goModPath = path.join(servicePath, 'go.mod');
|
|
27
|
+
if (!fs.existsSync(goModPath)) {
|
|
28
|
+
console.log(`[Go] go.mod not found, creating basic go.mod for ${config.name}`);
|
|
29
|
+
try {
|
|
30
|
+
const { execSync } = require('child_process');
|
|
31
|
+
execSync(`go mod init ${config.name}`, {
|
|
32
|
+
stdio: 'inherit',
|
|
33
|
+
cwd: servicePath,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.warn(`[Go] Failed to create go.mod: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Download dependencies
|
|
41
|
+
console.log('[Go] Downloading dependencies...');
|
|
42
|
+
try {
|
|
43
|
+
const { execSync } = require('child_process');
|
|
44
|
+
execSync('go mod tidy', {
|
|
45
|
+
stdio: 'inherit',
|
|
46
|
+
cwd: servicePath,
|
|
47
|
+
});
|
|
48
|
+
console.log('[Go] Dependencies downloaded successfully');
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.warn(`[Go] Failed to download dependencies: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
// Build executable (optional)
|
|
54
|
+
if (config.build) {
|
|
55
|
+
console.log('[Go] Building executable...');
|
|
56
|
+
try {
|
|
57
|
+
const { execSync } = require('child_process');
|
|
58
|
+
const outputName = config.output || config.name;
|
|
59
|
+
execSync(`go build -o ${outputName} ${config.entry}`, {
|
|
60
|
+
stdio: 'inherit',
|
|
61
|
+
cwd: servicePath,
|
|
62
|
+
});
|
|
63
|
+
console.log(`[Go] Executable built: ${outputName}`);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
console.warn(`[Go] Failed to build executable: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
console.log(`[Go] Setup completed for service: ${config.name}`);
|
|
70
|
+
}
|
|
71
|
+
findGoBinary(config) {
|
|
72
|
+
// First check if there is a pre-built executable file
|
|
73
|
+
if (config.binary) {
|
|
74
|
+
const binaryPath = path.join(config.path || '.', config.binary);
|
|
75
|
+
if (fs.existsSync(binaryPath)) {
|
|
76
|
+
return binaryPath;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check if there is a build output
|
|
80
|
+
const possibleOutputs = [
|
|
81
|
+
config.name,
|
|
82
|
+
`./${config.name}`,
|
|
83
|
+
path.join(config.path || '.', config.name),
|
|
84
|
+
path.join(config.path || '.', 'main'),
|
|
85
|
+
];
|
|
86
|
+
for (const output of possibleOutputs) {
|
|
87
|
+
if (fs.existsSync(output) && this.isExecutable(output)) {
|
|
88
|
+
return output;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Default to using go run
|
|
92
|
+
return 'go';
|
|
93
|
+
}
|
|
94
|
+
isExecutable(filePath) {
|
|
95
|
+
try {
|
|
96
|
+
fs.accessSync(filePath, fs.constants.X_OK);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async startService(config) {
|
|
104
|
+
const { command, args } = this.getSpawnArgs(config);
|
|
105
|
+
console.log(`[Go] Starting service: ${config.name}`);
|
|
106
|
+
console.log(`[Go] Command: ${command} ${args.join(' ')}`);
|
|
107
|
+
const childProcess = spawn(command, args, {
|
|
108
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
109
|
+
detached: false,
|
|
110
|
+
env: {
|
|
111
|
+
...process.env,
|
|
112
|
+
...config.env,
|
|
113
|
+
},
|
|
114
|
+
cwd: config.path || '.',
|
|
115
|
+
});
|
|
116
|
+
childProcess.stdout?.on('data', (data) => {
|
|
117
|
+
console.log(`[Go:${config.name}] ${data.toString().trim()}`);
|
|
118
|
+
});
|
|
119
|
+
childProcess.stderr?.on('data', (data) => {
|
|
120
|
+
console.error(`[Go:${config.name}] ERR: ${data.toString().trim()}`);
|
|
121
|
+
});
|
|
122
|
+
childProcess.on('error', (error) => {
|
|
123
|
+
console.error(`[Go:${config.name}] Failed to start: ${error.message}`);
|
|
124
|
+
});
|
|
125
|
+
childProcess.on('exit', (code, signal) => {
|
|
126
|
+
console.log(`[Go:${config.name}] Process exited with code ${code}, signal ${signal}`);
|
|
127
|
+
this.process = null;
|
|
128
|
+
});
|
|
129
|
+
this.process = childProcess;
|
|
130
|
+
return childProcess;
|
|
131
|
+
}
|
|
132
|
+
async stopService() {
|
|
133
|
+
if (this.process) {
|
|
134
|
+
console.log('[Go] Stopping service');
|
|
135
|
+
this.process.kill();
|
|
136
|
+
this.process = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async getServiceStatus() {
|
|
140
|
+
if (!this.process) {
|
|
141
|
+
return 'stopped';
|
|
142
|
+
}
|
|
143
|
+
// Check if the process is still running
|
|
144
|
+
if (this.process.exitCode !== null) {
|
|
145
|
+
return 'exited';
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
// Send signal 0 to check if the process exists
|
|
149
|
+
this.process.kill(0);
|
|
150
|
+
return 'running';
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
return 'stopped';
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async compile(config) {
|
|
157
|
+
console.log(`[Go] Compiling service: ${config.name}`);
|
|
158
|
+
try {
|
|
159
|
+
const { execSync } = require('child_process');
|
|
160
|
+
const outputName = config.output || config.name;
|
|
161
|
+
execSync(`go build -o ${outputName} ${config.entry}`, {
|
|
162
|
+
stdio: 'inherit',
|
|
163
|
+
cwd: config.path || '.',
|
|
164
|
+
});
|
|
165
|
+
console.log(`[Go] Successfully compiled: ${outputName}`);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error(`[Go] Compilation failed: ${error.message}`);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async test(config) {
|
|
174
|
+
console.log(`[Go] Running tests for service: ${config.name}`);
|
|
175
|
+
try {
|
|
176
|
+
const { execSync } = require('child_process');
|
|
177
|
+
execSync('go test ./...', {
|
|
178
|
+
stdio: 'inherit',
|
|
179
|
+
cwd: config.path || '.',
|
|
180
|
+
});
|
|
181
|
+
console.log('[Go] Tests passed');
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error(`[Go] Tests failed: ${error.message}`);
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=go-adapter.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Module Exports
|
|
3
|
+
* Provides unified interface for runtime functionality
|
|
4
|
+
*/
|
|
5
|
+
export { RuntimeAdapter } from './adapter';
|
|
6
|
+
export { RuntimeDetector } from './detector';
|
|
7
|
+
export { EnhancedRuntimeDetector } from './detector-advanced';
|
|
8
|
+
export { ExecutableAnalyzer } from './executable-analyzer';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Module Exports
|
|
3
|
+
* Provides unified interface for runtime functionality
|
|
4
|
+
*/
|
|
5
|
+
// Export detectors
|
|
6
|
+
export { RuntimeDetector } from './detector.js';
|
|
7
|
+
export { EnhancedRuntimeDetector } from './detector-advanced.js';
|
|
8
|
+
// Export executable analyzer
|
|
9
|
+
export { ExecutableAnalyzer } from './executable-analyzer.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { RuntimeAdapter } from './adapter';
|
|
2
|
+
import { ServiceConfig } from '../core/types';
|
|
3
|
+
export declare class NodeAdapter implements RuntimeAdapter {
|
|
4
|
+
getSpawnArgs(config: ServiceConfig): {
|
|
5
|
+
command: string;
|
|
6
|
+
args: string[];
|
|
7
|
+
};
|
|
8
|
+
setup(config: ServiceConfig): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=node-adapter.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
export class NodeAdapter {
|
|
3
|
+
getSpawnArgs(config) {
|
|
4
|
+
// Auto-detect runtime: try bun first, fallback to node
|
|
5
|
+
let command = 'bun';
|
|
6
|
+
try {
|
|
7
|
+
execSync('which bun', { stdio: 'ignore' });
|
|
8
|
+
command = 'bun';
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
command = 'node';
|
|
12
|
+
}
|
|
13
|
+
const args = command === 'bun' ? [config.entry, ...(config.args || [])] : [config.entry, ...(config.args || [])];
|
|
14
|
+
return {
|
|
15
|
+
command,
|
|
16
|
+
args,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async setup(config) {
|
|
20
|
+
// No special setup needed for Node/Bun
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=node-adapter.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface AdapterOptions {
|
|
2
|
+
name: string;
|
|
3
|
+
cwd: string;
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
args?: string[];
|
|
6
|
+
runtime?: 'bun' | 'node';
|
|
7
|
+
}
|
|
8
|
+
export declare class NodeAdapter {
|
|
9
|
+
private options;
|
|
10
|
+
private process;
|
|
11
|
+
private requestId;
|
|
12
|
+
private pendingRequests;
|
|
13
|
+
private runtime;
|
|
14
|
+
constructor(options: AdapterOptions);
|
|
15
|
+
start(): Promise<void>;
|
|
16
|
+
call(method: string, params?: any): Promise<any>;
|
|
17
|
+
stop(): void;
|
|
18
|
+
isRunning(): boolean;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=node.d.ts.map
|