stigmergy 1.2.10 → 1.2.12

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stigmergy",
3
- "version": "1.2.10",
3
+ "version": "1.2.12",
4
4
  "description": "Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/cli/router.js CHANGED
@@ -45,6 +45,30 @@ function formatBytes(bytes) {
45
45
  return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
46
46
  }
47
47
 
48
+ // Helper function to get appropriate working directory for CLI tools
49
+ function getWorkingDirectoryForTool(toolName) {
50
+ switch (toolName) {
51
+ case 'qwen':
52
+ // For Qwen CLI, use user home directory to avoid module resolution issues
53
+ return os.homedir();
54
+ case 'claude':
55
+ // For Claude CLI, use user home directory
56
+ return os.homedir();
57
+ case 'gemini':
58
+ // For Gemini CLI, use user home directory
59
+ return os.homedir();
60
+ case 'iflow':
61
+ // For iFlow CLI, use user home directory
62
+ return os.homedir();
63
+ case 'qodercli':
64
+ // For Qoder CLI, use user home directory
65
+ return os.homedir();
66
+ default:
67
+ // For other tools, use current directory
68
+ return process.cwd();
69
+ }
70
+ }
71
+
48
72
  async function main() {
49
73
  const args = process.argv.slice(2);
50
74
 
@@ -757,9 +781,18 @@ async function main() {
757
781
  console.log(`[DEBUG] Windows unified command: ${execCommand}`);
758
782
  }
759
783
 
784
+ // Set environment for tools that need specific working directories
785
+ const env = { ...process.env };
786
+ if (route.tool === 'qwen') {
787
+ // For Qwen CLI, clear NODE_PATH to avoid import conflicts
788
+ delete env.NODE_PATH;
789
+ }
790
+
760
791
  const result = await executeCommand(execCommand, execArgs, {
761
792
  stdio: 'inherit',
762
793
  shell: true,
794
+ cwd: getWorkingDirectoryForTool(route.tool),
795
+ env,
763
796
  });
764
797
 
765
798
  if (!result.success) {
@@ -809,9 +842,17 @@ async function main() {
809
842
  // For other execution errors, try to execute the command directly
810
843
  // which handles cases where the tool executed successfully but returned an error object
811
844
  console.log(`[EXEC] Running: ${toolPath} ${toolArgs.join(' ')}`);
845
+ // Set environment for tools that need specific working directories
846
+ const env = { ...process.env };
847
+ if (route.tool === 'qwen') {
848
+ delete env.NODE_PATH;
849
+ }
850
+
812
851
  const result = await executeCommand(toolPath, toolArgs, {
813
852
  stdio: 'inherit',
814
853
  shell: true,
854
+ cwd: getWorkingDirectoryForTool(route.tool),
855
+ env,
815
856
  });
816
857
 
817
858
  if (!result.success) {
@@ -1651,9 +1692,18 @@ async function main() {
1651
1692
  // For other execution errors, try to execute the command directly
1652
1693
  // which handles cases where the tool executed successfully but returned an error object
1653
1694
  console.log(`[EXEC] Running: ${toolPath} ${toolArgs.join(' ')}`);
1695
+
1696
+ // Set environment for tools that need specific working directories
1697
+ const env = { ...process.env };
1698
+ if (route.tool === 'qwen') {
1699
+ delete env.NODE_PATH;
1700
+ }
1701
+
1654
1702
  const result = await executeCommand(toolPath, toolArgs, {
1655
1703
  stdio: 'inherit',
1656
1704
  shell: true,
1705
+ cwd: getWorkingDirectoryForTool(route.tool),
1706
+ env,
1657
1707
  });
1658
1708
 
1659
1709
  if (!result.success) {
@@ -48,17 +48,52 @@ class CLIPathDetector {
48
48
  path.join(process.env.ProgramFiles || 'C:/Program Files', 'npm')
49
49
  );
50
50
  } else {
51
- // Unix-like paths
51
+ // Unix-like paths - comprehensive coverage
52
52
  paths.push(
53
- path.join(os.homedir(), '.npm-global', 'bin'), // User local
54
- '/usr/local/bin', // System
55
- '/usr/bin', // System
56
- path.join(os.homedir(), '.npm', 'bin') // User npm
53
+ // User-specific npm global paths
54
+ path.join(os.homedir(), '.npm-global', 'bin'), // User local with custom prefix
55
+ path.join(os.homedir(), '.npm', 'bin'), // User npm
56
+ path.join(os.homedir(), 'node_modules', '.bin'), // Local node_modules bin
57
+
58
+ // System-wide paths
59
+ '/usr/local/bin', // Common system location
60
+ '/usr/bin', // System binaries
61
+ '/opt/node/bin', // Node.js installed to /opt
62
+ '/opt/nodejs/bin', // Alternative system installation
63
+
64
+ // Root-specific paths (when running as root)
65
+ '/root/.npm-global/bin', // Root user custom prefix
66
+ '/root/.npm/bin', // Root user npm
67
+ '/root/node_modules/.bin', // Root local node_modules
68
+ '/root/.nvm/versions/node/*/bin', // NVM installations for root
69
+
70
+ // NVM (Node Version Manager) paths for regular users
71
+ path.join(os.homedir(), '.nvm', 'versions', 'node', '*', 'bin'), // NVM user installations
72
+ path.join(os.homedir(), '.nvm', 'current', 'bin'), // NVM current version
73
+
74
+ // NodeSource installation paths
75
+ '/usr/bin/nodejs', // NodeSource package installations
76
+ '/usr/local/share/npm/bin', // npm share location
77
+
78
+ // Homebrew (macOS) paths
79
+ path.join(os.homedir(), '.brew', 'node', 'bin'), // Custom Homebrew
80
+ '/opt/homebrew/bin', // Apple Silicon Homebrew
81
+ '/usr/local/bin', // Intel Homebrew
82
+
83
+ // pkg-config and other package managers
84
+ path.join(os.homedir(), '.local', 'bin'), // User local binaries
85
+ '/snap/bin', // Snap packages (Ubuntu)
86
+ '/var/lib/snapd/snap/bin' // Snap system
57
87
  );
58
88
  }
59
89
 
90
+ // Filter paths, handling wildcards for NVM
60
91
  return paths.filter(p => {
61
92
  try {
93
+ // Handle wildcard paths (NVM versions)
94
+ if (p.includes('*')) {
95
+ return this.expandWildcardPath(p);
96
+ }
62
97
  return fs.existsSync(p);
63
98
  } catch {
64
99
  return false;
@@ -66,6 +101,36 @@ class CLIPathDetector {
66
101
  });
67
102
  }
68
103
 
104
+ /**
105
+ * Expand wildcard paths (e.g., NVM version paths)
106
+ */
107
+ expandWildcardPath(wildcardPath) {
108
+ try {
109
+ const { spawnSync } = require('child_process');
110
+
111
+ // Use shell to expand wildcards
112
+ const result = spawnSync('bash', ['-c', `ls -d ${wildcardPath} 2>/dev/null`], {
113
+ encoding: 'utf8',
114
+ shell: true
115
+ });
116
+
117
+ if (result.status === 0 && result.stdout.trim()) {
118
+ // Check if any of the expanded paths exist
119
+ const expandedPaths = result.stdout.trim().split('\n');
120
+ return expandedPaths.some(p => {
121
+ try {
122
+ return fs.existsSync(p.trim());
123
+ } catch {
124
+ return false;
125
+ }
126
+ });
127
+ }
128
+ return false;
129
+ } catch {
130
+ return false;
131
+ }
132
+ }
133
+
69
134
  /**
70
135
  * Get current PATH environment variable
71
136
  */
@@ -146,8 +211,15 @@ class CLIPathDetector {
146
211
  const commandNames = this.cliNameMap[toolName] || [toolName];
147
212
 
148
213
  for (const command of commandNames) {
214
+ // Method 0: Use npm to get actual global installation path
215
+ let pathFound = await this.findCommandViaNPM(command);
216
+ if (pathFound) {
217
+ console.log(`[DETECTOR] Found ${toolName} via npm: ${pathFound}`);
218
+ return pathFound;
219
+ }
220
+
149
221
  // Method 1: Check system PATH (most common)
150
- let pathFound = this.findCommandInPath(command);
222
+ pathFound = this.findCommandInPath(command);
151
223
  if (pathFound) {
152
224
  console.log(`[DETECTOR] Found ${toolName} in PATH: ${pathFound}`);
153
225
  return pathFound;
@@ -169,11 +241,23 @@ class CLIPathDetector {
169
241
  return pathFound;
170
242
  }
171
243
  } else {
172
- const userNPMPath = path.join(os.homedir(), '.npm-global', 'bin');
173
- pathFound = this.checkCommandInDir(command, userNPMPath);
174
- if (pathFound) {
175
- console.log(`[DETECTOR] Found ${toolName} in user npm-global: ${pathFound}`);
176
- return pathFound;
244
+ // Check multiple Unix-like locations
245
+ const unixPaths = [
246
+ path.join(os.homedir(), '.npm-global', 'bin'),
247
+ path.join(os.homedir(), '.npm', 'bin'),
248
+ '/usr/local/bin',
249
+ '/usr/bin',
250
+ path.join(os.homedir(), '.local', 'bin'),
251
+ '/root/.npm-global/bin',
252
+ '/root/.npm/bin'
253
+ ];
254
+
255
+ for (const dir of unixPaths) {
256
+ pathFound = this.checkCommandInDir(command, dir);
257
+ if (pathFound) {
258
+ console.log(`[DETECTOR] Found ${toolName} in ${dir}: ${pathFound}`);
259
+ return pathFound;
260
+ }
177
261
  }
178
262
  }
179
263
  }
@@ -182,6 +266,59 @@ class CLIPathDetector {
182
266
  return null;
183
267
  }
184
268
 
269
+ /**
270
+ * Find command using npm's actual global installation path
271
+ */
272
+ async findCommandViaNPM(command) {
273
+ try {
274
+ const { spawnSync } = require('child_process');
275
+
276
+ // Get npm global prefix
277
+ const npmPrefixResult = spawnSync('npm', ['config', 'get', 'prefix'], {
278
+ encoding: 'utf8',
279
+ shell: true
280
+ });
281
+
282
+ if (npmPrefixResult.status === 0 && npmPrefixResult.stdout.trim()) {
283
+ const npmPrefix = npmPrefixResult.stdout.trim();
284
+ let binDir;
285
+
286
+ if (this.platform === 'win32') {
287
+ binDir = npmPrefix; // Windows: prefix already points to the directory with executables
288
+ } else {
289
+ binDir = path.join(npmPrefix, 'bin'); // Unix: bin subdirectory
290
+ }
291
+
292
+ const commandPath = this.checkCommandInDir(command, binDir);
293
+ if (commandPath) {
294
+ return commandPath;
295
+ }
296
+ }
297
+
298
+ // Try alternative npm config methods
299
+ const npmListResult = spawnSync('npm', ['list', '-g', '--depth=0'], {
300
+ encoding: 'utf8',
301
+ shell: true
302
+ });
303
+
304
+ if (npmListResult.status === 0) {
305
+ // Extract global prefix from npm list output if needed
306
+ const lines = npmListResult.stdout.split('\n');
307
+ for (const line of lines) {
308
+ if (line.includes(`${command}@`)) {
309
+ // Package is installed globally, try to find it in common locations
310
+ return null; // Fall back to other methods
311
+ }
312
+ }
313
+ }
314
+
315
+ return null;
316
+ } catch (error) {
317
+ console.log(`[DETECTOR] npm query failed: ${error.message}`);
318
+ return null;
319
+ }
320
+ }
321
+
185
322
  /**
186
323
  * Detect all CLI tool paths
187
324
  */