stigmergy 1.2.8 → 1.2.11

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 (48) hide show
  1. package/README.md +40 -6
  2. package/STIGMERGY.md +10 -0
  3. package/package.json +19 -5
  4. package/scripts/preuninstall.js +10 -0
  5. package/src/adapters/claude/install_claude_integration.js +21 -21
  6. package/src/adapters/codebuddy/install_codebuddy_integration.js +54 -51
  7. package/src/adapters/codex/install_codex_integration.js +27 -28
  8. package/src/adapters/gemini/install_gemini_integration.js +60 -60
  9. package/src/adapters/iflow/install_iflow_integration.js +72 -72
  10. package/src/adapters/qoder/install_qoder_integration.js +64 -64
  11. package/src/adapters/qwen/install_qwen_integration.js +7 -7
  12. package/src/cli/router.js +581 -175
  13. package/src/commands/skill-bridge.js +39 -0
  14. package/src/commands/skill-handler.js +150 -0
  15. package/src/commands/skill.js +127 -0
  16. package/src/core/cli_path_detector.js +710 -0
  17. package/src/core/cli_tools.js +72 -1
  18. package/src/core/coordination/nodejs/AdapterManager.js +29 -1
  19. package/src/core/directory_permission_manager.js +568 -0
  20. package/src/core/enhanced_cli_installer.js +609 -0
  21. package/src/core/installer.js +232 -88
  22. package/src/core/multilingual/language-pattern-manager.js +78 -50
  23. package/src/core/persistent_shell_configurator.js +468 -0
  24. package/src/core/skills/StigmergySkillManager.js +357 -0
  25. package/src/core/skills/__tests__/SkillInstaller.test.js +275 -0
  26. package/src/core/skills/__tests__/SkillParser.test.js +202 -0
  27. package/src/core/skills/__tests__/SkillReader.test.js +189 -0
  28. package/src/core/skills/cli-command-test.js +201 -0
  29. package/src/core/skills/comprehensive-e2e-test.js +473 -0
  30. package/src/core/skills/e2e-test.js +267 -0
  31. package/src/core/skills/embedded-openskills/SkillInstaller.js +438 -0
  32. package/src/core/skills/embedded-openskills/SkillParser.js +123 -0
  33. package/src/core/skills/embedded-openskills/SkillReader.js +143 -0
  34. package/src/core/skills/integration-test.js +248 -0
  35. package/src/core/skills/package.json +6 -0
  36. package/src/core/skills/regression-test.js +285 -0
  37. package/src/core/skills/run-all-tests.js +129 -0
  38. package/src/core/skills/sync-test.js +210 -0
  39. package/src/core/skills/test-runner.js +242 -0
  40. package/src/utils/helpers.js +3 -20
  41. package/src/auth.js +0 -173
  42. package/src/auth_command.js +0 -208
  43. package/src/calculator.js +0 -313
  44. package/src/core/enhanced_installer.js +0 -479
  45. package/src/core/enhanced_uninstaller.js +0 -638
  46. package/src/data_encryption.js +0 -143
  47. package/src/data_structures.js +0 -440
  48. package/src/deploy.js +0 -55
@@ -1,143 +0,0 @@
1
- /**
2
- * Data encryption utilities for the Stigmergy CLI
3
- * Provides secure data encryption and decryption functions using AES-256-GCM
4
- */
5
-
6
- const crypto = require('crypto');
7
-
8
- /**
9
- * Encrypts data using AES-256-GCM authenticated encryption
10
- *
11
- * This function provides secure symmetric encryption with authentication.
12
- * It generates a random initialization vector for each encryption operation
13
- * and returns the encrypted data along with the IV and authentication tag.
14
- *
15
- * @param {string|Buffer} data - The plaintext data to encrypt
16
- * @param {string|Buffer} secretKey - The secret key for encryption (must be 32 bytes for AES-256)
17
- * @returns {Object} Object containing encrypted data, IV, and authentication tag
18
- * @throws {Error} If encryption fails due to invalid inputs or cryptographic errors
19
- *
20
- * @example
21
- * const crypto = require('crypto');
22
- * const secretKey = crypto.randomBytes(32); // 256-bit key
23
- * const plaintext = "Secret message";
24
- * const encryptedObj = encryptData(plaintext, secretKey);
25
- * console.log(encryptedObj);
26
- * // Output: {
27
- * // encryptedData: 'a3f5b7c8...',
28
- * // iv: 'MjRkOGZj...',
29
- * // authTag: 'YzQyNTgx...'
30
- * // }
31
- */
32
- function encryptData(data, secretKey) {
33
- // Validate inputs
34
- if (!data) {
35
- throw new Error('Data to encrypt cannot be empty');
36
- }
37
-
38
- if (!secretKey) {
39
- throw new Error('Secret key is required');
40
- }
41
-
42
- // Generate a random initialization vector
43
- const iv = crypto.randomBytes(16);
44
-
45
- // Create cipher using AES-256-GCM
46
- const cipher = crypto.createCipherGCM('aes-256-gcm', secretKey, iv);
47
-
48
- // Encrypt the data
49
- let encrypted;
50
- if (typeof data === 'string') {
51
- encrypted = cipher.update(data, 'utf8', 'hex');
52
- } else {
53
- encrypted = cipher.update(data);
54
- encrypted = encrypted.toString('hex');
55
- }
56
- cipher.final();
57
-
58
- // Get the authentication tag
59
- const authTag = cipher.getAuthTag();
60
-
61
- // Return encrypted data with IV and auth tag
62
- return {
63
- encryptedData: encrypted,
64
- iv: iv.toString('base64'),
65
- authTag: authTag.toString('base64'),
66
- };
67
- }
68
-
69
- /**
70
- * Decrypts data using AES-256-GCM authenticated decryption
71
- *
72
- * This function decrypts data that was encrypted with encryptData().
73
- * It requires the encrypted data object containing the encrypted data,
74
- * initialization vector, and authentication tag.
75
- *
76
- * @param {Object} encryptedObj - Object containing encrypted data, IV, and auth tag
77
- * @param {string|Buffer} secretKey - The secret key used for encryption
78
- * @returns {string} The decrypted plaintext data
79
- * @throws {Error} If decryption fails due to invalid inputs, tampered data, or cryptographic errors
80
- *
81
- * @example
82
- * const decrypted = decryptData(encryptedObj, secretKey);
83
- * console.log(decrypted); // "Secret message"
84
- */
85
- function decryptData(encryptedObj, secretKey) {
86
- // Validate inputs
87
- if (
88
- !encryptedObj ||
89
- !encryptedObj.encryptedData ||
90
- !encryptedObj.iv ||
91
- !encryptedObj.authTag
92
- ) {
93
- throw new Error('Invalid encrypted object');
94
- }
95
-
96
- if (!secretKey) {
97
- throw new Error('Secret key is required');
98
- }
99
-
100
- // Decode base64 encoded values
101
- const iv = Buffer.from(encryptedObj.iv, 'base64');
102
- const authTag = Buffer.from(encryptedObj.authTag, 'base64');
103
-
104
- // Create decipher using AES-256-GCM
105
- const decipher = crypto.createDecipherGCM('aes-256-gcm', secretKey, iv);
106
-
107
- // Set the authentication tag
108
- decipher.setAuthTag(authTag);
109
-
110
- // Decrypt the data
111
- let decrypted;
112
- if (typeof encryptedObj.encryptedData === 'string') {
113
- decrypted = decipher.update(encryptedObj.encryptedData, 'hex', 'utf8');
114
- } else {
115
- decrypted = decipher.update(encryptedObj.encryptedData);
116
- decrypted = decrypted.toString('utf8');
117
- }
118
- decipher.final();
119
-
120
- return decrypted;
121
- }
122
-
123
- /**
124
- * Generates a cryptographically secure random key
125
- *
126
- * This function generates a random key suitable for AES-256 encryption.
127
- *
128
- * @param {number} [length=32] - Length of the key in bytes (32 bytes = 256 bits)
129
- * @returns {Buffer} A cryptographically secure random key
130
- *
131
- * @example
132
- * const key = generateKey(); // 32-byte key for AES-256
133
- * const shortKey = generateKey(16); // 16-byte key for AES-128
134
- */
135
- function generateKey(length = 32) {
136
- return crypto.randomBytes(length);
137
- }
138
-
139
- module.exports = {
140
- encryptData,
141
- decryptData,
142
- generateKey,
143
- };
@@ -1,440 +0,0 @@
1
- /**
2
- * Data Structures for the Stigmergy CLI
3
- */
4
-
5
- /**
6
- * HashTable implementation with collision handling using chaining and open addressing
7
- */
8
- class HashTable {
9
- /**
10
- * Create a new HashTable
11
- * @param {number} size - Initial size of the hash table
12
- * @param {string} collisionStrategy - Collision handling strategy ('chaining' or 'openAddressing')
13
- */
14
- constructor(size = 53, collisionStrategy = 'chaining') {
15
- this.size = size;
16
- this.collisionStrategy = collisionStrategy;
17
-
18
- if (collisionStrategy === 'chaining') {
19
- this.buckets = new Array(size).fill(null).map(() => []);
20
- } else if (collisionStrategy === 'openAddressing') {
21
- this.buckets = new Array(size).fill(null);
22
- this.deleted = new Array(size).fill(false);
23
- } else {
24
- throw new Error(
25
- 'Invalid collision strategy. Use "chaining" or "openAddressing"',
26
- );
27
- }
28
-
29
- this.count = 0;
30
- this.loadFactorThreshold = 0.75;
31
- }
32
-
33
- /**
34
- * Hash function to convert a key to an index
35
- * @param {string|number} key - Key to hash
36
- * @returns {number} Index in the hash table
37
- */
38
- _hash(key) {
39
- if (typeof key === 'number') {
40
- return key % this.size;
41
- }
42
-
43
- let hash = 0;
44
- const PRIME = 31;
45
-
46
- for (let i = 0; i < key.length; i++) {
47
- hash = (hash * PRIME + key.charCodeAt(i)) % this.size;
48
- }
49
-
50
- return hash;
51
- }
52
-
53
- /**
54
- * Secondary hash function for double hashing in open addressing
55
- * @param {string|number} key - Key to hash
56
- * @returns {number} Secondary hash value
57
- */
58
- _hash2(key) {
59
- if (typeof key === 'number') {
60
- return 7 - (key % 7);
61
- }
62
-
63
- let hash = 0;
64
- for (let i = 0; i < key.length; i++) {
65
- hash = (hash * 3 + key.charCodeAt(i)) % this.size;
66
- }
67
-
68
- return 7 - (hash % 7);
69
- }
70
-
71
- /**
72
- * Resize the hash table when load factor exceeds threshold
73
- */
74
- _resize() {
75
- const oldBuckets = this.buckets;
76
- const oldDeleted = this.deleted;
77
- const oldSize = this.size;
78
-
79
- // Double the size
80
- this.size *= 2;
81
- this.count = 0;
82
-
83
- if (this.collisionStrategy === 'chaining') {
84
- this.buckets = new Array(this.size).fill(null).map(() => []);
85
- } else {
86
- this.buckets = new Array(this.size).fill(null);
87
- this.deleted = new Array(this.size).fill(false);
88
- }
89
-
90
- // Rehash all existing elements
91
- if (this.collisionStrategy === 'chaining') {
92
- for (let i = 0; i < oldSize; i++) {
93
- const bucket = oldBuckets[i];
94
- if (bucket) {
95
- for (const [key, value] of bucket) {
96
- this.set(key, value);
97
- }
98
- }
99
- }
100
- } else {
101
- for (let i = 0; i < oldSize; i++) {
102
- if (oldBuckets[i] !== null && !oldDeleted[i]) {
103
- this.set(oldBuckets[i][0], oldBuckets[i][1]);
104
- }
105
- }
106
- }
107
- }
108
-
109
- /**
110
- * Set a key-value pair in the hash table
111
- * @param {string|number} key - Key to store
112
- * @param {*} value - Value to store
113
- * @returns {HashTable} The hash table instance
114
- */
115
- set(key, value) {
116
- // Check if resize is needed
117
- if (this.count >= this.size * this.loadFactorThreshold) {
118
- this._resize();
119
- }
120
-
121
- if (this.collisionStrategy === 'chaining') {
122
- return this._setChaining(key, value);
123
- } else {
124
- return this._setOpenAddressing(key, value);
125
- }
126
- }
127
-
128
- /**
129
- * Set a key-value pair using chaining
130
- * @private
131
- */
132
- _setChaining(key, value) {
133
- const index = this._hash(key);
134
- const bucket = this.buckets[index];
135
-
136
- // Check if key already exists
137
- for (let i = 0; i < bucket.length; i++) {
138
- if (bucket[i][0] === key) {
139
- bucket[i][1] = value; // Update existing value
140
- return this;
141
- }
142
- }
143
-
144
- // Add new key-value pair
145
- bucket.push([key, value]);
146
- this.count++;
147
- return this;
148
- }
149
-
150
- /**
151
- * Set a key-value pair using open addressing with double hashing
152
- * @private
153
- */
154
- _setOpenAddressing(key, value) {
155
- let index = this._hash(key);
156
- let originalIndex = index;
157
- let i = 0;
158
-
159
- // Probe until we find an empty slot or deleted slot
160
- while (
161
- this.buckets[index] !== null &&
162
- !this.deleted[index] &&
163
- this.buckets[index][0] !== key
164
- ) {
165
- i++;
166
- index = (originalIndex + i * this._hash2(key)) % this.size;
167
-
168
- // If we've checked all slots, the table is full
169
- if (i >= this.size) {
170
- // Instead of throwing an error, we'll resize and try again
171
- this._resize();
172
- return this.set(key, value);
173
- }
174
- }
175
-
176
- // If key already exists, update the value
177
- if (
178
- this.buckets[index] !== null &&
179
- !this.deleted[index] &&
180
- this.buckets[index][0] === key
181
- ) {
182
- this.buckets[index][1] = value;
183
- } else {
184
- // Insert new key-value pair
185
- this.buckets[index] = [key, value];
186
- this.deleted[index] = false;
187
- this.count++;
188
- }
189
-
190
- return this;
191
- }
192
-
193
- /**
194
- * Get a value by its key
195
- * @param {string|number} key - Key to look up
196
- * @returns {*} The value associated with the key, or undefined if not found
197
- */
198
- get(key) {
199
- if (this.collisionStrategy === 'chaining') {
200
- return this._getChaining(key);
201
- } else {
202
- return this._getOpenAddressing(key);
203
- }
204
- }
205
-
206
- /**
207
- * Get a value using chaining
208
- * @private
209
- */
210
- _getChaining(key) {
211
- const index = this._hash(key);
212
- const bucket = this.buckets[index];
213
-
214
- for (let i = 0; i < bucket.length; i++) {
215
- if (bucket[i][0] === key) {
216
- return bucket[i][1];
217
- }
218
- }
219
-
220
- return undefined;
221
- }
222
-
223
- /**
224
- * Get a value using open addressing
225
- * @private
226
- */
227
- _getOpenAddressing(key) {
228
- let index = this._hash(key);
229
- let i = 0;
230
-
231
- // Probe until we find the key or an empty slot
232
- while (this.buckets[index] !== null) {
233
- if (!this.deleted[index] && this.buckets[index][0] === key) {
234
- return this.buckets[index][1];
235
- }
236
-
237
- i++;
238
- index = (this._hash(key) + i * this._hash2(key)) % this.size;
239
-
240
- // Prevent infinite loop
241
- if (i >= this.size) {
242
- break;
243
- }
244
- }
245
-
246
- return undefined;
247
- }
248
-
249
- /**
250
- * Delete a key-value pair from the hash table
251
- * @param {string|number} key - Key to delete
252
- * @returns {boolean} True if the key was found and deleted, false otherwise
253
- */
254
- delete(key) {
255
- if (this.collisionStrategy === 'chaining') {
256
- return this._deleteChaining(key);
257
- } else {
258
- return this._deleteOpenAddressing(key);
259
- }
260
- }
261
-
262
- /**
263
- * Delete a key-value pair using chaining
264
- * @private
265
- */
266
- _deleteChaining(key) {
267
- const index = this._hash(key);
268
- const bucket = this.buckets[index];
269
-
270
- for (let i = 0; i < bucket.length; i++) {
271
- if (bucket[i][0] === key) {
272
- bucket.splice(i, 1);
273
- this.count--;
274
- return true;
275
- }
276
- }
277
-
278
- return false;
279
- }
280
-
281
- /**
282
- * Delete a key-value pair using open addressing
283
- * @private
284
- */
285
- _deleteOpenAddressing(key) {
286
- let index = this._hash(key);
287
- let i = 0;
288
-
289
- // Probe until we find the key or an empty slot
290
- while (this.buckets[index] !== null) {
291
- if (!this.deleted[index] && this.buckets[index][0] === key) {
292
- this.deleted[index] = true;
293
- this.count--;
294
- return true;
295
- }
296
-
297
- i++;
298
- index = (this._hash(key) + i * this._hash2(key)) % this.size;
299
-
300
- // Prevent infinite loop
301
- if (i >= this.size) {
302
- break;
303
- }
304
- }
305
-
306
- return false;
307
- }
308
-
309
- /**
310
- * Check if a key exists in the hash table
311
- * @param {string|number} key - Key to check
312
- * @returns {boolean} True if the key exists, false otherwise
313
- */
314
- has(key) {
315
- return this.get(key) !== undefined;
316
- }
317
-
318
- /**
319
- * Get all keys in the hash table
320
- * @returns {Array} Array of all keys
321
- */
322
- keys() {
323
- const keysArr = [];
324
-
325
- if (this.collisionStrategy === 'chaining') {
326
- for (let i = 0; i < this.size; i++) {
327
- const bucket = this.buckets[i];
328
- if (bucket) {
329
- for (const [key, __] of bucket) {
330
- keysArr.push(key);
331
- }
332
- }
333
- }
334
- } else {
335
- for (let i = 0; i < this.size; i++) {
336
- if (this.buckets[i] !== null && !this.deleted[i]) {
337
- keysArr.push(this.buckets[i][0]);
338
- }
339
- }
340
- }
341
-
342
- return keysArr;
343
- }
344
-
345
- /**
346
- * Get all values in the hash table
347
- * @returns {Array} Array of all values
348
- */
349
- values() {
350
- const valuesArr = [];
351
-
352
- if (this.collisionStrategy === 'chaining') {
353
- for (let i = 0; i < this.size; i++) {
354
- const bucket = this.buckets[i];
355
- if (bucket) {
356
- for (const [__, value] of bucket) {
357
- valuesArr.push(value);
358
- }
359
- }
360
- }
361
- } else {
362
- for (let i = 0; i < this.size; i++) {
363
- if (this.buckets[i] !== null && !this.deleted[i]) {
364
- valuesArr.push(this.buckets[i][1]);
365
- }
366
- }
367
- }
368
-
369
- return valuesArr;
370
- }
371
-
372
- /**
373
- * Get all key-value pairs in the hash table
374
- * @returns {Array} Array of all key-value pairs
375
- */
376
- entries() {
377
- const entriesArr = [];
378
-
379
- if (this.collisionStrategy === 'chaining') {
380
- for (let i = 0; i < this.size; i++) {
381
- const bucket = this.buckets[i];
382
- if (bucket) {
383
- for (const [key, value] of bucket) {
384
- entriesArr.push([key, value]);
385
- }
386
- }
387
- }
388
- } else {
389
- for (let i = 0; i < this.size; i++) {
390
- if (this.buckets[i] !== null && !this.deleted[i]) {
391
- entriesArr.push([this.buckets[i][0], this.buckets[i][1]]);
392
- }
393
- }
394
- }
395
-
396
- return entriesArr;
397
- }
398
-
399
- /**
400
- * Clear the hash table
401
- */
402
- clear() {
403
- if (this.collisionStrategy === 'chaining') {
404
- this.buckets = new Array(this.size).fill(null).map(() => []);
405
- } else {
406
- this.buckets = new Array(this.size).fill(null);
407
- this.deleted = new Array(this.size).fill(false);
408
- }
409
-
410
- this.count = 0;
411
- }
412
-
413
- /**
414
- * Get the size of the hash table
415
- * @returns {number} Number of key-value pairs in the hash table
416
- */
417
- getSize() {
418
- return this.count;
419
- }
420
-
421
- /**
422
- * Check if the hash table is empty
423
- * @returns {boolean} True if the hash table is empty, false otherwise
424
- */
425
- isEmpty() {
426
- return this.count === 0;
427
- }
428
-
429
- /**
430
- * Get the load factor of the hash table
431
- * @returns {number} Load factor (number of elements / table size)
432
- */
433
- getLoadFactor() {
434
- return this.count / this.size;
435
- }
436
- }
437
-
438
- module.exports = {
439
- HashTable,
440
- };
package/src/deploy.js DELETED
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Stigmergy Deployment Script
5
- * This script deploys hooks and integrations for all available CLI tools
6
- */
7
-
8
- const fs = require('fs').promises;
9
- const path = require('path');
10
-
11
- // Import the main Stigmergy installer
12
- const StigmergyInstaller = require('./core/installer');
13
-
14
- // Set up global error handlers using our error handler module
15
- const { setupGlobalErrorHandlers } = require('./core/error_handler');
16
- setupGlobalErrorHandlers();
17
-
18
- async function deploy() {
19
- console.log('Stigmergy Deployment Script');
20
- console.log('==========================');
21
-
22
- try {
23
- // Create installer instance
24
- const installer = new StigmergyInstaller();
25
-
26
- // Scan for available tools
27
- console.log('[SCAN] Scanning for available CLI tools...');
28
- const scanResult = await installer.scanCLI();
29
- const available = scanResult.available;
30
-
31
- // Deploy hooks for all available tools
32
- console.log('[DEPLOY] Deploying hooks for all available tools...');
33
- await installer.deployHooks(available);
34
-
35
- console.log('\n[SUCCESS] Deployment completed successfully!');
36
- return true;
37
- } catch (error) {
38
- console.error('[ERROR] Deployment failed:', error.message);
39
- return false;
40
- }
41
- }
42
-
43
- // Run deployment if called directly
44
- if (require.main === module) {
45
- deploy()
46
- .then((success) => {
47
- process.exit(success ? 0 : 1);
48
- })
49
- .catch((error) => {
50
- console.error('[FATAL ERROR]:', error.message);
51
- process.exit(1);
52
- });
53
- }
54
-
55
- module.exports = { deploy };