stigmergy 1.2.13 → 1.3.2-beta.1

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.
Files changed (50) hide show
  1. package/README.md +39 -3
  2. package/STIGMERGY.md +3 -0
  3. package/config/enhanced-cli-config.json +438 -0
  4. package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
  5. package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
  6. package/docs/INSTALLER_ARCHITECTURE.md +257 -0
  7. package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
  8. package/package.json +16 -5
  9. package/scripts/analyze-router.js +168 -0
  10. package/scripts/run-comprehensive-tests.js +230 -0
  11. package/scripts/run-quick-tests.js +90 -0
  12. package/scripts/test-runner.js +344 -0
  13. package/src/cli/commands/autoinstall.js +158 -0
  14. package/src/cli/commands/errors.js +190 -0
  15. package/src/cli/commands/install.js +142 -0
  16. package/src/cli/commands/permissions.js +108 -0
  17. package/src/cli/commands/project.js +449 -0
  18. package/src/cli/commands/resume.js +136 -0
  19. package/src/cli/commands/scan.js +97 -0
  20. package/src/cli/commands/skills.js +158 -0
  21. package/src/cli/commands/status.js +106 -0
  22. package/src/cli/commands/system.js +301 -0
  23. package/src/cli/router-beta.js +477 -0
  24. package/src/cli/utils/environment.js +75 -0
  25. package/src/cli/utils/formatters.js +47 -0
  26. package/src/cli/utils/skills_cache.js +92 -0
  27. package/src/core/cache_cleaner.js +1 -0
  28. package/src/core/cli_adapters.js +345 -0
  29. package/src/core/cli_help_analyzer.js +473 -1
  30. package/src/core/cli_path_detector.js +2 -1
  31. package/src/core/cli_tools.js +107 -0
  32. package/src/core/coordination/nodejs/HookDeploymentManager.js +204 -416
  33. package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
  34. package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
  35. package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +703 -0
  36. package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1210 -0
  37. package/src/core/coordination/nodejs/generators/index.js +12 -0
  38. package/src/core/enhanced_cli_installer.js +375 -31
  39. package/src/core/enhanced_cli_parameter_handler.js +395 -0
  40. package/src/core/execution_mode_detector.js +222 -0
  41. package/src/core/installer.js +83 -67
  42. package/src/core/local_skill_scanner.js +732 -0
  43. package/src/core/multilingual/language-pattern-manager.js +1 -1
  44. package/src/core/skills/StigmergySkillManager.js +26 -8
  45. package/src/core/smart_router.js +279 -2
  46. package/src/index.js +10 -4
  47. package/test/cli-integration.test.js +304 -0
  48. package/test/enhanced-cli-agent-skill-test.js +485 -0
  49. package/test/specific-cli-agent-skill-analysis.js +385 -0
  50. package/src/cli/router.js +0 -1783
@@ -6,9 +6,11 @@ const inquirer = require('inquirer');
6
6
  const SmartRouter = require('./smart_router');
7
7
  const { errorHandler } = require('./error_handler');
8
8
  const MemoryManager = require('./memory_manager');
9
+ const EnhancedCLIInstaller = require('./enhanced_cli_installer');
9
10
 
10
- class StigmergyInstaller {
11
- constructor() {
11
+ class StigmergyInstaller extends EnhancedCLIInstaller {
12
+ constructor(options = {}) {
13
+ super(options);
12
14
  this.router = new SmartRouter();
13
15
  this.memory = new MemoryManager();
14
16
  this.configDir = path.join(os.homedir(), '.stigmergy');
@@ -48,36 +50,38 @@ class StigmergyInstaller {
48
50
  codexPath.endsWith('/codex') ||
49
51
  codexPath.endsWith('\\codex')
50
52
  ) {
51
- // Read the script to find the JS file path
52
- const fsSync = require('fs');
53
- const scriptContent = fsSync.readFileSync(codexPath, 'utf8');
54
-
55
- // Look for JS file reference in the script
56
- const jsFileMatch = scriptContent.match(
57
- /(["'])(.*?codex\.js.*?)\1/,
58
- );
59
- if (jsFileMatch) {
60
- const jsFilePath = jsFileMatch[2];
61
- // Check if JS file exists and is not empty
62
- if (fsSync.existsSync(jsFilePath)) {
63
- const stats = fsSync.statSync(jsFilePath);
64
- if (stats.size === 0) {
65
- console.log(
66
- '[DEBUG] Codex JS file is empty, marking as unavailable',
67
- );
68
- return false;
53
+ // Try to verify JS file, but don't fail if we can't
54
+ // The actual --version test below is more reliable
55
+ try {
56
+ const fsSync = require('fs');
57
+ const scriptContent = fsSync.readFileSync(codexPath, 'utf8');
58
+
59
+ // Look for JS file reference in the script
60
+ // Match node_modules/@openai/codex/bin/codex.js pattern
61
+ const jsFileMatch = scriptContent.match(/node_modules\/@openai\/codex\/bin\/codex\.js/);
62
+ if (jsFileMatch) {
63
+ // Construct actual path based on npm global directory
64
+ const npmGlobalDir = require('path').dirname(codexPath);
65
+ const jsFilePath = require('path').join(npmGlobalDir, jsFileMatch[0]);
66
+
67
+ if (fsSync.existsSync(jsFilePath)) {
68
+ const stats = fsSync.statSync(jsFilePath);
69
+ if (stats.size === 0) {
70
+ console.log('[DEBUG] Codex JS file is empty, marking as unavailable');
71
+ return false;
72
+ }
73
+ // File exists and has content - continue to version check
74
+ } else {
75
+ console.log('[DEBUG] Codex JS file not found at expected path, will try version check');
69
76
  }
70
- } else {
71
- console.log(
72
- '[DEBUG] Codex JS file does not exist, marking as unavailable',
73
- );
74
- return false;
75
77
  }
78
+ } catch (scriptError) {
79
+ console.log(`[DEBUG] Could not verify codex script: ${scriptError.message}`);
80
+ // Continue anyway - the version check below is more reliable
76
81
  }
77
82
  }
78
83
 
79
- // If we got here, the codex command exists and seems valid
80
- // Continue with normal checks below
84
+ // If we got here, the codex command exists - continue with normal checks below
81
85
  } else {
82
86
  // Codex command doesn't exist
83
87
  return false;
@@ -109,8 +113,9 @@ class StigmergyInstaller {
109
113
  };
110
114
 
111
115
  // Additional protection for codex
116
+ // Note: codex requires shell=true on Windows to work properly
112
117
  if (toolName === 'codex') {
113
- testOptions.shell = false;
118
+ // Keep shell=true for codex (don't override)
114
119
  testOptions.windowsHide = true;
115
120
  testOptions.detached = false;
116
121
  }
@@ -132,6 +137,7 @@ class StigmergyInstaller {
132
137
  // Special handling for codex to avoid opening files
133
138
  if (toolName === 'codex') {
134
139
  // For codex, only try --help and --version with extra precautions
140
+ // Note: codex requires shell=true on Windows
135
141
  const codexChecks = [
136
142
  { args: ['--help'], expected: 0 },
137
143
  { args: ['--version'], expected: 0 },
@@ -143,7 +149,7 @@ class StigmergyInstaller {
143
149
  encoding: 'utf8',
144
150
  timeout: 10000,
145
151
  stdio: ['pipe', 'pipe', 'pipe'], // Ensure all IO is piped
146
- shell: false, // Don't use shell to avoid extra window opening
152
+ shell: true, // Use shell for codex compatibility
147
153
  windowsHide: true, // Hide console window on Windows
148
154
  detached: false, // Don't detach process
149
155
  });
@@ -205,6 +211,12 @@ class StigmergyInstaller {
205
211
  const missing = {};
206
212
 
207
213
  for (const [toolName, toolInfo] of Object.entries(this.router.tools)) {
214
+ // Skip internal functions without install command
215
+ if (!toolInfo.install) {
216
+ console.log(`[DEBUG] Tool ${toolName} has no version/install info, skipping check`);
217
+ continue;
218
+ }
219
+
208
220
  try {
209
221
  console.log(`[SCAN] Checking ${toolInfo.name}...`);
210
222
  const isAvailable = await this.checkCLI(toolName);
@@ -305,52 +317,56 @@ class StigmergyInstaller {
305
317
 
306
318
  /**
307
319
  * Install selected CLI tools
320
+ * 统一调用父类EnhancedCLIInstaller的实现
308
321
  */
309
322
  async installTools(selectedTools, missingTools) {
310
- const chalk = require('chalk');
311
- let successCount = 0;
312
-
313
- for (const toolName of selectedTools) {
314
- const toolInfo = missingTools[toolName];
315
- if (!toolInfo) continue;
316
-
317
- console.log(`\n[INSTALL] Installing ${toolInfo.name}...`);
318
- console.log(chalk.yellow(`Command: ${toolInfo.install}`));
319
-
320
- try {
321
- // Parse the install command
322
- const [command, ...args] = toolInfo.install.split(' ');
323
-
324
- // Execute the installation command
325
- const result = spawnSync(command, args, {
326
- stdio: 'inherit', // Show output in real-time
327
- shell: true, // Use shell for npm commands
328
- encoding: 'utf-8'
329
- });
330
-
331
- if (result.status === 0) {
332
- console.log(chalk.green(`[OK] Successfully installed ${toolInfo.name}`));
333
- successCount++;
334
- } else {
335
- console.log(chalk.red(`[ERROR] Failed to install ${toolInfo.name}. Exit code: ${result.status}`));
336
- // Continue with other tools
323
+ // 调用父类的增强安装功能
324
+ const result = await super.installTools(selectedTools, missingTools);
325
+
326
+ // 保留StigmergyInstaller的特有功能:生成cross-CLI hooks
327
+ if (result && result.successful > 0) {
328
+ console.log('\n[HOOKS] Generating cross-CLI integration hooks...');
329
+ for (const toolName of selectedTools) {
330
+ const toolInfo = missingTools[toolName];
331
+ if (toolInfo && this.results.installations[toolName]?.success) {
332
+ try {
333
+ await this.generateToolHook(toolName, toolInfo);
334
+ } catch (error) {
335
+ console.log(`[WARN] Failed to generate hook for ${toolName}: ${error.message}`);
336
+ }
337
337
  }
338
- } catch (error) {
339
- console.log(chalk.red(`[ERROR] Installation failed for ${toolInfo.name}: ${error.message}`));
340
- // Continue with other tools
341
338
  }
342
339
  }
343
340
 
344
- if (successCount > 0) {
345
- console.log(chalk.green(`\n[INSTALL] Successfully installed ${successCount}/${selectedTools.length} tools`));
341
+ return result;
342
+ }
346
343
 
347
- // Add a short delay to ensure installations are complete
348
- await new Promise(resolve => setTimeout(resolve, 2000));
344
+ /**
345
+ * Generate hook for a specific CLI tool
346
+ * @param {string} toolName - Name of the CLI tool
347
+ * @param {Object} toolInfo - Tool information object
348
+ */
349
+ async generateToolHook(toolName, toolInfo) {
350
+ console.log(`[HOOK] Generating hook for ${toolName}...`);
349
351
 
350
- return true;
351
- } else {
352
- console.log(chalk.red('[INSTALL] No tools were successfully installed'));
353
- return false;
352
+ const HookDeploymentManager = require('./coordination/nodejs/HookDeploymentManager');
353
+ const hookManager = new HookDeploymentManager();
354
+
355
+ await hookManager.initialize();
356
+
357
+ try {
358
+ const deploySuccess = await hookManager.deployHooksForCLI(toolName);
359
+
360
+ if (deploySuccess) {
361
+ console.log(`[OK] Hook generated successfully for ${toolName}`);
362
+ return true;
363
+ } else {
364
+ console.log(`[WARN] Hook generation failed for ${toolName}`);
365
+ return false;
366
+ }
367
+ } catch (error) {
368
+ console.error(`[ERROR] Hook generation error for ${toolName}:`, error.message);
369
+ throw error;
354
370
  }
355
371
  }
356
372