stigmergy 1.2.6 → 1.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +69 -20
  2. package/STIGMERGY.md +26 -7
  3. package/docs/MULTI_USER_WIKI_COLLABORATION_SYSTEM.md +523 -0
  4. package/docs/PROMPT_BASED_SKILLS_SYSTEM_DESIGN.md +458 -0
  5. package/docs/SKILL_IMPLEMENTATION_CONSTRAINTS_AND_ALIGNMENT.md +423 -0
  6. package/docs/TECHNICAL_FEASIBILITY_ANALYSIS.md +308 -0
  7. package/examples/multilingual-hook-demo.js +125 -0
  8. package/package.json +30 -19
  9. package/scripts/dependency-analyzer.js +101 -0
  10. package/scripts/generate-cli-docs.js +64 -0
  11. package/scripts/postuninstall.js +46 -0
  12. package/scripts/preuninstall.js +85 -0
  13. package/scripts/run-layered-tests.js +3 -3
  14. package/src/adapters/claude/install_claude_integration.js +37 -37
  15. package/src/adapters/codebuddy/install_codebuddy_integration.js +66 -63
  16. package/src/adapters/codex/install_codex_integration.js +54 -55
  17. package/src/adapters/copilot/install_copilot_integration.js +46 -46
  18. package/src/adapters/gemini/install_gemini_integration.js +68 -68
  19. package/src/adapters/iflow/install_iflow_integration.js +77 -77
  20. package/src/adapters/qoder/install_qoder_integration.js +76 -76
  21. package/src/adapters/qwen/install_qwen_integration.js +23 -23
  22. package/src/cli/router.js +713 -163
  23. package/src/commands/skill-bridge.js +39 -0
  24. package/src/commands/skill-handler.js +150 -0
  25. package/src/commands/skill.js +127 -0
  26. package/src/core/cache_cleaner.js +767 -767
  27. package/src/core/cli_help_analyzer.js +680 -680
  28. package/src/core/cli_parameter_handler.js +132 -132
  29. package/src/core/cli_path_detector.js +573 -0
  30. package/src/core/cli_tools.js +160 -89
  31. package/src/core/coordination/index.js +16 -16
  32. package/src/core/coordination/nodejs/AdapterManager.js +130 -102
  33. package/src/core/coordination/nodejs/CLCommunication.js +132 -132
  34. package/src/core/coordination/nodejs/CLIIntegrationManager.js +272 -272
  35. package/src/core/coordination/nodejs/HealthChecker.js +76 -76
  36. package/src/core/coordination/nodejs/HookDeploymentManager.js +463 -274
  37. package/src/core/coordination/nodejs/StatisticsCollector.js +71 -71
  38. package/src/core/coordination/nodejs/index.js +90 -90
  39. package/src/core/coordination/nodejs/utils/Logger.js +29 -29
  40. package/src/core/directory_permission_manager.js +568 -0
  41. package/src/core/enhanced_cli_installer.js +609 -0
  42. package/src/core/error_handler.js +406 -406
  43. package/src/core/installer.js +263 -119
  44. package/src/core/memory_manager.js +83 -83
  45. package/src/core/multilingual/language-pattern-manager.js +200 -0
  46. package/src/core/persistent_shell_configurator.js +468 -0
  47. package/src/core/rest_client.js +160 -160
  48. package/src/core/skills/StigmergySkillManager.js +357 -0
  49. package/src/core/skills/__tests__/SkillInstaller.test.js +275 -0
  50. package/src/core/skills/__tests__/SkillParser.test.js +202 -0
  51. package/src/core/skills/__tests__/SkillReader.test.js +189 -0
  52. package/src/core/skills/cli-command-test.js +201 -0
  53. package/src/core/skills/comprehensive-e2e-test.js +473 -0
  54. package/src/core/skills/e2e-test.js +267 -0
  55. package/src/core/skills/embedded-openskills/SkillInstaller.js +438 -0
  56. package/src/core/skills/embedded-openskills/SkillParser.js +123 -0
  57. package/src/core/skills/embedded-openskills/SkillReader.js +143 -0
  58. package/src/core/skills/integration-test.js +248 -0
  59. package/src/core/skills/package.json +6 -0
  60. package/src/core/skills/regression-test.js +285 -0
  61. package/src/core/skills/run-all-tests.js +129 -0
  62. package/src/core/skills/sync-test.js +210 -0
  63. package/src/core/skills/test-runner.js +242 -0
  64. package/src/core/smart_router.js +261 -249
  65. package/src/core/upgrade_manager.js +48 -20
  66. package/src/index.js +30 -30
  67. package/src/test/cli-availability-checker.js +194 -194
  68. package/src/test/test-environment.js +289 -289
  69. package/src/utils/helpers.js +18 -35
  70. package/src/utils.js +921 -921
  71. package/src/weatherProcessor.js +228 -228
  72. package/test/multilingual/hook-deployment.test.js +91 -0
  73. package/test/multilingual/language-pattern-manager.test.js +140 -0
  74. package/test/multilingual/system-test.js +85 -0
  75. package/src/auth.js +0 -173
  76. package/src/auth_command.js +0 -208
  77. package/src/calculator.js +0 -313
  78. package/src/core/enhanced_installer.js +0 -479
  79. package/src/core/enhanced_uninstaller.js +0 -638
  80. package/src/data_encryption.js +0 -143
  81. package/src/data_structures.js +0 -440
  82. package/src/deploy.js +0 -55
@@ -0,0 +1,468 @@
1
+ /**
2
+ * Persistent Shell Configurator
3
+ *
4
+ * This module handles writing shell configuration that persists
5
+ * across terminal sessions, ensuring CLI tools work from any directory.
6
+ */
7
+
8
+ const fs = require('fs').promises;
9
+ const path = require('path');
10
+ const os = require('os');
11
+
12
+ class PersistentShellConfigurator {
13
+ constructor(options = {}) {
14
+ this.options = {
15
+ verbose: options.verbose || false,
16
+ dryRun: options.dryRun || false,
17
+ force: options.force || false,
18
+ ...options
19
+ };
20
+
21
+ this.results = {
22
+ shellType: null,
23
+ profileFile: null,
24
+ configured: false,
25
+ createdFiles: [],
26
+ modifiedFiles: []
27
+ };
28
+ }
29
+
30
+ /**
31
+ * Log messages with formatting
32
+ */
33
+ log(level, message) {
34
+ const timestamp = new Date().toLocaleTimeString();
35
+ const prefixes = {
36
+ info: `[INFO] ${timestamp}`,
37
+ success: `[SUCCESS] ${timestamp}`,
38
+ warn: `[WARN] ${timestamp}`,
39
+ error: `[ERROR] ${timestamp}`,
40
+ debug: `[DEBUG] ${timestamp}`
41
+ };
42
+
43
+ const prefix = prefixes[level] || `[LOG] ${timestamp}`;
44
+ const shouldLog = level === 'debug' ? this.options.verbose : true;
45
+
46
+ if (shouldLog) {
47
+ console.log(`${prefix} ${message}`);
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Detect current shell type
53
+ */
54
+ detectShell() {
55
+ // Windows-specific detection
56
+ if (process.platform === 'win32') {
57
+ if (process.env.PSModulePath) return 'powershell';
58
+ if (process.env.COMSPEC && process.env.COMSPEC.includes('cmd.exe')) return 'cmd';
59
+ if (process.env.SHELL && process.env.SHELL.includes('bash')) return 'bash';
60
+ if (process.env.WSL_DISTRO_NAME) {
61
+ const shell = process.env.SHELL;
62
+ if (shell && shell.includes('zsh')) return 'zsh';
63
+ if (shell && shell.includes('bash')) return 'bash';
64
+ return 'wsl';
65
+ }
66
+ return 'powershell'; // Default to PowerShell on Windows
67
+ }
68
+
69
+ // Unix/Linux/macOS detection
70
+ const shell = process.env.SHELL;
71
+ if (!shell) return 'unknown';
72
+
73
+ if (shell.includes('zsh')) return 'zsh';
74
+ if (shell.includes('bash')) return 'bash';
75
+ if (shell.includes('fish')) return 'fish';
76
+ if (shell.includes('csh')) return 'csh';
77
+ if (shell.includes('tcsh')) return 'tcsh';
78
+
79
+ return 'unknown';
80
+ }
81
+
82
+ /**
83
+ * Get shell profile file path
84
+ */
85
+ getShellProfileFile(shellType) {
86
+ const homeDir = os.homedir();
87
+
88
+ switch (shellType) {
89
+ case 'powershell':
90
+ // PowerShell profile locations (try multiple)
91
+ const psProfiles = [
92
+ path.join(homeDir, 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1'),
93
+ path.join(homeDir, 'Documents', 'PowerShell', 'Microsoft.PowerShell_profile.ps1'),
94
+ path.join(homeDir, '.config', 'powershell', 'Microsoft.PowerShell_profile.ps1')
95
+ ];
96
+
97
+ // Return the first existing or most likely location
98
+ return psProfiles[0]; // We'll try to create this if it doesn't exist
99
+
100
+ case 'cmd':
101
+ // Command Prompt doesn't have profile files, but we can suggest registry methods
102
+ return null;
103
+
104
+ case 'wsl':
105
+ // WSL uses Linux-style shells
106
+ const wslHome = process.env.HOME || path.join('/mnt', 'c', 'Users', process.env.USER || 'user');
107
+ const wslShell = process.env.SHELL;
108
+ if (wslShell && wslShell.includes('zsh')) return path.join(wslHome, '.zshrc');
109
+ if (wslShell && wslShell.includes('bash')) return path.join(wslHome, '.bashrc');
110
+ return path.join(wslHome, '.bashrc');
111
+
112
+ case 'zsh':
113
+ return path.join(homeDir, '.zshrc');
114
+
115
+ case 'bash':
116
+ // Check for .bash_profile first, then .bashrc
117
+ if (process.platform === 'win32') {
118
+ // Git Bash on Windows
119
+ return path.join(homeDir, '.bashrc');
120
+ } else {
121
+ // Unix/Linux/macOS
122
+ const bashProfile = path.join(homeDir, '.bash_profile');
123
+ return bashProfile; // We'll check existence and fallback to .bashrc
124
+ }
125
+
126
+ case 'fish':
127
+ return path.join(homeDir, '.config', 'fish', 'config.fish');
128
+
129
+ case 'csh':
130
+ return path.join(homeDir, '.cshrc');
131
+
132
+ case 'tcsh':
133
+ return path.join(homeDir, '.tcshrc');
134
+
135
+ default:
136
+ return null;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Generate persistent configuration for different shell types
142
+ */
143
+ generatePersistentConfig(npmConfig) {
144
+ const { npmGlobalDir, npmBinDir } = npmConfig;
145
+ const shellType = this.detectShell();
146
+
147
+ let config = '';
148
+
149
+ // Add header comment
150
+ config += '\n# Stigmergy CLI Environment Configuration\n';
151
+ config += `# Generated on ${new Date().toISOString()}\n`;
152
+ config += '# This configuration enables CLI tools to work from any directory\n\n';
153
+
154
+ switch (shellType) {
155
+ case 'powershell':
156
+ config += '# PowerShell Environment Configuration\n';
157
+ config += `$env:npm_config_prefix = "${npmGlobalDir}"\n`;
158
+ config += `$env:PATH = "${npmBinDir};$env:PATH"\n`;
159
+ break;
160
+
161
+ case 'cmd':
162
+ config += '# Command Prompt Environment Configuration\n';
163
+ config += `@echo off\n`;
164
+ config += `set npm_config_prefix=${npmGlobalDir}\n`;
165
+ config += `set PATH=${npmBinDir};%PATH%\n`;
166
+ break;
167
+
168
+ case 'zsh':
169
+ case 'bash':
170
+ config += '# Shell Environment Configuration\n';
171
+ config += `export npm_config_prefix="${npmGlobalDir}"\n`;
172
+ config += `export PATH="${npmBinDir}:$PATH"\n`;
173
+ break;
174
+
175
+ case 'fish':
176
+ config += '# Fish Shell Environment Configuration\n';
177
+ config += `set -gx npm_config_prefix "${npmGlobalDir}"\n`;
178
+ config += `set -gx PATH "${npmBinDir}" $PATH\n`;
179
+ break;
180
+
181
+ case 'csh':
182
+ case 'tcsh':
183
+ config += '# C Shell Environment Configuration\n';
184
+ config += `setenv npm_config_prefix "${npmGlobalDir}"\n`;
185
+ config += `setenv PATH "${npmBinDir}:$PATH"\n`;
186
+ break;
187
+
188
+ default:
189
+ config += '# Generic Shell Configuration\n';
190
+ config += `npm_config_prefix="${npmGlobalDir}"\n`;
191
+ config += `PATH="${npmBinDir}:$PATH"\n`;
192
+ break;
193
+ }
194
+
195
+ return { shellType, config };
196
+ }
197
+
198
+ /**
199
+ * Ensure profile file exists
200
+ */
201
+ async ensureProfileFile(profilePath) {
202
+ try {
203
+ // Check if file exists
204
+ await fs.access(profilePath);
205
+ this.log('debug', `Profile file exists: ${profilePath}`);
206
+ return true;
207
+ } catch (error) {
208
+ // File doesn't exist, create it
209
+ this.log('info', `Creating profile file: ${profilePath}`);
210
+
211
+ try {
212
+ // Create directory if it doesn't exist
213
+ const dir = path.dirname(profilePath);
214
+ await fs.mkdir(dir, { recursive: true });
215
+
216
+ // Create empty file
217
+ await fs.writeFile(profilePath, '');
218
+ this.results.createdFiles.push(profilePath);
219
+ this.log('success', `Created profile file: ${profilePath}`);
220
+ return true;
221
+ } catch (createError) {
222
+ this.log('error', `Failed to create profile file: ${createError.message}`);
223
+ return false;
224
+ }
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Check if configuration already exists
230
+ */
231
+ async hasExistingConfiguration(profilePath) {
232
+ try {
233
+ const content = await fs.readFile(profilePath, 'utf8');
234
+ const marker = '# Stigmergy CLI Environment Configuration';
235
+ return content.includes(marker);
236
+ } catch (error) {
237
+ return false;
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Write persistent configuration to shell profile
243
+ */
244
+ async writePersistentConfiguration(npmConfig) {
245
+ this.log('info', 'Writing persistent shell configuration...');
246
+
247
+ // Detect shell and get profile file
248
+ this.results.shellType = this.detectShell();
249
+ this.results.profileFile = this.getShellProfileFile(this.results.shellType);
250
+
251
+ this.log('debug', `Detected shell: ${this.results.shellType}`);
252
+ if (this.results.profileFile) {
253
+ this.log('debug', `Profile file: ${this.results.profileFile}`);
254
+ }
255
+
256
+ if (!this.results.profileFile) {
257
+ if (this.results.shellType === 'cmd') {
258
+ this.log('warn', 'Command Prompt detected, providing manual instructions');
259
+ return await this.handleCmdPrompt(npmConfig);
260
+ } else {
261
+ this.log('error', 'Could not determine shell profile file');
262
+ return false;
263
+ }
264
+ }
265
+
266
+ // Generate configuration
267
+ const { config } = this.generatePersistentConfig(npmConfig);
268
+
269
+ if (this.options.dryRun) {
270
+ this.log('info', 'DRY RUN - Would write configuration:');
271
+ console.log(config);
272
+ return true;
273
+ }
274
+
275
+ try {
276
+ // Ensure profile file exists
277
+ if (!await this.ensureProfileFile(this.results.profileFile)) {
278
+ return false;
279
+ }
280
+
281
+ // Check for existing configuration
282
+ const hasExisting = await this.hasExistingConfiguration(this.results.profileFile);
283
+
284
+ if (hasExisting && !this.options.force) {
285
+ this.log('info', 'Configuration already exists in profile file');
286
+ this.results.configured = true;
287
+ return true;
288
+ }
289
+
290
+ if (hasExisting && this.options.force) {
291
+ this.log('warn', 'Overwriting existing configuration due to --force flag');
292
+ // Remove existing configuration
293
+ await this.removeExistingConfiguration(this.results.profileFile);
294
+ }
295
+
296
+ // Append configuration to profile
297
+ await fs.appendFile(this.results.profileFile, config);
298
+ this.results.modifiedFiles.push(this.results.profileFile);
299
+ this.results.configured = true;
300
+
301
+ this.log('success', `Configuration written to: ${this.results.profileFile}`);
302
+
303
+ return true;
304
+
305
+ } catch (error) {
306
+ this.log('error', `Failed to write configuration: ${error.message}`);
307
+ return false;
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Handle Command Prompt case (no profile files)
313
+ */
314
+ async handleCmdPrompt(npmConfig) {
315
+ const { npmGlobalDir, npmBinDir } = npmConfig;
316
+
317
+ this.log('info', 'Command Prompt detected - providing multiple setup options:');
318
+
319
+ console.log('\nšŸ”§ Command Prompt Setup Options:');
320
+ console.log('=====================================');
321
+
322
+ console.log('\nOption 1: Temporary setup (current session only)');
323
+ console.log(`set npm_config_prefix=${npmGlobalDir}`);
324
+ console.log(`set PATH=${npmBinDir};%PATH%`);
325
+
326
+ console.log('\nOption 2: Permanent setup (via registry)');
327
+ console.log('Run these commands as Administrator:');
328
+ console.log(`setx npm_config_prefix "${npmGlobalDir}"`);
329
+ console.log(`setx PATH "%PATH%;${npmBinDir}"`);
330
+
331
+ console.log('\nOption 3: Use PowerShell instead');
332
+ console.log('PowerShell supports profile files for permanent configuration');
333
+
334
+ console.log('\nšŸ’” Recommendation: Use PowerShell for better configuration management');
335
+
336
+ // Write configuration to a batch file for easy execution
337
+ const batchFile = path.join(process.env.TEMP || '/tmp', 'stigmergy-setup.bat');
338
+ const batchContent = `@echo off
339
+ echo Setting up Stigmergy CLI environment...
340
+ set npm_config_prefix=${npmGlobalDir}
341
+ set PATH=${npmBinDir};%PATH%
342
+ echo Environment configured for this session.
343
+ echo.
344
+ echo To make permanent, run:
345
+ echo setx npm_config_prefix "${npmGlobalDir}"
346
+ echo setx PATH "%PATH%;${npmBinDir}"
347
+ `;
348
+
349
+ try {
350
+ await fs.writeFile(batchFile, batchContent);
351
+ console.log(`\nšŸ“ Created setup script: ${batchFile}`);
352
+ console.log('You can run this script to set up the environment.');
353
+ } catch (error) {
354
+ this.log('warn', `Could not create setup script: ${error.message}`);
355
+ }
356
+
357
+ return true; // We've provided instructions, so consider it handled
358
+ }
359
+
360
+ /**
361
+ * Remove existing configuration from profile
362
+ */
363
+ async removeExistingConfiguration(profilePath) {
364
+ try {
365
+ const content = await fs.readFile(profilePath, 'utf8');
366
+ const lines = content.split('\n');
367
+ const startMarker = '# Stigmergy CLI Environment Configuration';
368
+ const endMarker = '# End Stigmergy CLI Configuration';
369
+
370
+ let inStigmergyConfig = false;
371
+ const filteredLines = lines.filter(line => {
372
+ if (line.includes(startMarker)) {
373
+ inStigmergyConfig = true;
374
+ return false;
375
+ }
376
+ if (line.includes(endMarker) || inStigmergyConfig && line.trim() === '') {
377
+ inStigmergyConfig = false;
378
+ return false;
379
+ }
380
+ return !inStigmergyConfig;
381
+ });
382
+
383
+ await fs.writeFile(profilePath, filteredLines.join('\n'));
384
+ this.log('debug', 'Removed existing Stigmergy configuration');
385
+ } catch (error) {
386
+ this.log('warn', `Could not remove existing configuration: ${error.message}`);
387
+ }
388
+ }
389
+
390
+ /**
391
+ * Verify configuration was written correctly
392
+ */
393
+ async verifyConfiguration() {
394
+ if (!this.results.profileFile) {
395
+ return false;
396
+ }
397
+
398
+ try {
399
+ const content = await fs.readFile(this.results.profileFile, 'utf8');
400
+ const hasConfig = content.includes('Stigmergy CLI Environment Configuration');
401
+
402
+ if (hasConfig) {
403
+ this.log('success', 'Configuration verified in profile file');
404
+ return true;
405
+ } else {
406
+ this.log('error', 'Configuration not found in profile file');
407
+ return false;
408
+ }
409
+ } catch (error) {
410
+ this.log('error', `Failed to verify configuration: ${error.message}`);
411
+ return false;
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Display setup instructions
417
+ */
418
+ displaySetupInstructions() {
419
+ console.log('\n' + '='.repeat(60));
420
+ console.log('šŸ”§ Shell Configuration Setup Instructions');
421
+ console.log('='.repeat(60));
422
+
423
+ if (this.results.configured) {
424
+ console.log('\nāœ… Configuration successfully written!');
425
+ console.log(`šŸ“„ Shell Profile: ${this.results.profileFile}`);
426
+ console.log(`šŸ”§ Shell Type: ${this.results.shellType}`);
427
+
428
+ console.log('\nšŸ’” Next Steps:');
429
+ console.log('1. Restart your terminal to load the new configuration');
430
+ console.log('2. Or manually source the profile file:');
431
+
432
+ switch (this.results.shellType) {
433
+ case 'powershell':
434
+ console.log(' . $PROFILE');
435
+ break;
436
+ case 'zsh':
437
+ console.log(' source ~/.zshrc');
438
+ break;
439
+ case 'bash':
440
+ console.log(' source ~/.bashrc');
441
+ break;
442
+ case 'fish':
443
+ console.log(' source ~/.config/fish/config.fish');
444
+ break;
445
+ }
446
+
447
+ console.log('3. Verify: stigmergy --version');
448
+
449
+ } else {
450
+ console.log('\nāŒ Configuration could not be written automatically');
451
+ console.log('\nšŸ’” Manual setup required:');
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Get results
457
+ */
458
+ getResults() {
459
+ return {
460
+ ...this.results,
461
+ timestamp: new Date().toISOString(),
462
+ platform: process.platform,
463
+ homeDirectory: os.homedir()
464
+ };
465
+ }
466
+ }
467
+
468
+ module.exports = PersistentShellConfigurator;