stigmergy 1.2.13 ā 1.3.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.
- package/README.md +39 -3
- package/STIGMERGY.md +3 -0
- package/config/builtin-skills.json +43 -0
- package/config/enhanced-cli-config.json +438 -0
- package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
- package/docs/DESIGN_CLI_HELP_ANALYZER_REFACTOR.md +726 -0
- package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
- package/docs/IMPLEMENTATION_CHECKLIST_CLI_HELP_ANALYZER_REFACTOR.md +1268 -0
- package/docs/INSTALLER_ARCHITECTURE.md +257 -0
- package/docs/LESSONS_LEARNED.md +252 -0
- package/docs/SPECS_CLI_HELP_ANALYZER_REFACTOR.md +287 -0
- package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
- package/docs/correct-skillsio-implementation.md +368 -0
- package/docs/development_guidelines.md +276 -0
- package/docs/independent-resume-implementation.md +198 -0
- package/docs/resumesession-final-implementation.md +195 -0
- package/docs/resumesession-usage.md +87 -0
- package/package.json +146 -136
- package/scripts/analyze-router.js +168 -0
- package/scripts/run-comprehensive-tests.js +230 -0
- package/scripts/run-quick-tests.js +90 -0
- package/scripts/test-runner.js +344 -0
- package/skills/resumesession/INDEPENDENT_SKILL.md +403 -0
- package/skills/resumesession/README.md +381 -0
- package/skills/resumesession/SKILL.md +211 -0
- package/skills/resumesession/__init__.py +33 -0
- package/skills/resumesession/implementations/simple-resume.js +13 -0
- package/skills/resumesession/independent-resume.js +750 -0
- package/skills/resumesession/package.json +1 -0
- package/skills/resumesession/skill.json +1 -0
- package/src/adapters/claude/install_claude_integration.js +9 -1
- package/src/adapters/codebuddy/install_codebuddy_integration.js +3 -1
- package/src/adapters/codex/install_codex_integration.js +15 -5
- package/src/adapters/gemini/install_gemini_integration.js +3 -1
- package/src/adapters/qwen/install_qwen_integration.js +3 -1
- package/src/cli/commands/autoinstall.js +65 -0
- package/src/cli/commands/errors.js +190 -0
- package/src/cli/commands/independent-resume.js +395 -0
- package/src/cli/commands/install.js +179 -0
- package/src/cli/commands/permissions.js +108 -0
- package/src/cli/commands/project.js +485 -0
- package/src/cli/commands/scan.js +97 -0
- package/src/cli/commands/simple-resume.js +377 -0
- package/src/cli/commands/skills.js +158 -0
- package/src/cli/commands/status.js +113 -0
- package/src/cli/commands/stigmergy-resume.js +775 -0
- package/src/cli/commands/system.js +301 -0
- package/src/cli/commands/universal-resume.js +394 -0
- package/src/cli/router-beta.js +471 -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 +1236 -680
- package/src/core/cli_path_detector.js +702 -709
- package/src/core/cli_tools.js +515 -160
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +18 -0
- package/src/core/coordination/nodejs/HookDeploymentManager.js +242 -412
- 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 +932 -0
- package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1395 -0
- package/src/core/coordination/nodejs/generators/index.js +12 -0
- package/src/core/enhanced_cli_installer.js +1208 -608
- package/src/core/enhanced_cli_parameter_handler.js +402 -0
- package/src/core/execution_mode_detector.js +222 -0
- package/src/core/installer.js +151 -106
- package/src/core/local_skill_scanner.js +732 -0
- package/src/core/multilingual/language-pattern-manager.js +1 -1
- package/src/core/skills/BuiltinSkillsDeployer.js +188 -0
- package/src/core/skills/StigmergySkillManager.js +123 -16
- package/src/core/skills/embedded-openskills/SkillParser.js +7 -3
- package/src/core/smart_router.js +550 -261
- package/src/index.js +10 -4
- package/src/utils.js +66 -7
- package/test/cli-integration.test.js +304 -0
- package/test/direct_smart_router_test.js +88 -0
- package/test/enhanced-cli-agent-skill-test.js +485 -0
- package/test/simple_test.js +82 -0
- package/test/smart_router_test_runner.js +123 -0
- package/test/smart_routing_edge_cases.test.js +284 -0
- package/test/smart_routing_simple_verification.js +139 -0
- package/test/smart_routing_verification.test.js +346 -0
- package/test/specific-cli-agent-skill-analysis.js +385 -0
- package/test/unit/smart_router.test.js +295 -0
- package/test/very_simple_test.js +54 -0
- package/src/cli/router.js +0 -1783
|
@@ -0,0 +1,485 @@
|
|
|
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
|
+
const packageJson = require('../../../package.json');
|
|
20
|
+
|
|
21
|
+
// Import execution mode detection and CLI adapters
|
|
22
|
+
const ExecutionModeDetector = require('../../core/execution_mode_detector');
|
|
23
|
+
const { CLIAdapterManager } = require('../../core/cli_adapters');
|
|
24
|
+
|
|
25
|
+
// Create instances
|
|
26
|
+
const modeDetector = new ExecutionModeDetector();
|
|
27
|
+
const cliAdapterManager = new CLIAdapterManager();
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Handle upgrade command
|
|
31
|
+
* @param {Object} options - Command options
|
|
32
|
+
*/
|
|
33
|
+
async function handleUpgradeCommand(options = {}) {
|
|
34
|
+
try {
|
|
35
|
+
console.log(chalk.cyan('[UPGRADE] Starting AI CLI tools upgrade process...\n'));
|
|
36
|
+
|
|
37
|
+
// Initialize or update skills/agents cache
|
|
38
|
+
await ensureSkillsCache({ verbose: process.env.DEBUG === 'true' });
|
|
39
|
+
|
|
40
|
+
const upgradeOptions = {
|
|
41
|
+
dryRun: options.dryRun || false,
|
|
42
|
+
force: options.force || false,
|
|
43
|
+
verbose: options.verbose || process.env.DEBUG === 'true'
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Use enhanced CLI installer for upgrade
|
|
47
|
+
const enhancedInstaller = new EnhancedCLIInstaller({
|
|
48
|
+
verbose: upgradeOptions.verbose,
|
|
49
|
+
autoRetry: true,
|
|
50
|
+
maxRetries: 2
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Get installed tools
|
|
54
|
+
const installer = new StigmergyInstaller({ verbose: upgradeOptions.verbose });
|
|
55
|
+
const { available: installedTools } = await installer.scanCLI();
|
|
56
|
+
|
|
57
|
+
if (Object.keys(installedTools).length === 0) {
|
|
58
|
+
console.log(chalk.yellow('[INFO] No CLI tools found to upgrade'));
|
|
59
|
+
console.log(chalk.blue('š” Run: stigmergy install to install CLI tools first'));
|
|
60
|
+
return { success: true, upgraded: 0 };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(chalk.blue(`[INFO] Found ${Object.keys(installedTools).length} CLI tools to upgrade`));
|
|
64
|
+
|
|
65
|
+
if (upgradeOptions.dryRun) {
|
|
66
|
+
console.log(chalk.yellow('[DRY RUN] Would upgrade the following tools:'));
|
|
67
|
+
Object.keys(installedTools).forEach(tool => {
|
|
68
|
+
console.log(` ⢠${tool}`);
|
|
69
|
+
});
|
|
70
|
+
return { success: true, upgraded: Object.keys(installedTools).length };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Perform upgrade
|
|
74
|
+
console.log(chalk.blue('[INFO] Starting upgrade process...'));
|
|
75
|
+
const toolsToUpgrade = Object.keys(installedTools);
|
|
76
|
+
|
|
77
|
+
const upgradeResult = await enhancedInstaller.upgradeTools(toolsToUpgrade, installedTools);
|
|
78
|
+
|
|
79
|
+
if (upgradeResult) {
|
|
80
|
+
console.log(chalk.green(`\nā
Successfully upgraded ${toolsToUpgrade.length} CLI tools!`));
|
|
81
|
+
return { success: true, upgraded: toolsToUpgrade.length };
|
|
82
|
+
} else {
|
|
83
|
+
console.log(chalk.red('\nā Upgrade process encountered issues'));
|
|
84
|
+
return { success: false, upgraded: 0 };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error(chalk.red('[ERROR] Upgrade failed:'), error.message);
|
|
89
|
+
if (options.verbose) {
|
|
90
|
+
console.error(error.stack);
|
|
91
|
+
}
|
|
92
|
+
return { success: false, error: error.message };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Handle deploy command
|
|
98
|
+
* @param {Object} options - Command options
|
|
99
|
+
*/
|
|
100
|
+
async function handleDeployCommand(options = {}) {
|
|
101
|
+
try {
|
|
102
|
+
console.log(chalk.cyan('[DEPLOY] Starting hook deployment...\n'));
|
|
103
|
+
|
|
104
|
+
const installer = new StigmergyInstaller({ verbose: options.verbose });
|
|
105
|
+
const { available: deployedTools } = await installer.scanCLI();
|
|
106
|
+
|
|
107
|
+
// å¦ę options.all äøŗ trueļ¼éØē½²ęęå·„å
·ļ¼å¦ååŖéØē½² autoInstall: true ēå·„å
·
|
|
108
|
+
let filteredDeployedTools;
|
|
109
|
+
if (options.all) {
|
|
110
|
+
console.log(chalk.blue('[INFO] Deploying hooks for ALL available tools (--all mode)'));
|
|
111
|
+
filteredDeployedTools = deployedTools;
|
|
112
|
+
} else {
|
|
113
|
+
console.log(chalk.blue('[INFO] Deploying hooks for auto-install tools only'));
|
|
114
|
+
const toolsToDeploy = Object.entries(deployedTools)
|
|
115
|
+
.filter(([toolName]) => installer.router.tools[toolName]?.autoInstall === true);
|
|
116
|
+
filteredDeployedTools = Object.fromEntries(toolsToDeploy);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (Object.keys(filteredDeployedTools).length === 0) {
|
|
120
|
+
console.log(chalk.yellow('[INFO] No CLI tools found for deployment'));
|
|
121
|
+
console.log(chalk.blue('š” Run: stigmergy install to install CLI tools first'));
|
|
122
|
+
return { success: true, deployed: 0 };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
console.log(chalk.blue(`[INFO] Deploying hooks for ${Object.keys(filteredDeployedTools).length} tools...`));
|
|
126
|
+
|
|
127
|
+
await installer.deployHooks(filteredDeployedTools);
|
|
128
|
+
|
|
129
|
+
console.log(chalk.green('\nā
Hook deployment completed successfully!'));
|
|
130
|
+
return { success: true, deployed: Object.keys(filteredDeployedTools).length };
|
|
131
|
+
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error(chalk.red('[ERROR] Deployment failed:'), error.message);
|
|
134
|
+
return { success: false, error: error.message };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Handle init command
|
|
140
|
+
* @param {Object} options - Command options
|
|
141
|
+
*/
|
|
142
|
+
async function handleInitCommand(options = {}) {
|
|
143
|
+
try {
|
|
144
|
+
console.log(chalk.cyan('[INIT] Initializing Stigmergy project in current directory...\n'));
|
|
145
|
+
|
|
146
|
+
// Initialize or update skills/agents cache
|
|
147
|
+
await ensureSkillsCache({ verbose: true });
|
|
148
|
+
|
|
149
|
+
// Quick path detection for better tool availability
|
|
150
|
+
console.log(chalk.blue('[INIT] Detecting CLI tool paths...'));
|
|
151
|
+
const pathSetup = await setupCLIPaths();
|
|
152
|
+
|
|
153
|
+
console.log(`[INIT] CLI tool detection: ${pathSetup.report.summary.found}/${pathSetup.report.summary.total} tools found`);
|
|
154
|
+
|
|
155
|
+
// Quick setup for basic project structure
|
|
156
|
+
const projectDir = process.cwd();
|
|
157
|
+
const stigmergyDir = path.join(projectDir, '.stigmergy');
|
|
158
|
+
|
|
159
|
+
const fs = require('fs').promises;
|
|
160
|
+
|
|
161
|
+
// Create .stigmergy directory
|
|
162
|
+
await fs.mkdir(stigmergyDir, { recursive: true });
|
|
163
|
+
|
|
164
|
+
// Create basic config
|
|
165
|
+
const config = {
|
|
166
|
+
version: packageJson.version,
|
|
167
|
+
created: new Date().toISOString(),
|
|
168
|
+
project: path.basename(projectDir)
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
await fs.writeFile(
|
|
172
|
+
path.join(stigmergyDir, 'config.json'),
|
|
173
|
+
JSON.stringify(config, null, 2)
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
console.log(chalk.green(`ā
Stigmergy project initialized in: ${projectDir}`));
|
|
177
|
+
console.log(chalk.blue(`š Configuration created: ${stigmergyDir}/config.json`));
|
|
178
|
+
console.log(chalk.gray('\nš” Next steps:'));
|
|
179
|
+
console.log(chalk.gray(' ⢠stigmergy install # Install CLI tools'));
|
|
180
|
+
console.log(chalk.gray(' ⢠stigmergy deploy # Deploy integration hooks'));
|
|
181
|
+
console.log(chalk.gray(' ⢠stigmergy status # Check tool status'));
|
|
182
|
+
|
|
183
|
+
if (pathSetup.report.summary.missing > 0) {
|
|
184
|
+
console.log(chalk.gray('\nš” For full CLI integration, run:'));
|
|
185
|
+
console.log(chalk.gray(' ⢠stigmergy setup # Complete setup with PATH configuration'));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return { success: true, projectDir };
|
|
189
|
+
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error(chalk.red('[ERROR] Initialization failed:'), error.message);
|
|
192
|
+
return { success: false, error: error.message };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Handle setup command
|
|
198
|
+
* @param {Object} options - Command options
|
|
199
|
+
*/
|
|
200
|
+
async function handleSetupCommand(options = {}) {
|
|
201
|
+
try {
|
|
202
|
+
console.log(chalk.cyan('[SETUP] Starting complete Stigmergy setup...\n'));
|
|
203
|
+
|
|
204
|
+
// Initialize or update skills/agents cache (explicit call, will also be called in init)
|
|
205
|
+
await ensureSkillsCache({ verbose: true });
|
|
206
|
+
|
|
207
|
+
// Step 0: Setup CLI paths detection and configuration
|
|
208
|
+
console.log(chalk.blue('[STEP 0] Setting up CLI path detection...'));
|
|
209
|
+
const pathSetup = await setupCLIPaths();
|
|
210
|
+
|
|
211
|
+
console.log(`[PATH] Path detection complete:`);
|
|
212
|
+
console.log(` - Found: ${pathSetup.report.summary.found} CLI tools`);
|
|
213
|
+
console.log(` - Missing: ${pathSetup.report.summary.missing} CLI tools`);
|
|
214
|
+
|
|
215
|
+
if (pathSetup.pathStatus.updated) {
|
|
216
|
+
console.log(chalk.green('\n[PATH] ā All npm global directories are now available in PATH'));
|
|
217
|
+
console.log(chalk.gray('[PATH] CLI tools will be globally accessible after terminal restart'));
|
|
218
|
+
} else {
|
|
219
|
+
console.log(chalk.yellow('\n[PATH] ā ļø PATH update failed:'));
|
|
220
|
+
console.log(chalk.gray(` Error: ${pathSetup.pathStatus.message}`));
|
|
221
|
+
console.log(chalk.gray('\n[PATH] Manual update required:'));
|
|
222
|
+
console.log(chalk.gray(' Run the generated scripts to update PATH:'));
|
|
223
|
+
if (pathSetup.pathStatus.scriptPath) {
|
|
224
|
+
console.log(chalk.gray(` - Script directory: ${pathSetup.pathStatus.scriptPath}`));
|
|
225
|
+
}
|
|
226
|
+
console.log(chalk.gray(' - Windows: Run PowerShell as Administrator and execute the scripts'));
|
|
227
|
+
console.log(chalk.gray(' - Unix/Linux: Source the shell script (source update-path.sh)'));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Initialize project (will call ensureSkillsCache again, that's ok)
|
|
231
|
+
await handleInitCommand({ verbose: options.verbose });
|
|
232
|
+
|
|
233
|
+
// Install CLI tools
|
|
234
|
+
const installer = new StigmergyInstaller({ verbose: options.verbose });
|
|
235
|
+
const { available: setupAvailable, missing: setupMissing } = await installer.scanCLI();
|
|
236
|
+
|
|
237
|
+
if (Object.keys(setupMissing).length > 0) {
|
|
238
|
+
console.log(chalk.yellow('\n[STEP 1] Missing tools found:'));
|
|
239
|
+
for (const [toolName, toolInfo] of Object.entries(setupMissing)) {
|
|
240
|
+
console.log(` - ${toolInfo.name}: ${toolInfo.install}`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
console.log(chalk.blue('\n[INFO] To install missing tools, run:'));
|
|
244
|
+
for (const [toolName, toolInfo] of Object.entries(setupMissing)) {
|
|
245
|
+
console.log(` ${toolInfo.install}`);
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
console.log(chalk.green('\n[STEP 1] All required tools are already installed!'));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Deploy hooks to available CLI tools
|
|
252
|
+
if (Object.keys(setupAvailable).length > 0) {
|
|
253
|
+
console.log(chalk.blue('\n[STEP 2] Deploying hooks to available tools...'));
|
|
254
|
+
await installer.deployHooks(setupAvailable);
|
|
255
|
+
} else {
|
|
256
|
+
console.log(chalk.yellow('\n[STEP 2] No tools available for hook deployment'));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Verify setup
|
|
260
|
+
console.log(chalk.blue('\n[STEP 3] Verifying installation...'));
|
|
261
|
+
await handleStatusCommand({ verbose: false });
|
|
262
|
+
|
|
263
|
+
console.log(chalk.green('\nš Setup completed successfully!'));
|
|
264
|
+
console.log(chalk.blue('\n[USAGE] Get started with these commands:'));
|
|
265
|
+
console.log(chalk.gray(' stigmergy d - System diagnostic (recommended first)'));
|
|
266
|
+
console.log(chalk.gray(' stigmergy inst - Install missing AI CLI tools'));
|
|
267
|
+
console.log(chalk.gray(' stigmergy deploy - Deploy hooks to installed tools'));
|
|
268
|
+
console.log(chalk.gray(' stigmergy call - Execute prompts with auto-routing'));
|
|
269
|
+
|
|
270
|
+
return { success: true };
|
|
271
|
+
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.error(chalk.red('[ERROR] Setup failed:'), error.message);
|
|
274
|
+
return { success: false, error: error.message };
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Get working directory for a specific CLI tool
|
|
280
|
+
*/
|
|
281
|
+
function getWorkingDirectoryForTool(toolName) {
|
|
282
|
+
const toolConfig = CLI_TOOLS[toolName];
|
|
283
|
+
if (toolConfig && toolConfig.workingDirectory) {
|
|
284
|
+
return toolConfig.workingDirectory;
|
|
285
|
+
}
|
|
286
|
+
return process.cwd();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Get environment for a specific CLI tool
|
|
291
|
+
*/
|
|
292
|
+
function getEnvironmentForTool(toolName) {
|
|
293
|
+
const env = { ...process.env };
|
|
294
|
+
|
|
295
|
+
// Tool-specific environment handling
|
|
296
|
+
if (toolName === 'qwen') {
|
|
297
|
+
// Qwen CLI requires NODE_PATH to be unset
|
|
298
|
+
delete env.NODE_PATH;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return env;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Add OAuth authentication arguments to command args
|
|
306
|
+
*/
|
|
307
|
+
function addOAuthAuthArgs(toolName, args = []) {
|
|
308
|
+
const toolConfig = CLI_TOOLS[toolName];
|
|
309
|
+
|
|
310
|
+
if (toolConfig && toolConfig.oauth) {
|
|
311
|
+
const oauth = toolConfig.oauth;
|
|
312
|
+
if (oauth.authRequired) {
|
|
313
|
+
// Qwen-specific OAuth handling
|
|
314
|
+
if (toolName === 'qwen' && process.env.QWEN_ACCESS_TOKEN) {
|
|
315
|
+
return [...args, '--access-token', process.env.QWEN_ACCESS_TOKEN];
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return args;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Execute a smart routed command with full parameter handling and mode detection
|
|
325
|
+
* @param {Object} route - Route object with tool and prompt
|
|
326
|
+
* @param {Object} options - Execution options
|
|
327
|
+
*/
|
|
328
|
+
async function executeSmartRoutedCommand(route, options = {}) {
|
|
329
|
+
const { verbose = false, maxRetries = 3, interactive, print } = options;
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
// Detect execution mode
|
|
333
|
+
const mode = modeDetector.detect({
|
|
334
|
+
interactive,
|
|
335
|
+
print,
|
|
336
|
+
verbose
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const modeDescription = modeDetector.getModeDescription(mode);
|
|
340
|
+
if (verbose) {
|
|
341
|
+
console.log(chalk.gray(`[MODE] ${modeDescription}`));
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Get adapted arguments for the tool and mode
|
|
345
|
+
let toolArgs = cliAdapterManager.getArguments(route.tool, mode, route.prompt);
|
|
346
|
+
|
|
347
|
+
// Add OAuth authentication if needed
|
|
348
|
+
toolArgs = addOAuthAuthArgs(route.tool, toolArgs);
|
|
349
|
+
|
|
350
|
+
// Use enhanced parameter handling for one-time mode only
|
|
351
|
+
if (mode === 'one-time') {
|
|
352
|
+
try {
|
|
353
|
+
const EnhancedCLIParameterHandler = require('../../core/enhanced_cli_parameter_handler');
|
|
354
|
+
const paramHandler = new EnhancedCLIParameterHandler();
|
|
355
|
+
|
|
356
|
+
// Generate optimized arguments with agent/skill support
|
|
357
|
+
// Add timeout protection for parameter generation
|
|
358
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
359
|
+
setTimeout(() => reject(new Error('Parameter generation timeout')), 30000); // 30 second timeout for parameter generation
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
const paramPromise = paramHandler.generateArgumentsWithRetry(
|
|
363
|
+
route.tool,
|
|
364
|
+
route.prompt,
|
|
365
|
+
{
|
|
366
|
+
maxRetries,
|
|
367
|
+
enableAgentSkillOptimization: true
|
|
368
|
+
}
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
const paramResult = await Promise.race([paramPromise, timeoutPromise]);
|
|
372
|
+
|
|
373
|
+
toolArgs = paramResult.arguments;
|
|
374
|
+
|
|
375
|
+
// Re-add OAuth authentication (paramResult might overwrite)
|
|
376
|
+
toolArgs = addOAuthAuthArgs(route.tool, toolArgs);
|
|
377
|
+
|
|
378
|
+
if (verbose) {
|
|
379
|
+
console.log(chalk.gray(`[DEBUG] Generated args: ${toolArgs.join(' ')}`));
|
|
380
|
+
}
|
|
381
|
+
} catch (paramError) {
|
|
382
|
+
console.log(chalk.yellow(`[WARN] Parameter generation failed: ${paramError.message}, using basic arguments`));
|
|
383
|
+
// Fallback to basic arguments if enhanced parameter generation fails
|
|
384
|
+
if (verbose) {
|
|
385
|
+
console.log(chalk.gray(`[DEBUG] Falling back to basic args: ${toolArgs.join(' ')}`));
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
if (verbose) {
|
|
390
|
+
console.log(chalk.gray(`[DEBUG] Adapted args: ${toolArgs.join(' ')}`));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Get tool path
|
|
395
|
+
const toolPath = await getCLIPath(route.tool);
|
|
396
|
+
if (!toolPath) {
|
|
397
|
+
throw new Error(`Tool ${route.tool} not found`);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Prepare execution environment
|
|
401
|
+
const cwd = getWorkingDirectoryForTool(route.tool);
|
|
402
|
+
const env = getEnvironmentForTool(route.tool);
|
|
403
|
+
|
|
404
|
+
if (verbose) {
|
|
405
|
+
console.log(chalk.gray(`[DEBUG] Executing: ${toolPath} ${toolArgs.join(' ')}`));
|
|
406
|
+
console.log(chalk.gray(`[DEBUG] Working directory: ${cwd}`));
|
|
407
|
+
console.log(chalk.gray(`[DEBUG] Mode: ${mode}`));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
console.log(chalk.gray(`[EXEC] ${route.tool}: ${route.prompt}`)); // Add this to match direct command format
|
|
411
|
+
|
|
412
|
+
// Execute the command
|
|
413
|
+
// For interactive mode, we need stdio: 'inherit' to allow user interaction
|
|
414
|
+
// For one-time mode, we should use 'inherit' to ensure CLI tools can properly execute
|
|
415
|
+
const stdioOption = mode === 'interactive' ? 'inherit' : 'inherit'; // Use 'inherit' for both modes to ensure proper CLI execution
|
|
416
|
+
|
|
417
|
+
console.log(chalk.gray(`[DEBUG] About to execute command with args: ${toolArgs.join(' ')}`)); // Debug log
|
|
418
|
+
console.log(chalk.gray(`[DEBUG] Using stdio option: ${stdioOption}`)); // Debug log
|
|
419
|
+
const result = await executeCommand(toolPath, toolArgs, {
|
|
420
|
+
stdio: stdioOption,
|
|
421
|
+
shell: true,
|
|
422
|
+
cwd,
|
|
423
|
+
env,
|
|
424
|
+
timeout: 300000 // 5 minutes
|
|
425
|
+
});
|
|
426
|
+
console.log(chalk.gray(`[DEBUG] Command execution completed`)); // Debug log
|
|
427
|
+
|
|
428
|
+
return { success: true, tool: route.tool, result, mode };
|
|
429
|
+
|
|
430
|
+
} catch (error) {
|
|
431
|
+
if (verbose) {
|
|
432
|
+
console.error(chalk.red('[ERROR] Execution failed:'), error.message);
|
|
433
|
+
}
|
|
434
|
+
throw error;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Handle call command - Smart tool routing
|
|
440
|
+
* @param {string} prompt - Prompt to process
|
|
441
|
+
* @param {Object} options - Command options
|
|
442
|
+
*/
|
|
443
|
+
async function handleCallCommand(prompt, options = {}) {
|
|
444
|
+
try {
|
|
445
|
+
if (!prompt) {
|
|
446
|
+
console.log(chalk.red('[ERROR] Usage: stigmergy call "<prompt>"'));
|
|
447
|
+
console.log(chalk.blue('\nš” Examples:'));
|
|
448
|
+
console.log(chalk.gray(' ⢠stigmergy call "Write a Python function to sort a list"'));
|
|
449
|
+
console.log(chalk.gray(' ⢠stigmergy call "Create a React component with TypeScript"'));
|
|
450
|
+
console.log(chalk.gray(' ⢠stigmergy call "Help me debug this JavaScript code"'));
|
|
451
|
+
console.log(chalk.gray('\n ⢠stigmergy call -i "Start interactive session"'));
|
|
452
|
+
console.log(chalk.gray(' ⢠stigmergy call --print "Quick answer"'));
|
|
453
|
+
return { success: false, error: 'Prompt required' };
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Use smart router to determine which tool to use
|
|
457
|
+
const router = new SmartRouter();
|
|
458
|
+
await router.initialize();
|
|
459
|
+
const route = await router.smartRoute(prompt);
|
|
460
|
+
|
|
461
|
+
console.log(chalk.blue(`[CALL] Routing to ${route.tool}: ${route.prompt}`));
|
|
462
|
+
|
|
463
|
+
// Use enhanced execution with parameter handling and mode detection
|
|
464
|
+
await executeSmartRoutedCommand(route, {
|
|
465
|
+
verbose: options.verbose || process.env.DEBUG === 'true',
|
|
466
|
+
maxRetries: options.maxRetries || 3,
|
|
467
|
+
interactive: options.interactive,
|
|
468
|
+
print: options.print
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
return { success: true, tool: route.tool };
|
|
472
|
+
|
|
473
|
+
} catch (error) {
|
|
474
|
+
console.error(chalk.red('[ERROR] Call command failed:'), error.message);
|
|
475
|
+
return { success: false, error: error.message };
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
module.exports = {
|
|
480
|
+
handleUpgradeCommand,
|
|
481
|
+
handleDeployCommand,
|
|
482
|
+
handleInitCommand,
|
|
483
|
+
handleSetupCommand,
|
|
484
|
+
handleCallCommand
|
|
485
|
+
};
|
|
@@ -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
|
+
};
|