stigmergy 1.0.99 → 1.1.0

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,236 @@
1
+ // src/core/coordination/nodejs/CLIIntegrationManager.js
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+ const { spawn, spawnSync } = require('child_process');
6
+
7
+ class CLIIntegrationManager {
8
+ constructor() {
9
+ this.supportedCLIs = {
10
+ 'claude': {
11
+ name: 'Claude CLI',
12
+ executable: 'claude',
13
+ hooks: ['user_prompt_submit', 'tool_use_pre', 'tool_use_post', 'response_generated']
14
+ },
15
+ 'gemini': {
16
+ name: 'Gemini CLI',
17
+ executable: 'gemini',
18
+ extensions: ['on_user_input', 'on_response_generated', 'on_tool_execution']
19
+ },
20
+ 'qwencode': {
21
+ name: 'QwenCode CLI',
22
+ executable: 'qwencode',
23
+ inheritance: ['on_code_generation', 'on_analysis_request', 'on_refactor_request']
24
+ },
25
+ 'iflow': {
26
+ name: 'iFlow CLI',
27
+ executable: 'iflow',
28
+ workflows: ['on_workflow_start', 'on_stage_complete', 'on_workflow_success']
29
+ },
30
+ 'qoder': {
31
+ name: 'Qoder CLI',
32
+ executable: 'qoder',
33
+ notifications: ['on_user_notification', 'on_system_alert', 'on_task_completion']
34
+ },
35
+ 'codebuddy': {
36
+ name: 'CodeBuddy CLI',
37
+ executable: 'codebuddy',
38
+ skills: ['on_skill_invocation', 'on_buddy_request', 'on_cross_cli_task']
39
+ },
40
+ 'codex': {
41
+ name: 'Codex CLI',
42
+ executable: 'codex',
43
+ slashCommands: ['/x', '/cross-cli', '/delegate']
44
+ },
45
+ 'copilot': {
46
+ name: 'Copilot CLI',
47
+ executable: 'copilot',
48
+ mcp: ['cross_cli_execute']
49
+ }
50
+ };
51
+ }
52
+
53
+ async checkCLIAvailability(cliName) {
54
+ console.log(`[CLI_INTEGRATION] Checking availability of ${cliName}...`);
55
+
56
+ const cliInfo = this.supportedCLIs[cliName.toLowerCase()];
57
+ if (!cliInfo) {
58
+ return { available: false, error: `Unsupported CLI: ${cliName}` };
59
+ }
60
+
61
+ try {
62
+ // Check if CLI executable is available
63
+ const result = spawnSync(cliInfo.executable, ['--version'], {
64
+ timeout: 5000,
65
+ stdio: ['pipe', 'pipe', 'pipe']
66
+ });
67
+
68
+ if (result.status === 0) {
69
+ const version = result.stdout ? result.stdout.toString().trim() : 'Unknown';
70
+ return {
71
+ available: true,
72
+ version: version,
73
+ name: cliInfo.name
74
+ };
75
+ } else {
76
+ return {
77
+ available: false,
78
+ error: `CLI returned non-zero exit code: ${result.status}`,
79
+ stderr: result.stderr ? result.stderr.toString() : ''
80
+ };
81
+ }
82
+ } catch (error) {
83
+ return {
84
+ available: false,
85
+ error: `Failed to execute CLI: ${error.message}`
86
+ };
87
+ }
88
+ }
89
+
90
+ async listAvailableCLIs() {
91
+ console.log('[CLI_INTEGRATION] Listing available CLIs...');
92
+
93
+ const results = {};
94
+ for (const [cliName, cliInfo] of Object.entries(this.supportedCLIs)) {
95
+ results[cliName] = await this.checkCLIAvailability(cliName);
96
+ }
97
+
98
+ return results;
99
+ }
100
+
101
+ async getNodeJsIntegrationScript(cliName) {
102
+ console.log(`[CLI_INTEGRATION] Generating Node.js integration script for ${cliName}...`);
103
+
104
+ const cliInfo = this.supportedCLIs[cliName.toLowerCase()];
105
+ if (!cliInfo) {
106
+ throw new Error(`Unsupported CLI: ${cliName}`);
107
+ }
108
+
109
+ // Generate a Node.js integration script
110
+ const script = `#!/usr/bin/env node
111
+
112
+ /**
113
+ * Node.js Integration Script for ${cliInfo.name}
114
+ * Auto-generated by Stigmergy CLI Integration Manager
115
+ */
116
+
117
+ const { spawn } = require('child_process');
118
+
119
+ class ${this.capitalize(cliName)}NodeJsIntegration {
120
+ constructor() {
121
+ this.cliName = '${cliName}';
122
+ this.executable = '${cliInfo.executable}';
123
+ }
124
+
125
+ async executeCommand(command, args = [], options = {}) {
126
+ return new Promise((resolve, reject) => {
127
+ const cliProcess = spawn(this.executable, [command, ...args], {
128
+ timeout: options.timeout || 30000,
129
+ ...options
130
+ });
131
+
132
+ let stdout = '';
133
+ let stderr = '';
134
+
135
+ cliProcess.stdout.on('data', (data) => {
136
+ stdout += data.toString();
137
+ });
138
+
139
+ cliProcess.stderr.on('data', (data) => {
140
+ stderr += data.toString();
141
+ });
142
+
143
+ cliProcess.on('close', (code) => {
144
+ if (code === 0) {
145
+ resolve(stdout.trim());
146
+ } else {
147
+ reject(new Error(\`CLI process exited with code \${code}: \${stderr}\`));
148
+ }
149
+ });
150
+
151
+ cliProcess.on('error', (error) => {
152
+ reject(new Error(\`Failed to start CLI process: \${error.message}\`));
153
+ });
154
+ });
155
+ }
156
+
157
+ async getVersion() {
158
+ try {
159
+ const version = await this.executeCommand('--version');
160
+ return version;
161
+ } catch (error) {
162
+ throw new Error(\`Failed to get ${cliName} version: \${error.message}\`);
163
+ }
164
+ }
165
+
166
+ async executeTask(task, context = {}) {
167
+ // This would depend on the specific CLI's interface
168
+ // For demonstration, we'll simulate execution
169
+ return \`[NODE.JS INTEGRATION] Simulated execution of task: \${task}\`;
170
+ }
171
+
172
+ capitalize(str) {
173
+ return str.charAt(0).toUpperCase() + str.slice(1);
174
+ }
175
+ }
176
+
177
+ module.exports = ${this.capitalize(cliName)}NodeJsIntegration;
178
+
179
+ // If run directly, test the integration
180
+ if (require.main === module) {
181
+ const integration = new ${this.capitalize(cliName)}NodeJsIntegration();
182
+
183
+ integration.getVersion()
184
+ .then(version => {
185
+ console.log('${cliInfo.name} version:', version);
186
+ })
187
+ .catch(error => {
188
+ console.error('Failed to get version:', error.message);
189
+ });
190
+ }
191
+ `;
192
+
193
+ return script;
194
+ }
195
+
196
+ capitalize(str) {
197
+ return str.charAt(0).toUpperCase() + str.slice(1);
198
+ }
199
+
200
+ async deployNodeJsIntegration(cliName, targetDir) {
201
+ console.log(`[CLI_INTEGRATION] Deploying Node.js integration for ${cliName}...`);
202
+
203
+ if (!fs.existsSync(targetDir)) {
204
+ fs.mkdirSync(targetDir, { recursive: true });
205
+ }
206
+
207
+ const script = await this.getNodeJsIntegrationScript(cliName);
208
+ const scriptPath = path.join(targetDir, `${cliName}_nodejs_integration.js`);
209
+
210
+ fs.writeFileSync(scriptPath, script);
211
+
212
+ // Make executable
213
+ try {
214
+ fs.chmodSync(scriptPath, 0o755);
215
+ } catch (error) {
216
+ console.warn(`[CLI_INTEGRATION] Failed to make script executable:`, error.message);
217
+ }
218
+
219
+ return scriptPath;
220
+ }
221
+
222
+ async getSupportedFeatures(cliName) {
223
+ const cliInfo = this.supportedCLIs[cliName.toLowerCase()];
224
+ if (!cliInfo) {
225
+ return null;
226
+ }
227
+
228
+ return {
229
+ name: cliInfo.name,
230
+ executable: cliInfo.executable,
231
+ features: Object.keys(cliInfo).filter(key => key !== 'name' && key !== 'executable')
232
+ };
233
+ }
234
+ }
235
+
236
+ module.exports = CLIIntegrationManager;
@@ -0,0 +1,77 @@
1
+ // src/core/coordination/nodejs/HealthChecker.js
2
+ const os = require('os');
3
+
4
+ class HealthChecker {
5
+ constructor() {
6
+ this.checks = [
7
+ 'AdapterAvailability',
8
+ 'SystemResources',
9
+ 'DiskSpace'
10
+ ];
11
+ }
12
+
13
+ async checkHealth() {
14
+ console.log('[HEALTH_CHECKER] Performing health check...');
15
+
16
+ const results = {};
17
+ let overallHealthy = true;
18
+
19
+ for (const check of this.checks) {
20
+ try {
21
+ const methodName = `check${check}`;
22
+ if (typeof this[methodName] === 'function') {
23
+ results[check.toLowerCase()] = await this[methodName]();
24
+ } else {
25
+ results[check.toLowerCase()] = { healthy: false, error: `Method ${methodName} not found` };
26
+ overallHealthy = false;
27
+ }
28
+ } catch (error) {
29
+ results[check.toLowerCase()] = { healthy: false, error: error.message };
30
+ overallHealthy = false;
31
+ }
32
+ }
33
+
34
+ return {
35
+ healthy: overallHealthy,
36
+ timestamp: new Date().toISOString(),
37
+ checks: results
38
+ };
39
+ }
40
+
41
+ async checkAdapterAvailability() {
42
+ // In a real implementation, this would check actual adapter availability
43
+ return {
44
+ healthy: true,
45
+ unavailableAdapters: []
46
+ };
47
+ }
48
+
49
+ async checkSystemResources() {
50
+ const memUsage = process.memoryUsage();
51
+ const totalMem = os.totalmem();
52
+ const freeMem = os.freemem();
53
+ const usedMemPercent = ((totalMem - freeMem) / totalMem) * 100;
54
+
55
+ return {
56
+ healthy: usedMemPercent < 90, // Healthy if less than 90% memory used
57
+ memory: {
58
+ used: totalMem - freeMem,
59
+ free: freeMem,
60
+ total: totalMem,
61
+ percent: usedMemPercent
62
+ },
63
+ cpu: os.cpus().length
64
+ };
65
+ }
66
+
67
+ async checkDiskSpace() {
68
+ // Node.js doesn't have built-in disk space checking
69
+ // This is a simplified check
70
+ return {
71
+ healthy: true,
72
+ message: 'Disk space check not implemented in Node.js layer'
73
+ };
74
+ }
75
+ }
76
+
77
+ module.exports = HealthChecker;
@@ -0,0 +1,256 @@
1
+ // src/core/coordination/nodejs/HookDeploymentManager.js
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+ const { spawn, spawnSync } = require('child_process');
6
+
7
+ class HookDeploymentManager {
8
+ constructor() {
9
+ this.deploymentDir = path.join(os.homedir(), '.stigmergy', 'hooks');
10
+ this.supportedCLIs = [
11
+ 'claude', 'gemini', 'qwencode', 'iflow', 'qoder', 'codebuddy', 'codex', 'copilot'
12
+ ];
13
+ }
14
+
15
+ async initialize() {
16
+ console.log('[HOOK_DEPLOYMENT] Initializing hook deployment manager...');
17
+ await this.ensureDeploymentDirectory();
18
+ }
19
+
20
+ async ensureDeploymentDirectory() {
21
+ if (!fs.existsSync(this.deploymentDir)) {
22
+ fs.mkdirSync(this.deploymentDir, { recursive: true });
23
+ console.log(`[HOOK_DEPLOYMENT] Created deployment directory: ${this.deploymentDir}`);
24
+ }
25
+ }
26
+
27
+ async deployHooksForCLI(cliName, options = {}) {
28
+ console.log(`[HOOK_DEPLOYMENT] Deploying hooks for ${cliName}...`);
29
+
30
+ if (!this.supportedCLIs.includes(cliName.toLowerCase())) {
31
+ throw new Error(`Unsupported CLI: ${cliName}`);
32
+ }
33
+
34
+ try {
35
+ // Create CLI-specific hook directory
36
+ const cliHookDir = path.join(this.deploymentDir, cliName);
37
+ if (!fs.existsSync(cliHookDir)) {
38
+ fs.mkdirSync(cliHookDir, { recursive: true });
39
+ }
40
+
41
+ // Deploy Node.js specific hooks
42
+ await this.deployNodeJsHooks(cliName, cliHookDir, options);
43
+
44
+ console.log(`[HOOK_DEPLOYMENT] Hooks deployed successfully for ${cliName}`);
45
+ return true;
46
+ } catch (error) {
47
+ console.error(`[HOOK_DEPLOYMENT] Failed to deploy hooks for ${cliName}:`, error);
48
+ return false;
49
+ }
50
+ }
51
+
52
+ async deployNodeJsHooks(cliName, hookDir, options) {
53
+ console.log(`[HOOK_DEPLOYMENT] Deploying Node.js hooks for ${cliName}...`);
54
+
55
+ // Create a basic hook template for Node.js
56
+ const hookTemplate = this.generateNodeJsHookTemplate(cliName);
57
+ const hookFilePath = path.join(hookDir, `${cliName}_nodejs_hook.js`);
58
+
59
+ fs.writeFileSync(hookFilePath, hookTemplate);
60
+ console.log(`[HOOK_DEPLOYMENT] Created Node.js hook: ${hookFilePath}`);
61
+
62
+ // Make the hook executable
63
+ try {
64
+ fs.chmodSync(hookFilePath, 0o755);
65
+ console.log(`[HOOK_DEPLOYMENT] Made hook executable: ${hookFilePath}`);
66
+ } catch (error) {
67
+ console.warn(`[HOOK_DEPLOYMENT] Failed to make hook executable: ${error.message}`);
68
+ }
69
+
70
+ // Create configuration file
71
+ const config = {
72
+ cli: cliName,
73
+ hookPath: hookFilePath,
74
+ deploymentTime: new Date().toISOString(),
75
+ version: '1.0.0-nodejs'
76
+ };
77
+
78
+ const configPath = path.join(hookDir, 'config.json');
79
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
80
+ console.log(`[HOOK_DEPLOYMENT] Created hook configuration: ${configPath}`);
81
+ }
82
+
83
+ generateNodeJsHookTemplate(cliName) {
84
+ return `#!/usr/bin/env node
85
+
86
+ /**
87
+ * Node.js Hook for ${cliName.toUpperCase()}
88
+ * Auto-generated by Stigmergy CLI Hook Deployment Manager
89
+ */
90
+
91
+ const fs = require('fs');
92
+ const path = require('path');
93
+
94
+ class ${this.capitalize(cliName)}NodeJsHook {
95
+ constructor() {
96
+ this.cliName = '${cliName}';
97
+ this.hookDir = __dirname;
98
+ this.logFile = path.join(this.hookDir, '${cliName}_hook.log');
99
+ }
100
+
101
+ async onUserPrompt(prompt, context) {
102
+ this.log('INFO', \`User prompt received: \${prompt}\`);
103
+
104
+ // Check for cross-CLI requests
105
+ const crossCLIRequest = this.detectCrossCLIRequest(prompt);
106
+ if (crossCLIRequest) {
107
+ return await this.handleCrossCLIRequest(crossCLIRequest, context);
108
+ }
109
+
110
+ // Default processing
111
+ return null;
112
+ }
113
+
114
+ async onToolUse(toolName, toolArgs, context) {
115
+ this.log('INFO', \`Tool use detected: \${toolName}\`);
116
+ return null;
117
+ }
118
+
119
+ async onResponseGenerated(response, context) {
120
+ this.log('INFO', 'Response generated');
121
+ return null;
122
+ }
123
+
124
+ detectCrossCLIRequest(prompt) {
125
+ // Simple pattern matching for cross-CLI requests
126
+ const patterns = [
127
+ /(?:use|call|ask)\\s+(\\w+)\\s+(?:to|for)\\s+(.+)$/i,
128
+ /(?:use|call|ask)\\s+(\\w+)\\s+(?:to|for)\\s+(.+)$/i // English-only pattern
129
+ ];
130
+
131
+ for (const pattern of patterns) {
132
+ const match = prompt.match(pattern);
133
+ if (match) {
134
+ return {
135
+ targetCLI: match[1].toLowerCase(),
136
+ task: match[2] || match[3],
137
+ source: this.cliName
138
+ };
139
+ }
140
+ }
141
+
142
+ return null;
143
+ }
144
+
145
+ async handleCrossCLIRequest(request, context) {
146
+ this.log('INFO', \`Cross-CLI request detected: \${JSON.stringify(request)}\`);
147
+
148
+ // In a real implementation, this would communicate with the coordination layer
149
+ // For now, we simulate the response
150
+ return \`[NODE.JS HOOK] Simulated cross-CLI call to \${request.targetCLI}: \${request.task}\`;
151
+ }
152
+
153
+ log(level, message) {
154
+ const timestamp = new Date().toISOString();
155
+ const logEntry = \`[\${timestamp}] [\${level}] [\${this.cliName.toUpperCase()}] \${message}\\n\`;
156
+
157
+ try {
158
+ fs.appendFileSync(this.logFile, logEntry);
159
+ } catch (error) {
160
+ console.error('Failed to write to log file:', error);
161
+ }
162
+ }
163
+
164
+ capitalize(str) {
165
+ return str.charAt(0).toUpperCase() + str.slice(1);
166
+ }
167
+ }
168
+
169
+ // Export the hook class
170
+ module.exports = ${this.capitalize(cliName)}NodeJsHook;
171
+
172
+ // If run directly, instantiate and test
173
+ if (require.main === module) {
174
+ const hook = new ${this.capitalize(cliName)}NodeJsHook();
175
+ console.log('${cliName.toUpperCase()} Node.js Hook initialized');
176
+ }
177
+ `;
178
+ }
179
+
180
+ capitalize(str) {
181
+ return str.charAt(0).toUpperCase() + str.slice(1);
182
+ }
183
+
184
+ async undeployHooksForCLI(cliName) {
185
+ console.log(`[HOOK_DEPLOYMENT] Undeploying hooks for ${cliName}...`);
186
+
187
+ const cliHookDir = path.join(this.deploymentDir, cliName);
188
+ if (fs.existsSync(cliHookDir)) {
189
+ try {
190
+ fs.rmSync(cliHookDir, { recursive: true, force: true });
191
+ console.log(`[HOOK_DEPLOYMENT] Removed hook directory: ${cliHookDir}`);
192
+ return true;
193
+ } catch (error) {
194
+ console.error(`[HOOK_DEPLOYMENT] Failed to remove hook directory:`, error);
195
+ return false;
196
+ }
197
+ }
198
+
199
+ console.log(`[HOOK_DEPLOYMENT] No hooks found for ${cliName}`);
200
+ return true;
201
+ }
202
+
203
+ async listDeployedHooks() {
204
+ if (!fs.existsSync(this.deploymentDir)) {
205
+ return [];
206
+ }
207
+
208
+ const cliDirs = fs.readdirSync(this.deploymentDir, { withFileTypes: true })
209
+ .filter(dirent => dirent.isDirectory())
210
+ .map(dirent => dirent.name);
211
+
212
+ const hooks = [];
213
+ for (const cliName of cliDirs) {
214
+ const configPath = path.join(this.deploymentDir, cliName, 'config.json');
215
+ if (fs.existsSync(configPath)) {
216
+ try {
217
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
218
+ hooks.push(config);
219
+ } catch (error) {
220
+ console.warn(`[HOOK_DEPLOYMENT] Failed to read config for ${cliName}:`, error.message);
221
+ }
222
+ }
223
+ }
224
+
225
+ return hooks;
226
+ }
227
+
228
+ async validateHookDeployment(cliName) {
229
+ console.log(`[HOOK_DEPLOYMENT] Validating hook deployment for ${cliName}...`);
230
+
231
+ const cliHookDir = path.join(this.deploymentDir, cliName);
232
+ if (!fs.existsSync(cliHookDir)) {
233
+ return { valid: false, error: 'Hook directory not found' };
234
+ }
235
+
236
+ const configPath = path.join(cliHookDir, 'config.json');
237
+ if (!fs.existsSync(configPath)) {
238
+ return { valid: false, error: 'Configuration file not found' };
239
+ }
240
+
241
+ const hookPath = path.join(cliHookDir, `${cliName}_nodejs_hook.js`);
242
+ if (!fs.existsSync(hookPath)) {
243
+ return { valid: false, error: 'Hook script not found' };
244
+ }
245
+
246
+ // Try to load the hook
247
+ try {
248
+ require(hookPath);
249
+ return { valid: true, message: 'Hook deployment is valid' };
250
+ } catch (error) {
251
+ return { valid: false, error: `Failed to load hook: ${error.message}` };
252
+ }
253
+ }
254
+ }
255
+
256
+ module.exports = HookDeploymentManager;
@@ -0,0 +1,71 @@
1
+ // src/core/coordination/nodejs/StatisticsCollector.js
2
+ class StatisticsCollector {
3
+ constructor() {
4
+ this.counters = {};
5
+ this.timings = {};
6
+ this.startTime = Date.now();
7
+ }
8
+
9
+ initialize() {
10
+ console.log('[STATISTICS_COLLECTOR] Initializing statistics collector...');
11
+ this.reset();
12
+ }
13
+
14
+ reset() {
15
+ this.counters = {
16
+ cross_cli_calls: 0,
17
+ successful_calls: 0,
18
+ failed_calls: 0,
19
+ adapter_loads: 0
20
+ };
21
+ this.timings = {
22
+ execution_times: [],
23
+ last_reset: Date.now()
24
+ };
25
+ }
26
+
27
+ incrementCounter(name) {
28
+ this.counters[name] = (this.counters[name] || 0) + 1;
29
+ }
30
+
31
+ recordExecutionTime(timeMs) {
32
+ this.timings.execution_times.push(timeMs);
33
+ // Keep only last 1000 timings to prevent memory bloat
34
+ if (this.timings.execution_times.length > 1000) {
35
+ this.timings.execution_times.shift();
36
+ }
37
+ }
38
+
39
+ getAdapterStats(cliName) {
40
+ return {
41
+ calls: this.counters.cross_cli_calls,
42
+ successRate: this.calculateSuccessRate(),
43
+ averageExecutionTime: this.calculateAverageExecutionTime(),
44
+ uptime: Date.now() - this.startTime
45
+ };
46
+ }
47
+
48
+ getAllStats() {
49
+ return {
50
+ counters: this.counters,
51
+ timings: {
52
+ ...this.timings,
53
+ averageExecutionTime: this.calculateAverageExecutionTime()
54
+ },
55
+ uptime: Date.now() - this.startTime
56
+ };
57
+ }
58
+
59
+ calculateSuccessRate() {
60
+ if (this.counters.cross_cli_calls === 0) return 1.0;
61
+ return this.counters.successful_calls / this.counters.cross_cli_calls;
62
+ }
63
+
64
+ calculateAverageExecutionTime() {
65
+ if (this.timings.execution_times.length === 0) return 0;
66
+ const sum = this.timings.execution_times.reduce((a, b) => a + b, 0);
67
+ return sum / this.timings.execution_times.length;
68
+ }
69
+ }
70
+
71
+ module.exports = StatisticsCollector;
@@ -0,0 +1,72 @@
1
+ // src/core/coordination/nodejs/index.js
2
+ const AdapterManager = require('./AdapterManager');
3
+ const CLCommunication = require('./CLCommunication');
4
+ const StatisticsCollector = require('./StatisticsCollector');
5
+ const HealthChecker = require('./HealthChecker');
6
+
7
+ class NodeJsCoordinationLayer {
8
+ constructor() {
9
+ this.adapterManager = new AdapterManager();
10
+ this.communication = new CLCommunication();
11
+ this.statistics = new StatisticsCollector();
12
+ this.healthChecker = new HealthChecker();
13
+ }
14
+
15
+ async initialize(options = {}) {
16
+ try {
17
+ console.log('[NODEJS_COORDINATION] Initializing Node.js coordination layer...');
18
+
19
+ // Initialize components
20
+ await this.adapterManager.initialize();
21
+ await this.communication.initialize();
22
+ this.statistics.initialize();
23
+
24
+ // Perform health check
25
+ const health = await this.healthChecker.checkHealth();
26
+ if (!health.healthy) {
27
+ console.warn('[NODEJS_COORDINATION] Health check issues detected:', health);
28
+ }
29
+
30
+ console.log('[NODEJS_COORDINATION] Node.js coordination layer initialized successfully');
31
+ return true;
32
+ } catch (error) {
33
+ console.error('[NODEJS_COORDINATION] Failed to initialize Node.js coordination layer:', error);
34
+ return false;
35
+ }
36
+ }
37
+
38
+ async executeCrossCLITask(sourceCLI, targetCLI, task, context = {}) {
39
+ this.statistics.incrementCounter('cross_cli_calls');
40
+ const startTime = Date.now();
41
+
42
+ try {
43
+ const result = await this.communication.executeTask(sourceCLI, targetCLI, task, context);
44
+ this.statistics.recordExecutionTime(Date.now() - startTime);
45
+ this.statistics.incrementCounter('successful_calls');
46
+ return result;
47
+ } catch (error) {
48
+ this.statistics.incrementCounter('failed_calls');
49
+ console.error(`[NODEJS_COORDINATION] Cross-CLI task execution failed:`, error);
50
+ throw error;
51
+ }
52
+ }
53
+
54
+ async getAdapterStatistics(cliName) {
55
+ return this.statistics.getAdapterStats(cliName);
56
+ }
57
+
58
+ async getSystemStatus() {
59
+ return {
60
+ implementation: 'nodejs',
61
+ health: await this.healthChecker.checkHealth(),
62
+ statistics: this.statistics.getAllStats(),
63
+ adapters: await this.adapterManager.listAdapters()
64
+ };
65
+ }
66
+
67
+ async healthCheck() {
68
+ return await this.healthChecker.checkHealth();
69
+ }
70
+ }
71
+
72
+ module.exports = NodeJsCoordinationLayer;