stigmergy 1.0.99 → 1.1.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 +17 -0
- package/bin/stigmergy +1 -1
- package/bin/stigmergy.cmd +1 -1
- package/docs/NATIVE_INTEGRATION_GUIDE.md +1155 -1190
- package/docs/PROJECT_STRUCTURE.md +283 -303
- package/package.json +10 -7
- package/src/cli/router.js +456 -0
- package/src/core/coordination/index.js +16 -0
- package/src/core/coordination/nodejs/AdapterManager.js +89 -0
- package/src/core/coordination/nodejs/CLCommunication.js +59 -0
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +236 -0
- package/src/core/coordination/nodejs/HealthChecker.js +77 -0
- package/src/core/coordination/nodejs/HookDeploymentManager.js +256 -0
- package/src/core/coordination/nodejs/StatisticsCollector.js +71 -0
- package/src/core/coordination/nodejs/index.js +72 -0
- package/src/core/coordination/nodejs/utils/Logger.js +29 -0
- package/src/core/installer.js +375 -0
- package/src/index.js +25 -4
- package/src/main.js +1068 -831
- package/src/utils/helpers.js +35 -0
- package/test/cross-cli-detection-test.js +33 -0
- package/test/python-plugins-test.js +259 -0
- package/test/remaining-adapters-test.js +256 -0
- package/test/system-compatibility-test.js +466 -446
- package/test/tool-selection-integration-test.js +157 -156
- package/src/main_english.js +0 -1338
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/core/coordination/nodejs/utils/Logger.js
|
|
2
|
+
class Logger {
|
|
3
|
+
constructor(component) {
|
|
4
|
+
this.component = component;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
info(message) {
|
|
8
|
+
this.log('INFO', message);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
warn(message) {
|
|
12
|
+
this.log('WARN', message);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
error(message) {
|
|
16
|
+
this.log('ERROR', message);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
debug(message) {
|
|
20
|
+
this.log('DEBUG', message);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
log(level, message) {
|
|
24
|
+
const timestamp = new Date().toISOString();
|
|
25
|
+
console.log(`[${timestamp}] [${level}] [${this.component}] ${message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = Logger;
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs/promises');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { spawnSync } = require('child_process');
|
|
5
|
+
const SmartRouter = require('./smart_router');
|
|
6
|
+
const { errorHandler } = require('./error_handler');
|
|
7
|
+
const MemoryManager = require('./memory_manager');
|
|
8
|
+
|
|
9
|
+
class StigmergyInstaller {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.router = new SmartRouter();
|
|
12
|
+
this.memory = new MemoryManager();
|
|
13
|
+
this.configDir = path.join(os.homedir(), '.stigmergy');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async checkCLI(toolName) {
|
|
17
|
+
const tool = this.router.tools[toolName];
|
|
18
|
+
if (!tool) return false;
|
|
19
|
+
|
|
20
|
+
// Try multiple ways to check if CLI is available
|
|
21
|
+
const checks = [
|
|
22
|
+
// Method 1: Try version command
|
|
23
|
+
{ args: ['--version'], expected: 0 },
|
|
24
|
+
// Method 2: Try help command
|
|
25
|
+
{ args: ['--help'], expected: 0 },
|
|
26
|
+
// Method 3: Try help command with -h
|
|
27
|
+
{ args: ['-h'], expected: 0 },
|
|
28
|
+
// Method 4: Try just the command (help case)
|
|
29
|
+
{ args: [], expected: 0 },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
for (const check of checks) {
|
|
33
|
+
try {
|
|
34
|
+
const result = spawnSync(toolName, check.args, {
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
timeout: 5000,
|
|
37
|
+
shell: true,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Check if command executed successfully or at least didn't fail with "command not found"
|
|
41
|
+
if (
|
|
42
|
+
result.status === check.expected ||
|
|
43
|
+
(result.status !== 127 && result.status !== 9009)
|
|
44
|
+
) {
|
|
45
|
+
// 127 = command not found on Unix, 9009 = command not found on Windows
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
// Continue to next check method
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async scanCLI() {
|
|
58
|
+
console.log('[SCAN] Scanning for AI CLI tools...');
|
|
59
|
+
const available = {};
|
|
60
|
+
const missing = {};
|
|
61
|
+
|
|
62
|
+
for (const [toolName, toolInfo] of Object.entries(this.router.tools)) {
|
|
63
|
+
try {
|
|
64
|
+
console.log(`[SCAN] Checking ${toolInfo.name}...`);
|
|
65
|
+
const isAvailable = await this.checkCLI(toolName);
|
|
66
|
+
|
|
67
|
+
if (isAvailable) {
|
|
68
|
+
console.log(`[OK] ${toolInfo.name} is available`);
|
|
69
|
+
available[toolName] = toolInfo;
|
|
70
|
+
} else {
|
|
71
|
+
console.log(`[MISSING] ${toolInfo.name} is not installed`);
|
|
72
|
+
missing[toolName] = toolInfo;
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
await errorHandler.logError(
|
|
76
|
+
error,
|
|
77
|
+
'WARN',
|
|
78
|
+
`StigmergyInstaller.scanCLI.${toolName}`,
|
|
79
|
+
);
|
|
80
|
+
console.log(
|
|
81
|
+
`[ERROR] Failed to check ${toolInfo.name}: ${error.message}`,
|
|
82
|
+
);
|
|
83
|
+
missing[toolName] = toolInfo;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { available, missing };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async installTools(selectedTools, missingTools) {
|
|
91
|
+
console.log(
|
|
92
|
+
`\n[INSTALL] Installing ${selectedTools.length} AI CLI tools...`,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
for (const toolName of selectedTools) {
|
|
96
|
+
const toolInfo = missingTools[toolName];
|
|
97
|
+
if (!toolInfo) {
|
|
98
|
+
console.log(`[SKIP] Tool ${toolName} not found in missing tools list`);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
console.log(`\n[INSTALL] Installing ${toolInfo.name}...`);
|
|
104
|
+
console.log(`[CMD] ${toolInfo.install}`);
|
|
105
|
+
|
|
106
|
+
const result = spawnSync(toolInfo.install, {
|
|
107
|
+
shell: true,
|
|
108
|
+
stdio: 'inherit',
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (result.status === 0) {
|
|
112
|
+
console.log(`[OK] ${toolInfo.name} installed successfully`);
|
|
113
|
+
} else {
|
|
114
|
+
console.log(
|
|
115
|
+
`[ERROR] Failed to install ${toolInfo.name} (exit code: ${result.status})`,
|
|
116
|
+
);
|
|
117
|
+
if (result.error) {
|
|
118
|
+
console.log(`[ERROR] Installation error: ${result.error.message}`);
|
|
119
|
+
}
|
|
120
|
+
console.log(`[INFO] Please run manually: ${toolInfo.install}`);
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
await errorHandler.logError(
|
|
124
|
+
error,
|
|
125
|
+
'ERROR',
|
|
126
|
+
`StigmergyInstaller.installTools.${toolName}`,
|
|
127
|
+
);
|
|
128
|
+
console.log(
|
|
129
|
+
`[ERROR] Failed to install ${toolInfo.name}: ${error.message}`,
|
|
130
|
+
);
|
|
131
|
+
console.log(`[INFO] Please run manually: ${toolInfo.install}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async deployHooks(availableTools) {
|
|
139
|
+
console.log('\n[DEPLOY] Deploying hooks to AI CLI tools...');
|
|
140
|
+
let successCount = 0;
|
|
141
|
+
const totalCount = Object.keys(availableTools).length;
|
|
142
|
+
|
|
143
|
+
// Import Node.js coordination layer for hook deployment
|
|
144
|
+
let HookDeploymentManager;
|
|
145
|
+
try {
|
|
146
|
+
HookDeploymentManager = require('../core/coordination/nodejs/HookDeploymentManager');
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.log('[WARN] Node.js coordination layer not available, using Python fallback');
|
|
149
|
+
// Fallback to Python implementation would go here
|
|
150
|
+
console.log('[ERROR] Python fallback not implemented yet');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Initialize hook deployment manager
|
|
155
|
+
const hookManager = new HookDeploymentManager();
|
|
156
|
+
await hookManager.initialize();
|
|
157
|
+
|
|
158
|
+
for (const [toolName, toolInfo] of Object.entries(availableTools)) {
|
|
159
|
+
try {
|
|
160
|
+
console.log(`\n[DEPLOY] Deploying hooks for ${toolInfo.name}...`);
|
|
161
|
+
|
|
162
|
+
// Deploy hooks for this tool
|
|
163
|
+
const result = await hookManager.deployHooksForCLI(toolName);
|
|
164
|
+
|
|
165
|
+
if (result) {
|
|
166
|
+
console.log(`[OK] Hooks deployed for ${toolInfo.name}`);
|
|
167
|
+
successCount++;
|
|
168
|
+
} else {
|
|
169
|
+
console.log(`[ERROR] Failed to deploy hooks for ${toolInfo.name}`);
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
await errorHandler.logError(
|
|
173
|
+
error,
|
|
174
|
+
'ERROR',
|
|
175
|
+
`StigmergyInstaller.deployHooks.${toolName}`,
|
|
176
|
+
);
|
|
177
|
+
console.log(
|
|
178
|
+
`[ERROR] Failed to deploy hooks for ${toolInfo.name}: ${error.message}`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
console.log(
|
|
184
|
+
`\n[SUMMARY] Hook deployment completed: ${successCount}/${totalCount} tools successful`,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async deployProjectDocumentation() {
|
|
189
|
+
console.log('\n[DEPLOY] Deploying project documentation...');
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
// Create standard project documentation files
|
|
193
|
+
const docs = {
|
|
194
|
+
'STIGMERGY.md': this.generateProjectMemoryTemplate(),
|
|
195
|
+
'README.md': this.generateProjectReadme(),
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
for (const [filename, content] of Object.entries(docs)) {
|
|
199
|
+
const filepath = path.join(process.cwd(), filename);
|
|
200
|
+
if (!(await this.fileExists(filepath))) {
|
|
201
|
+
await fs.writeFile(filepath, content);
|
|
202
|
+
console.log(`[OK] Created ${filename}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
console.log('[OK] Project documentation deployed successfully');
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.log(
|
|
209
|
+
`[ERROR] Failed to deploy project documentation: ${error.message}`,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
generateProjectMemoryTemplate() {
|
|
215
|
+
return `# Stigmergy Project Memory
|
|
216
|
+
|
|
217
|
+
## Project Information
|
|
218
|
+
- **Project Name**: ${path.basename(process.cwd())}
|
|
219
|
+
- **Created**: ${new Date().toISOString()}
|
|
220
|
+
- **Stigmergy Version**: 1.0.94
|
|
221
|
+
|
|
222
|
+
## Usage Instructions
|
|
223
|
+
This file automatically tracks all interactions with AI CLI tools through the Stigmergy system.
|
|
224
|
+
|
|
225
|
+
## Recent Interactions
|
|
226
|
+
No interactions recorded yet.
|
|
227
|
+
|
|
228
|
+
## Collaboration History
|
|
229
|
+
No collaboration history yet.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
*This file is automatically managed by Stigmergy CLI*
|
|
233
|
+
*Last updated: ${new Date().toISOString()}*
|
|
234
|
+
`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
generateProjectReadme() {
|
|
238
|
+
return `# ${path.basename(process.cwd())}
|
|
239
|
+
|
|
240
|
+
This project uses Stigmergy CLI for AI-assisted development.
|
|
241
|
+
|
|
242
|
+
## Getting Started
|
|
243
|
+
1. Install Stigmergy CLI: \`npm install -g stigmergy\`
|
|
244
|
+
2. Run \`stigmergy setup\` to configure the environment
|
|
245
|
+
3. Use \`stigmergy call "<your prompt>"\` to interact with AI tools
|
|
246
|
+
|
|
247
|
+
## Available AI Tools
|
|
248
|
+
- Claude (Anthropic)
|
|
249
|
+
- Qwen (Alibaba)
|
|
250
|
+
- Gemini (Google)
|
|
251
|
+
- And others configured in your environment
|
|
252
|
+
|
|
253
|
+
## Project Memory
|
|
254
|
+
See [STIGMERGY.md](STIGMERGY.md) for interaction history and collaboration records.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
*Generated by Stigmergy CLI*
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async initializeConfig() {
|
|
262
|
+
console.log('\n[CONFIG] Initializing Stigmergy configuration...');
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
// Create config directory
|
|
266
|
+
const configDir = path.join(os.homedir(), '.stigmergy');
|
|
267
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
268
|
+
|
|
269
|
+
// Create initial configuration
|
|
270
|
+
const config = {
|
|
271
|
+
version: '1.0.94',
|
|
272
|
+
initialized: true,
|
|
273
|
+
createdAt: new Date().toISOString(),
|
|
274
|
+
lastUpdated: new Date().toISOString(),
|
|
275
|
+
defaultCLI: 'claude',
|
|
276
|
+
enableCrossCLI: true,
|
|
277
|
+
enableMemory: true,
|
|
278
|
+
tools: {},
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// Save configuration
|
|
282
|
+
const configPath = path.join(configDir, 'config.json');
|
|
283
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
284
|
+
console.log('[OK] Configuration initialized successfully');
|
|
285
|
+
} catch (error) {
|
|
286
|
+
console.log(
|
|
287
|
+
`[ERROR] Failed to initialize configuration: ${error.message}`,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async downloadRequiredAssets() {
|
|
293
|
+
console.log('[DOWNLOAD] Downloading required assets...');
|
|
294
|
+
// In a real implementation, this would download templates, configs, etc.
|
|
295
|
+
console.log('[OK] All required assets downloaded');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async fileExists(filePath) {
|
|
299
|
+
try {
|
|
300
|
+
await fs.access(filePath);
|
|
301
|
+
return true;
|
|
302
|
+
} catch {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async showInstallOptions(missingTools) {
|
|
308
|
+
if (Object.keys(missingTools).length === 0) {
|
|
309
|
+
console.log('[INFO] All required AI CLI tools are already installed!');
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
console.log('\n[INSTALL] Missing AI CLI tools detected:');
|
|
314
|
+
const choices = [];
|
|
315
|
+
|
|
316
|
+
for (const [toolName, toolInfo] of Object.entries(missingTools)) {
|
|
317
|
+
choices.push({
|
|
318
|
+
name: `${toolInfo.name} (${toolName}) - ${toolInfo.install}`,
|
|
319
|
+
value: toolName,
|
|
320
|
+
checked: true,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const answers = await inquirer.prompt([
|
|
325
|
+
{
|
|
326
|
+
type: 'checkbox',
|
|
327
|
+
name: 'tools',
|
|
328
|
+
message:
|
|
329
|
+
'Select which tools to install (Space to select, Enter to confirm):',
|
|
330
|
+
choices: choices,
|
|
331
|
+
pageSize: 10,
|
|
332
|
+
},
|
|
333
|
+
]);
|
|
334
|
+
|
|
335
|
+
return answers.tools;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async getUserSelection(options, missingTools) {
|
|
339
|
+
if (options.length === 0) {
|
|
340
|
+
return [];
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const answers = await inquirer.prompt([
|
|
344
|
+
{
|
|
345
|
+
type: 'confirm',
|
|
346
|
+
name: 'proceed',
|
|
347
|
+
message: `Install ${options.length} missing AI CLI tools?`,
|
|
348
|
+
default: true,
|
|
349
|
+
},
|
|
350
|
+
]);
|
|
351
|
+
|
|
352
|
+
return answers.proceed ? options : [];
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
showUsageInstructions() {
|
|
356
|
+
console.log('\n');
|
|
357
|
+
console.log('='.repeat(60));
|
|
358
|
+
console.log('🎉 Stigmergy CLI Setup Complete!');
|
|
359
|
+
console.log('='.repeat(60));
|
|
360
|
+
console.log('');
|
|
361
|
+
console.log('Next steps:');
|
|
362
|
+
console.log(' ✅ Run `stigmergy call "<your prompt>"` to start collaborating');
|
|
363
|
+
console.log(' ✅ Or use `stigmergy --help` for more commands');
|
|
364
|
+
console.log('');
|
|
365
|
+
console.log('Example usage:');
|
|
366
|
+
console.log(' stigmergy call "Create a React component for a todo list"');
|
|
367
|
+
console.log(' stigmergy call "Refactor this Python code for better performance"');
|
|
368
|
+
console.log(' stigmergy call "Explain how this JavaScript function works"');
|
|
369
|
+
console.log('');
|
|
370
|
+
console.log('Happy coding with Stigmergy! 🚀');
|
|
371
|
+
console.log('');
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
module.exports = StigmergyInstaller;
|
package/src/index.js
CHANGED
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Stigmergy CLI -
|
|
5
|
-
*
|
|
4
|
+
* Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System
|
|
5
|
+
* Unified Entry Point
|
|
6
|
+
* International Version - Pure English & ANSI Only
|
|
7
|
+
* Version: 1.0.94
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
|
-
// Import
|
|
9
|
-
require('./
|
|
10
|
+
// Import all components
|
|
11
|
+
const MemoryManager = require('./core/memory_manager');
|
|
12
|
+
const StigmergyInstaller = require('./core/installer');
|
|
13
|
+
const { maxOfTwo, isAuthenticated } = require('./utils/helpers');
|
|
14
|
+
const main = require('./cli/router');
|
|
15
|
+
|
|
16
|
+
// Run the main application
|
|
17
|
+
if (require.main === module) {
|
|
18
|
+
main().catch(error => {
|
|
19
|
+
console.error('[FATAL] Unhandled error in Stigmergy CLI:', error);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
MemoryManager,
|
|
26
|
+
StigmergyInstaller,
|
|
27
|
+
maxOfTwo,
|
|
28
|
+
isAuthenticated,
|
|
29
|
+
main
|
|
30
|
+
};
|