stigmergy 1.2.8 → 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.
- package/README.md +40 -6
- package/STIGMERGY.md +10 -0
- package/package.json +19 -5
- package/scripts/preuninstall.js +10 -0
- package/src/adapters/claude/install_claude_integration.js +21 -21
- package/src/adapters/codebuddy/install_codebuddy_integration.js +54 -51
- package/src/adapters/codex/install_codex_integration.js +27 -28
- package/src/adapters/gemini/install_gemini_integration.js +60 -60
- package/src/adapters/iflow/install_iflow_integration.js +72 -72
- package/src/adapters/qoder/install_qoder_integration.js +64 -64
- package/src/adapters/qwen/install_qwen_integration.js +7 -7
- package/src/cli/router.js +581 -175
- package/src/commands/skill-bridge.js +39 -0
- package/src/commands/skill-handler.js +150 -0
- package/src/commands/skill.js +127 -0
- package/src/core/cli_path_detector.js +573 -0
- package/src/core/cli_tools.js +72 -1
- package/src/core/coordination/nodejs/AdapterManager.js +29 -1
- package/src/core/directory_permission_manager.js +568 -0
- package/src/core/enhanced_cli_installer.js +609 -0
- package/src/core/installer.js +232 -88
- package/src/core/multilingual/language-pattern-manager.js +78 -50
- package/src/core/persistent_shell_configurator.js +468 -0
- package/src/core/skills/StigmergySkillManager.js +357 -0
- package/src/core/skills/__tests__/SkillInstaller.test.js +275 -0
- package/src/core/skills/__tests__/SkillParser.test.js +202 -0
- package/src/core/skills/__tests__/SkillReader.test.js +189 -0
- package/src/core/skills/cli-command-test.js +201 -0
- package/src/core/skills/comprehensive-e2e-test.js +473 -0
- package/src/core/skills/e2e-test.js +267 -0
- package/src/core/skills/embedded-openskills/SkillInstaller.js +438 -0
- package/src/core/skills/embedded-openskills/SkillParser.js +123 -0
- package/src/core/skills/embedded-openskills/SkillReader.js +143 -0
- package/src/core/skills/integration-test.js +248 -0
- package/src/core/skills/package.json +6 -0
- package/src/core/skills/regression-test.js +285 -0
- package/src/core/skills/run-all-tests.js +129 -0
- package/src/core/skills/sync-test.js +210 -0
- package/src/core/skills/test-runner.js +242 -0
- package/src/utils/helpers.js +3 -20
- package/src/auth.js +0 -173
- package/src/auth_command.js +0 -208
- package/src/calculator.js +0 -313
- package/src/core/enhanced_installer.js +0 -479
- package/src/core/enhanced_uninstaller.js +0 -638
- package/src/data_encryption.js +0 -143
- package/src/data_structures.js +0 -440
- package/src/deploy.js +0 -55
package/src/data_encryption.js
DELETED
|
@@ -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
|
-
};
|
package/src/data_structures.js
DELETED
|
@@ -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 };
|