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.
@@ -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 - Entry Point
5
- * International Version - Pure ANSI Characters Only
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 and export the main functionality from main.js
9
- require('./main.js');
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
+ };