stigmergy 1.3.10 → 1.3.13
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/package.json +1 -1
- package/src/cli/commands/project.js +43 -20
- package/src/utils.js +38 -7
- package/test/simple_test.js +82 -0
- package/test/very_simple_test.js +54 -0
package/package.json
CHANGED
|
@@ -336,26 +336,41 @@ async function executeSmartRoutedCommand(route, options = {}) {
|
|
|
336
336
|
|
|
337
337
|
// Use enhanced parameter handling for one-time mode only
|
|
338
338
|
if (mode === 'one-time') {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
339
|
+
try {
|
|
340
|
+
const EnhancedCLIParameterHandler = require('../../core/enhanced_cli_parameter_handler');
|
|
341
|
+
const paramHandler = new EnhancedCLIParameterHandler();
|
|
342
|
+
|
|
343
|
+
// Generate optimized arguments with agent/skill support
|
|
344
|
+
// Add timeout protection for parameter generation
|
|
345
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
346
|
+
setTimeout(() => reject(new Error('Parameter generation timeout')), 30000); // 30 second timeout for parameter generation
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const paramPromise = paramHandler.generateArgumentsWithRetry(
|
|
350
|
+
route.tool,
|
|
351
|
+
route.prompt,
|
|
352
|
+
{
|
|
353
|
+
maxRetries,
|
|
354
|
+
enableAgentSkillOptimization: true
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
const paramResult = await Promise.race([paramPromise, timeoutPromise]);
|
|
359
|
+
|
|
360
|
+
toolArgs = paramResult.arguments;
|
|
361
|
+
|
|
362
|
+
// Re-add OAuth authentication (paramResult might overwrite)
|
|
363
|
+
toolArgs = addOAuthAuthArgs(route.tool, toolArgs);
|
|
364
|
+
|
|
365
|
+
if (verbose) {
|
|
366
|
+
console.log(chalk.gray(`[DEBUG] Generated args: ${toolArgs.join(' ')}`));
|
|
367
|
+
}
|
|
368
|
+
} catch (paramError) {
|
|
369
|
+
console.log(chalk.yellow(`[WARN] Parameter generation failed: ${paramError.message}, using basic arguments`));
|
|
370
|
+
// Fallback to basic arguments if enhanced parameter generation fails
|
|
371
|
+
if (verbose) {
|
|
372
|
+
console.log(chalk.gray(`[DEBUG] Falling back to basic args: ${toolArgs.join(' ')}`));
|
|
349
373
|
}
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
toolArgs = paramResult.arguments;
|
|
353
|
-
|
|
354
|
-
// Re-add OAuth authentication (paramResult might overwrite)
|
|
355
|
-
toolArgs = addOAuthAuthArgs(route.tool, toolArgs);
|
|
356
|
-
|
|
357
|
-
if (verbose) {
|
|
358
|
-
console.log(chalk.gray(`[DEBUG] Generated args: ${toolArgs.join(' ')}`));
|
|
359
374
|
}
|
|
360
375
|
} else {
|
|
361
376
|
if (verbose) {
|
|
@@ -379,15 +394,23 @@ async function executeSmartRoutedCommand(route, options = {}) {
|
|
|
379
394
|
console.log(chalk.gray(`[DEBUG] Mode: ${mode}`));
|
|
380
395
|
}
|
|
381
396
|
|
|
397
|
+
console.log(chalk.gray(`[EXEC] ${route.tool}: ${route.prompt}`)); // Add this to match direct command format
|
|
398
|
+
|
|
382
399
|
// Execute the command
|
|
383
400
|
// For interactive mode, we need stdio: 'inherit' to allow user interaction
|
|
401
|
+
// For one-time mode, we should use 'inherit' to ensure CLI tools can properly execute
|
|
402
|
+
const stdioOption = mode === 'interactive' ? 'inherit' : 'inherit'; // Use 'inherit' for both modes to ensure proper CLI execution
|
|
403
|
+
|
|
404
|
+
console.log(chalk.gray(`[DEBUG] About to execute command with args: ${toolArgs.join(' ')}`)); // Debug log
|
|
405
|
+
console.log(chalk.gray(`[DEBUG] Using stdio option: ${stdioOption}`)); // Debug log
|
|
384
406
|
const result = await executeCommand(toolPath, toolArgs, {
|
|
385
|
-
stdio:
|
|
407
|
+
stdio: stdioOption,
|
|
386
408
|
shell: true,
|
|
387
409
|
cwd,
|
|
388
410
|
env,
|
|
389
411
|
timeout: 300000 // 5 minutes
|
|
390
412
|
});
|
|
413
|
+
console.log(chalk.gray(`[DEBUG] Command execution completed`)); // Debug log
|
|
391
414
|
|
|
392
415
|
return { success: true, tool: route.tool, result, mode };
|
|
393
416
|
|
package/src/utils.js
CHANGED
|
@@ -631,10 +631,12 @@ async function executeCommand(command, args = [], options = {}) {
|
|
|
631
631
|
const opts = {
|
|
632
632
|
stdio: 'inherit',
|
|
633
633
|
shell: true,
|
|
634
|
-
timeout: 300000, // 5 minute timeout
|
|
635
634
|
...options,
|
|
636
635
|
};
|
|
637
636
|
|
|
637
|
+
// Extract timeout from options to handle separately
|
|
638
|
+
const timeoutValue = options.timeout || 300000; // Default to 5 minutes if not specified
|
|
639
|
+
|
|
638
640
|
return new Promise((resolve, reject) => {
|
|
639
641
|
// Don't log the command if it contains sensitive information
|
|
640
642
|
if (process.env.DEBUG === 'true') {
|
|
@@ -704,6 +706,9 @@ async function executeCommand(command, args = [], options = {}) {
|
|
|
704
706
|
// Flag to ensure timeout is cleared only once
|
|
705
707
|
let timeoutCleared = false;
|
|
706
708
|
|
|
709
|
+
// Flag to prevent duplicate promise resolution
|
|
710
|
+
let promiseResolved = false;
|
|
711
|
+
|
|
707
712
|
// Function to clear timeout safely
|
|
708
713
|
const clearTimeoutSafely = () => {
|
|
709
714
|
if (timeoutId && !timeoutCleared) {
|
|
@@ -712,25 +717,51 @@ async function executeCommand(command, args = [], options = {}) {
|
|
|
712
717
|
}
|
|
713
718
|
};
|
|
714
719
|
|
|
715
|
-
|
|
720
|
+
// Function to resolve safely (prevent duplicate resolution)
|
|
721
|
+
const safeResolve = (result) => {
|
|
722
|
+
if (!promiseResolved) {
|
|
723
|
+
promiseResolved = true;
|
|
724
|
+
resolve(result);
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
// Function to reject safely (prevent duplicate rejection)
|
|
729
|
+
const safeReject = (error) => {
|
|
730
|
+
if (!promiseResolved) {
|
|
731
|
+
promiseResolved = true;
|
|
732
|
+
reject(error);
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
child.on('exit', (code, signal) => {
|
|
716
737
|
// Clear timeout when process exits
|
|
717
738
|
clearTimeoutSafely();
|
|
718
739
|
|
|
719
740
|
// Resolve with collected stdout/stderr
|
|
720
|
-
|
|
741
|
+
safeResolve({
|
|
721
742
|
code,
|
|
743
|
+
signal,
|
|
722
744
|
stdout,
|
|
723
745
|
stderr,
|
|
724
746
|
success: code === 0,
|
|
725
747
|
});
|
|
726
748
|
});
|
|
727
749
|
|
|
728
|
-
child.on('close', (code) => {
|
|
750
|
+
child.on('close', (code, signal) => {
|
|
729
751
|
// Clear timeout when all stdio streams are closed
|
|
730
752
|
clearTimeoutSafely();
|
|
731
753
|
|
|
732
754
|
// Only resolve if not already resolved via 'exit' event
|
|
733
755
|
// This prevents duplicate resolution
|
|
756
|
+
if (!promiseResolved) {
|
|
757
|
+
safeResolve({
|
|
758
|
+
code,
|
|
759
|
+
signal,
|
|
760
|
+
stdout,
|
|
761
|
+
stderr,
|
|
762
|
+
success: code === 0,
|
|
763
|
+
});
|
|
764
|
+
}
|
|
734
765
|
});
|
|
735
766
|
|
|
736
767
|
child.on('error', (error) => {
|
|
@@ -756,16 +787,16 @@ async function executeCommand(command, args = [], options = {}) {
|
|
|
756
787
|
});
|
|
757
788
|
|
|
758
789
|
// Handle timeout
|
|
759
|
-
if (
|
|
790
|
+
if (timeoutValue) {
|
|
760
791
|
timeoutId = setTimeout(() => {
|
|
761
792
|
child.kill();
|
|
762
793
|
reject({
|
|
763
794
|
error: new Error('Command timeout'),
|
|
764
|
-
message: `Command timed out after ${
|
|
795
|
+
message: `Command timed out after ${timeoutValue}ms`,
|
|
765
796
|
stdout,
|
|
766
797
|
stderr,
|
|
767
798
|
});
|
|
768
|
-
},
|
|
799
|
+
}, timeoutValue);
|
|
769
800
|
}
|
|
770
801
|
} catch (error) {
|
|
771
802
|
reject({
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple test for basic functionality
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Mock the CLI tools to ensure they're available for testing
|
|
8
|
+
jest.doMock('../src/core/cli_tools', () => ({
|
|
9
|
+
CLI_TOOLS: {
|
|
10
|
+
claude: { name: 'Claude CLI', command: 'claude', version: 'claude --version' },
|
|
11
|
+
qwen: { name: 'Qwen CLI', command: 'qwen', version: 'qwen --version' },
|
|
12
|
+
gemini: { name: 'Gemini CLI', command: 'gemini', version: 'gemini --version' },
|
|
13
|
+
iflow: { name: 'iFlow CLI', command: 'iflow', version: 'iflow --version' },
|
|
14
|
+
codebuddy: { name: 'CodeBuddy CLI', command: 'codebuddy', version: 'codebuddy --version' },
|
|
15
|
+
codex: { name: 'Codex CLI', command: 'codex', version: 'codex --version' },
|
|
16
|
+
qodercli: { name: 'QoderCLI', command: 'qodercli', version: 'qodercli --version' },
|
|
17
|
+
copilot: { name: 'Copilot CLI', command: 'copilot', version: 'copilot --version' },
|
|
18
|
+
kode: { name: 'Kode CLI', command: 'kode', version: 'kode --version' }
|
|
19
|
+
},
|
|
20
|
+
validateCLITool: jest.fn().mockReturnValue(true)
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
// Mock CLIHelpAnalyzer to avoid actual CLI analysis during testing
|
|
24
|
+
jest.doMock('../src/core/cli_help_analyzer', () => {
|
|
25
|
+
return jest.fn().mockImplementation(() => {
|
|
26
|
+
return {
|
|
27
|
+
setCLITools: jest.fn(),
|
|
28
|
+
initialize: jest.fn().mockResolvedValue(undefined),
|
|
29
|
+
analyzeCLI: jest.fn().mockResolvedValue({
|
|
30
|
+
success: true,
|
|
31
|
+
cliName: 'test-cli',
|
|
32
|
+
patterns: {
|
|
33
|
+
commands: [{ name: 'analyze' }, { name: 'generate' }, { name: 'explain' }],
|
|
34
|
+
subcommands: []
|
|
35
|
+
}
|
|
36
|
+
}),
|
|
37
|
+
loadPersistentConfig: jest.fn().mockResolvedValue({
|
|
38
|
+
failedAttempts: {},
|
|
39
|
+
cliPatterns: {}
|
|
40
|
+
}),
|
|
41
|
+
getCachedAnalysis: jest.fn().mockResolvedValue(null),
|
|
42
|
+
isCacheExpired: jest.fn().mockReturnValue(false),
|
|
43
|
+
generateOptimizedCall: jest.fn().mockReturnValue({
|
|
44
|
+
optimizedPrompt: 'test prompt'
|
|
45
|
+
}),
|
|
46
|
+
getAgentSkillCompatibilityScore: jest.fn().mockReturnValue({ score: 0.5, reasons: ['test'] }),
|
|
47
|
+
getEnhancedCLIPattern: jest.fn().mockResolvedValue({})
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const SmartRouter = require('../src/core/smart_router');
|
|
53
|
+
|
|
54
|
+
async function runSimpleTest() {
|
|
55
|
+
console.log('Running simple test...');
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const router = new SmartRouter();
|
|
59
|
+
await router.initialize();
|
|
60
|
+
|
|
61
|
+
console.log('✓ Router initialized successfully');
|
|
62
|
+
|
|
63
|
+
// Test a simple routing case
|
|
64
|
+
const result = await router.smartRoute('use claude to analyze code');
|
|
65
|
+
console.log(`✓ Simple routing test passed: ${result.tool}`);
|
|
66
|
+
|
|
67
|
+
// Test shouldRoute functionality
|
|
68
|
+
const shouldRoute = router.shouldRoute('help with code');
|
|
69
|
+
console.log(`✓ shouldRoute test passed: ${shouldRoute}`);
|
|
70
|
+
|
|
71
|
+
console.log('All simple tests passed!');
|
|
72
|
+
return true;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Simple test failed:', error);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Run the test
|
|
80
|
+
runSimpleTest().then(success => {
|
|
81
|
+
process.exit(success ? 0 : 1);
|
|
82
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Very simple test without complex mocking
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Simple test to check basic functionality
|
|
8
|
+
async function runVerySimpleTest() {
|
|
9
|
+
console.log('Running very simple test...');
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
// Test basic Node.js functionality
|
|
13
|
+
console.log('✓ Node.js environment is working');
|
|
14
|
+
|
|
15
|
+
// Test basic string operations
|
|
16
|
+
const testString = 'hello world';
|
|
17
|
+
if (testString.toUpperCase() === 'HELLO WORLD') {
|
|
18
|
+
console.log('✓ String operations working');
|
|
19
|
+
} else {
|
|
20
|
+
console.log('✗ String operations failed');
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Test basic math
|
|
25
|
+
if (2 + 2 === 4) {
|
|
26
|
+
console.log('✓ Math operations working');
|
|
27
|
+
} else {
|
|
28
|
+
console.log('✗ Math operations failed');
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Test basic array operations
|
|
33
|
+
const arr = [1, 2, 3];
|
|
34
|
+
arr.push(4);
|
|
35
|
+
if (arr.length === 4 && arr[3] === 4) {
|
|
36
|
+
console.log('✓ Array operations working');
|
|
37
|
+
} else {
|
|
38
|
+
console.log('✗ Array operations failed');
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log('All very simple tests passed!');
|
|
43
|
+
return true;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error('Very simple test failed:', error);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Run the test
|
|
51
|
+
runVerySimpleTest().then(success => {
|
|
52
|
+
console.log(`Test completed with success: ${success}`);
|
|
53
|
+
process.exit(success ? 0 : 1);
|
|
54
|
+
});
|