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
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Install Command Module
3
+ * Handles CLI tool installation commands
4
+ */
5
+
6
+ const StigmergyInstaller = require('../../core/installer');
7
+ const chalk = require('chalk');
8
+ const { ensureSkillsCache } = require('../utils/skills_cache');
9
+
10
+ /**
11
+ * Handle install command
12
+ * @param {Object} options - Command options
13
+ * @param {string} options.cli - Specific CLI to install
14
+ * @param {boolean} options.verbose - Verbose output
15
+ * @param {boolean} options.force - Force installation
16
+ */
17
+ async function handleInstallCommand(options = {}) {
18
+ const installer = new StigmergyInstaller();
19
+
20
+ try {
21
+ // Initialize or update skills/agents cache
22
+ await ensureSkillsCache({ verbose: options.verbose || process.env.DEBUG === 'true' });
23
+
24
+ console.log(chalk.blue('šŸš€ Starting CLI tools installation...'));
25
+
26
+ // Handle auto-install mode (non-interactive)
27
+ if (options.nonInteractive) {
28
+ console.log(chalk.blue('[AUTO-INSTALL] Running in non-interactive mode'));
29
+
30
+ // Scan for available and missing tools
31
+ const { missing: missingTools, available: availableTools } = await installer.scanCLI();
32
+
33
+ if (Object.keys(missingTools).length === 0) {
34
+ console.log(chalk.green('āœ… All AI CLI tools are already installed!'));
35
+ return {
36
+ success: true,
37
+ installed: [],
38
+ existing: Object.keys(availableTools)
39
+ };
40
+ }
41
+
42
+ // Install all missing tools in auto mode
43
+ const selectedTools = Object.keys(missingTools);
44
+ console.log(chalk.blue(`[AUTO-INSTALL] Installing ${selectedTools.length} tools: ${selectedTools.join(', ')}`));
45
+
46
+ const installResult = await installer.installTools(selectedTools, missingTools);
47
+
48
+ if (installResult.success) {
49
+ console.log(chalk.green('āœ… Auto-install completed successfully!'));
50
+ return {
51
+ success: true,
52
+ installed: installResult.installed || [],
53
+ failed: installResult.failed || [],
54
+ existing: Object.keys(availableTools)
55
+ };
56
+ } else {
57
+ console.log(chalk.yellow('āš ļø Some tools may not have installed successfully'));
58
+ return {
59
+ success: false,
60
+ installed: installResult.installed || [],
61
+ failed: installResult.failed || [],
62
+ existing: Object.keys(availableTools),
63
+ error: 'Some installations failed'
64
+ };
65
+ }
66
+ }
67
+
68
+ // Interactive install mode
69
+ const { missing: missingTools, available: availableTools } = await installer.scanCLI();
70
+
71
+ if (Object.keys(missingTools).length === 0) {
72
+ console.log(chalk.green('āœ… All AI CLI tools are already installed!'));
73
+
74
+ if (Object.keys(availableTools).length > 0) {
75
+ console.log(chalk.cyan('\nšŸ“¦ Available tools:'));
76
+ Object.keys(availableTools).forEach(tool => {
77
+ console.log(` āœ… ${tool}`);
78
+ });
79
+ }
80
+
81
+ return {
82
+ success: true,
83
+ installed: [],
84
+ existing: Object.keys(availableTools)
85
+ };
86
+ }
87
+
88
+ console.log(chalk.yellow(`\nāš ļø Found ${Object.keys(missingTools).length} missing tools:`));
89
+ Object.entries(missingTools).forEach(([toolName, toolInfo]) => {
90
+ console.log(` - ${toolInfo.name}: ${toolInfo.install}`);
91
+ });
92
+
93
+ // For now, install all missing tools
94
+ const selectedTools = Object.keys(missingTools);
95
+ const installResult = await installer.installTools(selectedTools, missingTools);
96
+
97
+ if (installResult.success) {
98
+ console.log(chalk.green('āœ… Installation completed successfully!'));
99
+
100
+ if (installResult.installed && installResult.installed.length > 0) {
101
+ console.log(chalk.cyan('\nšŸ“¦ Installed tools:'));
102
+ installResult.installed.forEach(tool => {
103
+ console.log(` āœ… ${tool}`);
104
+ });
105
+ }
106
+
107
+ if (installResult.failed && installResult.failed.length > 0) {
108
+ console.log(chalk.red('\nāŒ Failed tools:'));
109
+ installResult.failed.forEach(tool => {
110
+ console.log(` āŒ ${tool}`);
111
+ });
112
+ }
113
+
114
+ return {
115
+ success: true,
116
+ installed: installResult.installed || [],
117
+ failed: installResult.failed || [],
118
+ existing: Object.keys(availableTools)
119
+ };
120
+ } else {
121
+ console.log(chalk.red('āŒ Installation failed!'));
122
+ return {
123
+ success: false,
124
+ installed: installResult.installed || [],
125
+ failed: installResult.failed || [],
126
+ existing: Object.keys(availableTools),
127
+ error: 'Installation failed'
128
+ };
129
+ }
130
+ } catch (error) {
131
+ console.log(chalk.red(`āŒ Installation error: ${error.message}`));
132
+ return {
133
+ success: false,
134
+ error: error.message,
135
+ installed: []
136
+ };
137
+ }
138
+ }
139
+
140
+ module.exports = {
141
+ handleInstallCommand
142
+ };
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Permission Management Commands
3
+ * Modular implementation for fix-perms and perm-check commands
4
+ */
5
+
6
+ const chalk = require('chalk');
7
+ const DirectoryPermissionManager = require('../../core/directory_permission_manager');
8
+
9
+ /**
10
+ * Handle permission check command
11
+ * @param {Object} options - Command options
12
+ */
13
+ async function handlePermCheckCommand(options = {}) {
14
+ try {
15
+ console.log(chalk.cyan('[PERM-CHECK] Checking current directory permissions...\n'));
16
+
17
+ const permissionManager = new DirectoryPermissionManager({
18
+ verbose: options.verbose || process.env.DEBUG === 'true'
19
+ });
20
+
21
+ const hasWritePermission = await permissionManager.checkWritePermission();
22
+
23
+ console.log(`šŸ“ Current directory: ${process.cwd()}`);
24
+ console.log(`šŸ”§ Write permission: ${hasWritePermission ? chalk.green('āœ… Yes') : chalk.red('āŒ No')}`);
25
+
26
+ if (!hasWritePermission) {
27
+ console.log('\nšŸ’” Suggestions:');
28
+ console.log('1. Run: stigmergy fix-perms # Fix permissions automatically');
29
+ console.log('2. Change to user directory: cd ~');
30
+ console.log('3. Create project directory: mkdir ~/stigmergy && cd ~/stigmergy');
31
+
32
+ console.log('\nšŸ” System Info:');
33
+ const sysInfo = permissionManager.getSystemInfo();
34
+ console.log(` Platform: ${sysInfo.platform}`);
35
+ console.log(` Shell: ${sysInfo.shell}`);
36
+ console.log(` Home: ${sysInfo.homeDir}`);
37
+ } else {
38
+ console.log(chalk.green('\nāœ… Directory permissions are OK!'));
39
+ }
40
+
41
+ return { success: true, hasWritePermission };
42
+ } catch (error) {
43
+ console.error(chalk.red('[ERROR] Permission check failed:'), error.message);
44
+ return { success: false, error: error.message };
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Handle fix permissions command
50
+ * @param {Object} options - Command options
51
+ */
52
+ async function handleFixPermsCommand(options = {}) {
53
+ try {
54
+ console.log(chalk.cyan('[FIX-PERMS] Setting up working directory with proper permissions...\n'));
55
+
56
+ // Using DirectoryPermissionManager for permission handling
57
+ // This provides the core permission management functionality
58
+ const permissionManager = new DirectoryPermissionManager({
59
+ verbose: options.verbose || process.env.DEBUG === 'true',
60
+ createStigmergyDir: true
61
+ });
62
+
63
+ const hasWritePermission = await permissionManager.checkWritePermission();
64
+
65
+ if (hasWritePermission) {
66
+ console.log(chalk.green('āœ… Current directory already has proper permissions!'));
67
+ return { success: true, alreadyFixed: true };
68
+ }
69
+
70
+ console.log(chalk.yellow('šŸ”§ Attempting to fix permissions...'));
71
+
72
+ // Try to create a .stigmergy directory in user home as fallback
73
+ const fs = require('fs').promises;
74
+ const path = require('path');
75
+ const os = require('os');
76
+
77
+ const stigmergyDir = path.join(os.homedir(), '.stigmergy');
78
+
79
+ try {
80
+ await fs.mkdir(stigmergyDir, { recursive: true });
81
+ console.log(chalk.green(`āœ… Created Stigmergy directory: ${stigmergyDir}`));
82
+ console.log(chalk.yellow('šŸ’” Consider changing to this directory for your projects'));
83
+
84
+ return { success: true, createdDirectory: stigmergyDir };
85
+ } catch (mkdirError) {
86
+ console.log(chalk.red('āŒ Could not create directory or fix permissions'));
87
+ console.log(chalk.red(`Error: ${mkdirError.message}`));
88
+
89
+ console.log('\nšŸ”§ Manual fix required:');
90
+ console.log('1. Run in a directory where you have write permissions');
91
+ console.log('2. Try: cd ~ && mkdir stigmergy-workspace && cd stigmergy-workspace');
92
+
93
+ return { success: false, error: mkdirError.message };
94
+ }
95
+
96
+ } catch (error) {
97
+ console.error(chalk.red('[ERROR] Permission setup failed:'), error.message);
98
+ if (options.verbose) {
99
+ console.error(error.stack);
100
+ }
101
+ return { success: false, error: error.message };
102
+ }
103
+ }
104
+
105
+ module.exports = {
106
+ handlePermCheckCommand,
107
+ handleFixPermsCommand
108
+ };
@@ -0,0 +1,449 @@
1
+ /**
2
+ * Project Commands
3
+ * Modular implementation for init, setup, deploy, upgrade, call commands
4
+ */
5
+
6
+ const chalk = require('chalk');
7
+ const { handleStatusCommand } = require('./status');
8
+ const path = require('path');
9
+ const os = require('os');
10
+ const { getCLIPath, setupCLIPaths } = require('../../core/cli_tools');
11
+ const SmartRouter = require('../../core/smart_router');
12
+ const EnhancedCLIInstaller = require('../../core/enhanced_cli_installer');
13
+ const StigmergyInstaller = require('../../core/installer');
14
+ const { executeCommand } = require('../../utils');
15
+ const LocalSkillScanner = require('../../core/local_skill_scanner');
16
+ const CLIHelpAnalyzer = require('../../core/cli_help_analyzer');
17
+ const { CLI_TOOLS } = require('../../core/cli_tools');
18
+ const { ensureSkillsCache } = require('../utils/skills_cache');
19
+
20
+ // Import execution mode detection and CLI adapters
21
+ const ExecutionModeDetector = require('../../core/execution_mode_detector');
22
+ const { CLIAdapterManager } = require('../../core/cli_adapters');
23
+
24
+ // Create instances
25
+ const modeDetector = new ExecutionModeDetector();
26
+ const cliAdapterManager = new CLIAdapterManager();
27
+
28
+ /**
29
+ * Handle upgrade command
30
+ * @param {Object} options - Command options
31
+ */
32
+ async function handleUpgradeCommand(options = {}) {
33
+ try {
34
+ console.log(chalk.cyan('[UPGRADE] Starting AI CLI tools upgrade process...\n'));
35
+
36
+ // Initialize or update skills/agents cache
37
+ await ensureSkillsCache({ verbose: process.env.DEBUG === 'true' });
38
+
39
+ const upgradeOptions = {
40
+ dryRun: options.dryRun || false,
41
+ force: options.force || false,
42
+ verbose: options.verbose || process.env.DEBUG === 'true'
43
+ };
44
+
45
+ // Use enhanced CLI installer for upgrade
46
+ const enhancedInstaller = new EnhancedCLIInstaller({
47
+ verbose: upgradeOptions.verbose,
48
+ autoRetry: true,
49
+ maxRetries: 2
50
+ });
51
+
52
+ // Get installed tools
53
+ const installer = new StigmergyInstaller({ verbose: upgradeOptions.verbose });
54
+ const { available: installedTools } = await installer.scanCLI();
55
+
56
+ if (Object.keys(installedTools).length === 0) {
57
+ console.log(chalk.yellow('[INFO] No CLI tools found to upgrade'));
58
+ console.log(chalk.blue('šŸ’” Run: stigmergy install to install CLI tools first'));
59
+ return { success: true, upgraded: 0 };
60
+ }
61
+
62
+ console.log(chalk.blue(`[INFO] Found ${Object.keys(installedTools).length} CLI tools to upgrade`));
63
+
64
+ if (upgradeOptions.dryRun) {
65
+ console.log(chalk.yellow('[DRY RUN] Would upgrade the following tools:'));
66
+ Object.keys(installedTools).forEach(tool => {
67
+ console.log(` • ${tool}`);
68
+ });
69
+ return { success: true, upgraded: Object.keys(installedTools).length };
70
+ }
71
+
72
+ // Perform upgrade
73
+ console.log(chalk.blue('[INFO] Starting upgrade process...'));
74
+ const toolsToUpgrade = Object.keys(installedTools);
75
+
76
+ const upgradeResult = await enhancedInstaller.upgradeTools(toolsToUpgrade, installedTools);
77
+
78
+ if (upgradeResult) {
79
+ console.log(chalk.green(`\nāœ… Successfully upgraded ${toolsToUpgrade.length} CLI tools!`));
80
+ return { success: true, upgraded: toolsToUpgrade.length };
81
+ } else {
82
+ console.log(chalk.red('\nāŒ Upgrade process encountered issues'));
83
+ return { success: false, upgraded: 0 };
84
+ }
85
+
86
+ } catch (error) {
87
+ console.error(chalk.red('[ERROR] Upgrade failed:'), error.message);
88
+ if (options.verbose) {
89
+ console.error(error.stack);
90
+ }
91
+ return { success: false, error: error.message };
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Handle deploy command
97
+ * @param {Object} options - Command options
98
+ */
99
+ async function handleDeployCommand(options = {}) {
100
+ try {
101
+ console.log(chalk.cyan('[DEPLOY] Starting hook deployment...\n'));
102
+
103
+ const installer = new StigmergyInstaller({ verbose: options.verbose });
104
+ const { available: deployedTools } = await installer.scanCLI();
105
+
106
+ if (Object.keys(deployedTools).length === 0) {
107
+ console.log(chalk.yellow('[INFO] No CLI tools found for deployment'));
108
+ console.log(chalk.blue('šŸ’” Run: stigmergy install to install CLI tools first'));
109
+ return { success: true, deployed: 0 };
110
+ }
111
+
112
+ console.log(chalk.blue(`[INFO] Deploying hooks for ${Object.keys(deployedTools).length} tools...`));
113
+
114
+ await installer.deployHooks(deployedTools);
115
+
116
+ console.log(chalk.green('\nāœ… Hook deployment completed successfully!'));
117
+ return { success: true, deployed: Object.keys(deployedTools).length };
118
+
119
+ } catch (error) {
120
+ console.error(chalk.red('[ERROR] Deployment failed:'), error.message);
121
+ return { success: false, error: error.message };
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Handle init command
127
+ * @param {Object} options - Command options
128
+ */
129
+ async function handleInitCommand(options = {}) {
130
+ try {
131
+ console.log(chalk.cyan('[INIT] Initializing Stigmergy project in current directory...\n'));
132
+
133
+ // Initialize or update skills/agents cache
134
+ await ensureSkillsCache({ verbose: true });
135
+
136
+ // Quick path detection for better tool availability
137
+ console.log(chalk.blue('[INIT] Detecting CLI tool paths...'));
138
+ const pathSetup = await setupCLIPaths();
139
+
140
+ console.log(`[INIT] CLI tool detection: ${pathSetup.report.summary.found}/${pathSetup.report.summary.total} tools found`);
141
+
142
+ // Quick setup for basic project structure
143
+ const projectDir = process.cwd();
144
+ const stigmergyDir = path.join(projectDir, '.stigmergy');
145
+
146
+ const fs = require('fs').promises;
147
+
148
+ // Create .stigmergy directory
149
+ await fs.mkdir(stigmergyDir, { recursive: true });
150
+
151
+ // Create basic config
152
+ const config = {
153
+ version: '1.3.0-beta.0',
154
+ created: new Date().toISOString(),
155
+ project: path.basename(projectDir)
156
+ };
157
+
158
+ await fs.writeFile(
159
+ path.join(stigmergyDir, 'config.json'),
160
+ JSON.stringify(config, null, 2)
161
+ );
162
+
163
+ console.log(chalk.green(`āœ… Stigmergy project initialized in: ${projectDir}`));
164
+ console.log(chalk.blue(`šŸ“ Configuration created: ${stigmergyDir}/config.json`));
165
+ console.log(chalk.gray('\nšŸ’” Next steps:'));
166
+ console.log(chalk.gray(' • stigmergy install # Install CLI tools'));
167
+ console.log(chalk.gray(' • stigmergy deploy # Deploy integration hooks'));
168
+ console.log(chalk.gray(' • stigmergy status # Check tool status'));
169
+
170
+ if (pathSetup.report.summary.missing > 0) {
171
+ console.log(chalk.gray('\nšŸ’” For full CLI integration, run:'));
172
+ console.log(chalk.gray(' • stigmergy setup # Complete setup with PATH configuration'));
173
+ }
174
+
175
+ return { success: true, projectDir };
176
+
177
+ } catch (error) {
178
+ console.error(chalk.red('[ERROR] Initialization failed:'), error.message);
179
+ return { success: false, error: error.message };
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Handle setup command
185
+ * @param {Object} options - Command options
186
+ */
187
+ async function handleSetupCommand(options = {}) {
188
+ try {
189
+ console.log(chalk.cyan('[SETUP] Starting complete Stigmergy setup...\n'));
190
+
191
+ // Initialize or update skills/agents cache (explicit call, will also be called in init)
192
+ await ensureSkillsCache({ verbose: true });
193
+
194
+ // Step 0: Setup CLI paths detection and configuration
195
+ console.log(chalk.blue('[STEP 0] Setting up CLI path detection...'));
196
+ const pathSetup = await setupCLIPaths();
197
+
198
+ console.log(`[PATH] Path detection complete:`);
199
+ console.log(` - Found: ${pathSetup.report.summary.found} CLI tools`);
200
+ console.log(` - Missing: ${pathSetup.report.summary.missing} CLI tools`);
201
+
202
+ if (pathSetup.pathStatus.updated) {
203
+ console.log(chalk.green('\n[PATH] āœ“ All npm global directories are now available in PATH'));
204
+ console.log(chalk.gray('[PATH] CLI tools will be globally accessible after terminal restart'));
205
+ } else {
206
+ console.log(chalk.yellow('\n[PATH] āš ļø PATH update failed:'));
207
+ console.log(chalk.gray(` Error: ${pathSetup.pathStatus.message}`));
208
+ console.log(chalk.gray('\n[PATH] Manual update required:'));
209
+ console.log(chalk.gray(' Run the generated scripts to update PATH:'));
210
+ if (pathSetup.pathStatus.scriptPath) {
211
+ console.log(chalk.gray(` - Script directory: ${pathSetup.pathStatus.scriptPath}`));
212
+ }
213
+ console.log(chalk.gray(' - Windows: Run PowerShell as Administrator and execute the scripts'));
214
+ console.log(chalk.gray(' - Unix/Linux: Source the shell script (source update-path.sh)'));
215
+ }
216
+
217
+ // Initialize project (will call ensureSkillsCache again, that's ok)
218
+ await handleInitCommand({ verbose: options.verbose });
219
+
220
+ // Install CLI tools
221
+ const installer = new StigmergyInstaller({ verbose: options.verbose });
222
+ const { available: setupAvailable, missing: setupMissing } = await installer.scanCLI();
223
+
224
+ if (Object.keys(setupMissing).length > 0) {
225
+ console.log(chalk.yellow('\n[STEP 1] Missing tools found:'));
226
+ for (const [toolName, toolInfo] of Object.entries(setupMissing)) {
227
+ console.log(` - ${toolInfo.name}: ${toolInfo.install}`);
228
+ }
229
+
230
+ console.log(chalk.blue('\n[INFO] To install missing tools, run:'));
231
+ for (const [toolName, toolInfo] of Object.entries(setupMissing)) {
232
+ console.log(` ${toolInfo.install}`);
233
+ }
234
+ } else {
235
+ console.log(chalk.green('\n[STEP 1] All required tools are already installed!'));
236
+ }
237
+
238
+ // Deploy hooks to available CLI tools
239
+ if (Object.keys(setupAvailable).length > 0) {
240
+ console.log(chalk.blue('\n[STEP 2] Deploying hooks to available tools...'));
241
+ await installer.deployHooks(setupAvailable);
242
+ } else {
243
+ console.log(chalk.yellow('\n[STEP 2] No tools available for hook deployment'));
244
+ }
245
+
246
+ // Verify setup
247
+ console.log(chalk.blue('\n[STEP 3] Verifying installation...'));
248
+ await handleStatusCommand({ verbose: false });
249
+
250
+ console.log(chalk.green('\nšŸŽ‰ Setup completed successfully!'));
251
+ console.log(chalk.blue('\n[USAGE] Get started with these commands:'));
252
+ console.log(chalk.gray(' stigmergy d - System diagnostic (recommended first)'));
253
+ console.log(chalk.gray(' stigmergy inst - Install missing AI CLI tools'));
254
+ console.log(chalk.gray(' stigmergy deploy - Deploy hooks to installed tools'));
255
+ console.log(chalk.gray(' stigmergy call - Execute prompts with auto-routing'));
256
+
257
+ return { success: true };
258
+
259
+ } catch (error) {
260
+ console.error(chalk.red('[ERROR] Setup failed:'), error.message);
261
+ return { success: false, error: error.message };
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Get working directory for a specific CLI tool
267
+ */
268
+ function getWorkingDirectoryForTool(toolName) {
269
+ const toolConfig = CLI_TOOLS[toolName];
270
+ if (toolConfig && toolConfig.workingDirectory) {
271
+ return toolConfig.workingDirectory;
272
+ }
273
+ return process.cwd();
274
+ }
275
+
276
+ /**
277
+ * Get environment for a specific CLI tool
278
+ */
279
+ function getEnvironmentForTool(toolName) {
280
+ const env = { ...process.env };
281
+
282
+ // Tool-specific environment handling
283
+ if (toolName === 'qwen') {
284
+ // Qwen CLI requires NODE_PATH to be unset
285
+ delete env.NODE_PATH;
286
+ }
287
+
288
+ return env;
289
+ }
290
+
291
+ /**
292
+ * Add OAuth authentication arguments to command args
293
+ */
294
+ function addOAuthAuthArgs(toolName, args = []) {
295
+ const toolConfig = CLI_TOOLS[toolName];
296
+
297
+ if (toolConfig && toolConfig.oauth) {
298
+ const oauth = toolConfig.oauth;
299
+ if (oauth.authRequired) {
300
+ // Qwen-specific OAuth handling
301
+ if (toolName === 'qwen' && process.env.QWEN_ACCESS_TOKEN) {
302
+ return [...args, '--access-token', process.env.QWEN_ACCESS_TOKEN];
303
+ }
304
+ }
305
+ }
306
+
307
+ return args;
308
+ }
309
+
310
+ /**
311
+ * Execute a smart routed command with full parameter handling and mode detection
312
+ * @param {Object} route - Route object with tool and prompt
313
+ * @param {Object} options - Execution options
314
+ */
315
+ async function executeSmartRoutedCommand(route, options = {}) {
316
+ const { verbose = false, maxRetries = 3, interactive, print } = options;
317
+
318
+ try {
319
+ // Detect execution mode
320
+ const mode = modeDetector.detect({
321
+ interactive,
322
+ print,
323
+ verbose
324
+ });
325
+
326
+ const modeDescription = modeDetector.getModeDescription(mode);
327
+ if (verbose) {
328
+ console.log(chalk.gray(`[MODE] ${modeDescription}`));
329
+ }
330
+
331
+ // Get adapted arguments for the tool and mode
332
+ let toolArgs = cliAdapterManager.getArguments(route.tool, mode, route.prompt);
333
+
334
+ // Add OAuth authentication if needed
335
+ toolArgs = addOAuthAuthArgs(route.tool, toolArgs);
336
+
337
+ // Use enhanced parameter handling for one-time mode only
338
+ if (mode === 'one-time') {
339
+ const EnhancedCLIParameterHandler = require('../../core/enhanced_cli_parameter_handler');
340
+ const paramHandler = new EnhancedCLIParameterHandler();
341
+
342
+ // Generate optimized arguments with agent/skill support
343
+ const paramResult = await paramHandler.generateArgumentsWithRetry(
344
+ route.tool,
345
+ route.prompt,
346
+ {
347
+ maxRetries,
348
+ enableAgentSkillOptimization: true
349
+ }
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
+ }
360
+ } else {
361
+ if (verbose) {
362
+ console.log(chalk.gray(`[DEBUG] Adapted args: ${toolArgs.join(' ')}`));
363
+ }
364
+ }
365
+
366
+ // Get tool path
367
+ const toolPath = await getCLIPath(route.tool);
368
+ if (!toolPath) {
369
+ throw new Error(`Tool ${route.tool} not found`);
370
+ }
371
+
372
+ // Prepare execution environment
373
+ const cwd = getWorkingDirectoryForTool(route.tool);
374
+ const env = getEnvironmentForTool(route.tool);
375
+
376
+ if (verbose) {
377
+ console.log(chalk.gray(`[DEBUG] Executing: ${toolPath} ${toolArgs.join(' ')}`));
378
+ console.log(chalk.gray(`[DEBUG] Working directory: ${cwd}`));
379
+ console.log(chalk.gray(`[DEBUG] Mode: ${mode}`));
380
+ }
381
+
382
+ // Execute the command
383
+ // For interactive mode, we need stdio: 'inherit' to allow user interaction
384
+ const result = await executeCommand(toolPath, toolArgs, {
385
+ stdio: mode === 'interactive' ? 'inherit' : 'pipe',
386
+ shell: true,
387
+ cwd,
388
+ env,
389
+ timeout: 300000 // 5 minutes
390
+ });
391
+
392
+ return { success: true, tool: route.tool, result, mode };
393
+
394
+ } catch (error) {
395
+ if (verbose) {
396
+ console.error(chalk.red('[ERROR] Execution failed:'), error.message);
397
+ }
398
+ throw error;
399
+ }
400
+ }
401
+
402
+ /**
403
+ * Handle call command - Smart tool routing
404
+ * @param {string} prompt - Prompt to process
405
+ * @param {Object} options - Command options
406
+ */
407
+ async function handleCallCommand(prompt, options = {}) {
408
+ try {
409
+ if (!prompt) {
410
+ console.log(chalk.red('[ERROR] Usage: stigmergy call "<prompt>"'));
411
+ console.log(chalk.blue('\nšŸ’” Examples:'));
412
+ console.log(chalk.gray(' • stigmergy call "Write a Python function to sort a list"'));
413
+ console.log(chalk.gray(' • stigmergy call "Create a React component with TypeScript"'));
414
+ console.log(chalk.gray(' • stigmergy call "Help me debug this JavaScript code"'));
415
+ console.log(chalk.gray('\n • stigmergy call -i "Start interactive session"'));
416
+ console.log(chalk.gray(' • stigmergy call --print "Quick answer"'));
417
+ return { success: false, error: 'Prompt required' };
418
+ }
419
+
420
+ // Use smart router to determine which tool to use
421
+ const router = new SmartRouter();
422
+ await router.initialize();
423
+ const route = await router.smartRoute(prompt);
424
+
425
+ console.log(chalk.blue(`[CALL] Routing to ${route.tool}: ${route.prompt}`));
426
+
427
+ // Use enhanced execution with parameter handling and mode detection
428
+ await executeSmartRoutedCommand(route, {
429
+ verbose: options.verbose || process.env.DEBUG === 'true',
430
+ maxRetries: options.maxRetries || 3,
431
+ interactive: options.interactive,
432
+ print: options.print
433
+ });
434
+
435
+ return { success: true, tool: route.tool };
436
+
437
+ } catch (error) {
438
+ console.error(chalk.red('[ERROR] Call command failed:'), error.message);
439
+ return { success: false, error: error.message };
440
+ }
441
+ }
442
+
443
+ module.exports = {
444
+ handleUpgradeCommand,
445
+ handleDeployCommand,
446
+ handleInitCommand,
447
+ handleSetupCommand,
448
+ handleCallCommand
449
+ };