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.
- package/README.md +39 -3
- package/STIGMERGY.md +3 -0
- package/config/enhanced-cli-config.json +438 -0
- package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
- package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
- package/docs/INSTALLER_ARCHITECTURE.md +257 -0
- package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
- package/package.json +14 -5
- package/scripts/analyze-router.js +168 -0
- package/scripts/test-runner.js +344 -0
- package/src/cli/commands/autoinstall.js +158 -0
- package/src/cli/commands/errors.js +190 -0
- package/src/cli/commands/install.js +142 -0
- package/src/cli/commands/permissions.js +108 -0
- package/src/cli/commands/project.js +449 -0
- package/src/cli/commands/resume.js +136 -0
- package/src/cli/commands/scan.js +97 -0
- package/src/cli/commands/skills.js +158 -0
- package/src/cli/commands/status.js +106 -0
- package/src/cli/commands/system.js +301 -0
- package/src/cli/router-beta.js +477 -0
- package/src/cli/utils/environment.js +75 -0
- package/src/cli/utils/formatters.js +47 -0
- package/src/cli/utils/skills_cache.js +92 -0
- package/src/core/cache_cleaner.js +1 -0
- package/src/core/cli_adapters.js +345 -0
- package/src/core/cli_help_analyzer.js +473 -1
- package/src/core/cli_path_detector.js +2 -1
- package/src/core/cli_tools.js +107 -0
- package/src/core/coordination/nodejs/HookDeploymentManager.js +185 -422
- package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
- package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
- package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +701 -0
- package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1210 -0
- package/src/core/coordination/nodejs/generators/index.js +12 -0
- package/src/core/enhanced_cli_installer.js +220 -30
- package/src/core/enhanced_cli_parameter_handler.js +395 -0
- package/src/core/execution_mode_detector.js +222 -0
- package/src/core/installer.js +51 -70
- package/src/core/local_skill_scanner.js +732 -0
- package/src/core/multilingual/language-pattern-manager.js +1 -1
- package/src/core/skills/StigmergySkillManager.js +26 -8
- package/src/core/smart_router.js +279 -2
- package/src/index.js +10 -4
- package/test/cli-integration.test.js +304 -0
- package/test/enhanced-cli-agent-skill-test.js +485 -0
- package/test/specific-cli-agent-skill-analysis.js +385 -0
- 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
|
+
};
|