stigmergy 1.2.12 → 1.3.2-beta.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.
Files changed (48) 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 +14 -5
  9. package/scripts/analyze-router.js +168 -0
  10. package/scripts/test-runner.js +344 -0
  11. package/src/cli/commands/autoinstall.js +158 -0
  12. package/src/cli/commands/errors.js +190 -0
  13. package/src/cli/commands/install.js +142 -0
  14. package/src/cli/commands/permissions.js +108 -0
  15. package/src/cli/commands/project.js +449 -0
  16. package/src/cli/commands/resume.js +136 -0
  17. package/src/cli/commands/scan.js +97 -0
  18. package/src/cli/commands/skills.js +158 -0
  19. package/src/cli/commands/status.js +106 -0
  20. package/src/cli/commands/system.js +301 -0
  21. package/src/cli/router-beta.js +477 -0
  22. package/src/cli/utils/environment.js +75 -0
  23. package/src/cli/utils/formatters.js +47 -0
  24. package/src/cli/utils/skills_cache.js +92 -0
  25. package/src/core/cache_cleaner.js +1 -0
  26. package/src/core/cli_adapters.js +345 -0
  27. package/src/core/cli_help_analyzer.js +473 -1
  28. package/src/core/cli_path_detector.js +2 -1
  29. package/src/core/cli_tools.js +107 -0
  30. package/src/core/coordination/nodejs/HookDeploymentManager.js +185 -422
  31. package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
  32. package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
  33. package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +701 -0
  34. package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1210 -0
  35. package/src/core/coordination/nodejs/generators/index.js +12 -0
  36. package/src/core/enhanced_cli_installer.js +220 -30
  37. package/src/core/enhanced_cli_parameter_handler.js +395 -0
  38. package/src/core/execution_mode_detector.js +222 -0
  39. package/src/core/installer.js +51 -70
  40. package/src/core/local_skill_scanner.js +732 -0
  41. package/src/core/multilingual/language-pattern-manager.js +1 -1
  42. package/src/core/skills/StigmergySkillManager.js +26 -8
  43. package/src/core/smart_router.js +279 -2
  44. package/src/index.js +10 -4
  45. package/test/cli-integration.test.js +304 -0
  46. package/test/enhanced-cli-agent-skill-test.js +485 -0
  47. package/test/specific-cli-agent-skill-analysis.js +385 -0
  48. package/src/cli/router.js +0 -1737
@@ -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
+ };
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Resume Session Commands
3
+ * Modular implementation for resume/resumesession/sg-resume commands
4
+ */
5
+
6
+ const chalk = require('chalk');
7
+ const { spawnSync } = require('child_process');
8
+ const { getCLIPath } = require('../../core/cli_tools');
9
+
10
+ /**
11
+ * Handle resume session command - Forward to @stigmergy/resume CLI tool
12
+ * @param {Array} args - Arguments to pass to resumesession
13
+ * @param {Object} options - Command options
14
+ */
15
+ async function handleResumeCommand(args = [], options = {}) {
16
+ try {
17
+ console.log(chalk.blue('[RESUME] Checking for ResumeSession CLI tool...'));
18
+
19
+ // Check if resumesession command is available
20
+ const resumesessionPath = await getCLIPath('resumesession');
21
+
22
+ if (resumesessionPath) {
23
+ console.log(chalk.green(`[RESUME] Found ResumeSession at: ${resumesessionPath}`));
24
+
25
+ // Forward all arguments to the resumesession CLI tool
26
+ const resumeArgs = args; // Pass all arguments through
27
+ console.log(chalk.blue(`[RESUME] Forwarding to resumesession: ${resumeArgs.join(' ') || '(no args)'}`));
28
+
29
+ // Execute resumesession with the provided arguments
30
+ const result = spawnSync(resumesessionPath, resumeArgs, {
31
+ stdio: 'inherit',
32
+ shell: true,
33
+ cwd: process.cwd(),
34
+ env: { ...process.env, FORCE_COLOR: '1' } // Ensure colors are preserved
35
+ });
36
+
37
+ if (result.status !== 0) {
38
+ console.log(chalk.yellow(`[WARN] ResumeSession exited with code ${result.status}`));
39
+ return { success: false, exitCode: result.status, forwarded: true };
40
+ }
41
+
42
+ return { success: true, exitCode: result.status, forwarded: true };
43
+
44
+ } else {
45
+ // ResumeSession CLI tool not found
46
+ console.log(chalk.red('[ERROR] ResumeSession CLI tool not found'));
47
+ console.log(chalk.yellow('[INFO] ResumeSession is an optional component for session recovery'));
48
+
49
+ console.log(chalk.blue('\nšŸ“¦ To install ResumeSession:'));
50
+ console.log(' npm install -g @stigmergy/resume');
51
+ console.log('');
52
+ console.log(chalk.blue('šŸ”§ ResumeSession provides:'));
53
+ console.log(' • Cross-CLI session history');
54
+ console.log(' • Memory sharing between CLI tools');
55
+ console.log(' • Session recovery and continuation');
56
+ console.log(' • Centralized configuration management');
57
+ console.log('');
58
+ console.log(chalk.blue('šŸ“‹ Usage examples:'));
59
+ console.log(' stigmergy resume list # Show session history');
60
+ console.log(' stigmergy resume continue <session-id> # Continue a session');
61
+ console.log(' stigmergy resume export # Export session data');
62
+ console.log(' stigmergy resume --help # Show all options');
63
+
64
+ return { success: false, error: 'ResumeSession CLI tool not found', forwarded: false };
65
+ }
66
+
67
+ } catch (error) {
68
+ console.error(chalk.red('[ERROR] Resume command failed:'), error.message);
69
+
70
+ if (options.verbose) {
71
+ console.error(chalk.red('Stack trace:'), error.stack);
72
+ }
73
+
74
+ return { success: false, error: error.message, forwarded: false };
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Handle resumesession command alias
80
+ * @param {Array} args - Arguments
81
+ * @param {Object} options - Options
82
+ */
83
+ async function handleResumeSessionCommand(args = [], options = {}) {
84
+ return await handleResumeCommand(args, options);
85
+ }
86
+
87
+ /**
88
+ * Handle sg-resume command alias
89
+ * @param {Array} args - Arguments
90
+ * @param {Object} options - Options
91
+ */
92
+ async function handleSgResumeCommand(args = [], options = {}) {
93
+ return await handleResumeCommand(args, options);
94
+ }
95
+
96
+ /**
97
+ * Print resume help information
98
+ */
99
+ function printResumeHelp() {
100
+ console.log(chalk.cyan(`
101
+ šŸ”„ Stigmergy Resume Session System
102
+
103
+ šŸ“‹ ResumeSession forwards to the @stigmergy/resume CLI tool for session management.
104
+
105
+ šŸ› ļø Available Commands:
106
+ stigmergy resume [args] Forward to resumesession CLI
107
+ stigmergy resumesession [args] Same as resume (full name)
108
+ stigmergy sg-resume [args] Same as resume (short alias)
109
+
110
+ šŸ“¦ Requirements:
111
+ @stigmergy/resume CLI tool must be installed separately.
112
+
113
+ šŸ’¾ Installation:
114
+ npm install -g @stigmergy/resume
115
+
116
+ šŸ” Common Usage:
117
+ stigmergy resume list # Show available sessions
118
+ stigmergy resume continue <id> # Continue a specific session
119
+ stigmergy resume export # Export session data
120
+ stigmergy resume clean # Clean old sessions
121
+
122
+ šŸ“š More Information:
123
+ ResumeSession provides cross-CLI memory sharing and session recovery
124
+ capabilities, allowing you to maintain context across different AI CLI tools.
125
+
126
+ If ResumeSession is not installed, you can still use all other Stigmergy
127
+ CLI features normally.
128
+ `));
129
+ }
130
+
131
+ module.exports = {
132
+ handleResumeCommand,
133
+ handleResumeSessionCommand,
134
+ handleSgResumeCommand,
135
+ printResumeHelp
136
+ };
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Scan Command Module
3
+ * Handles CLI tool scanning and discovery commands
4
+ */
5
+
6
+ const { CLI_TOOLS } = require('../../core/cli_tools');
7
+ const chalk = require('chalk');
8
+ const { ensureSkillsCache } = require('../utils/skills_cache');
9
+
10
+ /**
11
+ * Handle scan command
12
+ * @param {Object} options - Command options
13
+ * @param {boolean} options.deep - Deep scan for CLI tools
14
+ * @param {boolean} options.json - Output in JSON format
15
+ * @param {boolean} options.verbose - Verbose output
16
+ */
17
+ async function handleScanCommand(options = {}) {
18
+ try {
19
+ // Initialize or update skills/agents cache
20
+ await ensureSkillsCache({ verbose: options.verbose });
21
+
22
+ console.log(chalk.blue('šŸ” Scanning for CLI tools...'));
23
+
24
+ const scanOptions = {
25
+ deep: options.deep || false,
26
+ verbose: options.verbose || false
27
+ };
28
+
29
+ // Scan for available CLI tools
30
+ const results = await CLI_TOOLS.scanForTools(scanOptions);
31
+
32
+ if (results.found && results.found.length > 0) {
33
+ console.log(chalk.green(`\nāœ… Found ${results.found.length} CLI tools:`));
34
+
35
+ for (const tool of results.found) {
36
+ console.log(chalk.cyan(` šŸ“¦ ${tool.name}`));
37
+ console.log(chalk.gray(` Version: ${tool.version || 'unknown'}`));
38
+ console.log(chalk.gray(` Path: ${tool.path}`));
39
+
40
+ if (options.verbose) {
41
+ console.log(chalk.gray(` Type: ${tool.type}`));
42
+ console.log(chalk.gray(` Status: ${tool.status}`));
43
+ if (tool.description) {
44
+ console.log(chalk.gray(` Description: ${tool.description}`));
45
+ }
46
+ }
47
+ }
48
+ } else {
49
+ console.log(chalk.yellow('\nāš ļø No CLI tools found'));
50
+ }
51
+
52
+ // Show missing tools
53
+ if (results.missing && results.missing.length > 0) {
54
+ console.log(chalk.yellow(`\nāŒ Missing ${results.missing.length} tools:`));
55
+ results.missing.forEach(tool => {
56
+ console.log(chalk.red(` āŒ ${tool}`));
57
+ });
58
+
59
+ console.log(chalk.cyan('\nšŸ’” To install missing tools:'));
60
+ console.log(chalk.cyan(' stigmergy install'));
61
+ }
62
+
63
+ // Summary
64
+ console.log('');
65
+ console.log(chalk.blue('šŸ“Š Scan Summary:'));
66
+ console.log(` Total tools checked: ${results.total || 0}`);
67
+ console.log(` Found: ${results.found?.length || 0}`);
68
+ console.log(` Missing: ${results.missing?.length || 0}`);
69
+
70
+ if (options.json) {
71
+ console.log('');
72
+ console.log(chalk.blue('šŸ“„ JSON Output:'));
73
+ console.log(JSON.stringify(results, null, 2));
74
+ }
75
+
76
+ // Recommendations
77
+ if (results.found && results.found.length > 0) {
78
+ console.log(chalk.cyan('\nšŸ’” You can now use these tools:'));
79
+ const toolExamples = results.found.slice(0, 3);
80
+ toolExamples.forEach(tool => {
81
+ console.log(chalk.cyan(` stigmergy ${tool.name} "your prompt here"`));
82
+ });
83
+
84
+ if (results.found.length > 3) {
85
+ console.log(chalk.cyan(` ... and ${results.found.length - 3} more tools`));
86
+ }
87
+ }
88
+
89
+ } catch (error) {
90
+ console.log(chalk.red(`āŒ Scan failed: ${error.message}`));
91
+ process.exit(1);
92
+ }
93
+ }
94
+
95
+ module.exports = {
96
+ handleScanCommand
97
+ };