snow-flow 8.37.26 โ†’ 8.38.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.
Files changed (41) hide show
  1. package/.snow-code/agent/deployment-specialist.md +346 -0
  2. package/.snow-code/agent/orchestrator.md +286 -0
  3. package/.snow-code/agent/risk-assessor.md +454 -0
  4. package/.snow-code/agent/solution-architect.md +582 -0
  5. package/.snow-code/agent/validator.md +503 -0
  6. package/.snow-code/opencode.json +49 -0
  7. package/README.md +141 -904
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +93 -256
  10. package/dist/cli.js.map +1 -1
  11. package/dist/utils/sync-mcp-configs.d.ts +7 -5
  12. package/dist/utils/sync-mcp-configs.d.ts.map +1 -1
  13. package/dist/utils/sync-mcp-configs.js +19 -74
  14. package/dist/utils/sync-mcp-configs.js.map +1 -1
  15. package/package.json +2 -3
  16. package/scripts/check-binary-updates.js +0 -169
  17. package/scripts/check-npm-version.js +0 -92
  18. package/scripts/classify-all-tools.ts +0 -446
  19. package/scripts/classify-edge-cases.ts +0 -275
  20. package/scripts/classify-operations-tools.sh +0 -96
  21. package/scripts/cleanup-mcp-servers.js +0 -115
  22. package/scripts/diagnose-mcp.js +0 -299
  23. package/scripts/generate-mcp-config.js +0 -45
  24. package/scripts/mcp-server-manager.sh +0 -320
  25. package/scripts/postinstall.js +0 -75
  26. package/scripts/reset-mcp-servers.js +0 -266
  27. package/scripts/safe-mcp-cleanup.js +0 -151
  28. package/scripts/setup-mcp.js +0 -106
  29. package/scripts/start-mcp-proper.js +0 -76
  30. package/scripts/start-snowcode.sh +0 -123
  31. package/scripts/start-sysprops-mcp.js +0 -43
  32. package/scripts/sync-snow-code-version.js +0 -74
  33. package/scripts/test-auth-flow.js +0 -172
  34. package/scripts/test-auth-location-fix.js +0 -84
  35. package/scripts/test-mcp-manual.js +0 -140
  36. package/scripts/test-todowrite-timeout.js +0 -108
  37. package/scripts/update-dependencies.js +0 -90
  38. package/scripts/update-mcp-config.js +0 -96
  39. package/scripts/update-snow-code.js +0 -146
  40. package/scripts/verify-snowcode-fork.sh +0 -141
  41. package/templates/snow-code-package.json +0 -3
@@ -1,275 +0,0 @@
1
- #!/usr/bin/env tsx
2
-
3
- /**
4
- * Second Pass: Classify Edge Case Tools
5
- *
6
- * Manually classify the 120 tools that couldn't be auto-classified
7
- * based on logical categories and functionality.
8
- */
9
-
10
- import * as fs from 'fs';
11
- import * as path from 'path';
12
-
13
- const TOOLS_BASE_DIR = path.join(__dirname, '../src/mcp/servicenow-mcp-unified/tools');
14
- const DRY_RUN = process.argv.includes('--dry-run');
15
-
16
- // Manual classification of edge cases
17
- const EDGE_CASE_CLASSIFICATIONS: Record<string, { permission: 'read' | 'write'; reason: string }> = {
18
- // Utility functions - READ (pure functions, no ServiceNow modifications)
19
- 'snow_timestamp': { permission: 'read', reason: 'Utility function - generates timestamp locally' },
20
- 'snow_sleep': { permission: 'read', reason: 'Utility function - delays execution but no data modification' },
21
- 'snow_sanitize_input': { permission: 'read', reason: 'Utility function - sanitizes data locally' },
22
- 'snow_random_string': { permission: 'read', reason: 'Utility function - generates random string locally' },
23
- 'snow_merge_objects': { permission: 'read', reason: 'Utility function - merges objects locally' },
24
- 'snow_generate_guid': { permission: 'read', reason: 'Utility function - generates GUID locally' },
25
- 'snow_format_date': { permission: 'read', reason: 'Utility function - formats date locally' },
26
- 'snow_encode_query': { permission: 'read', reason: 'Utility function - encodes query string locally' },
27
- 'snow_decode_query': { permission: 'read', reason: 'Utility function - decodes query string locally' },
28
- 'snow_parse_json': { permission: 'read', reason: 'Utility function - parses JSON locally' },
29
- 'snow_parse_xml': { permission: 'read', reason: 'Utility function - parses XML locally' },
30
- 'snow_hash_string': { permission: 'read', reason: 'Utility function - hashes string locally' },
31
- 'snow_base64_encode': { permission: 'read', reason: 'Utility function - encodes base64 locally' },
32
- 'snow_base64_decode': { permission: 'read', reason: 'Utility function - decodes base64 locally' },
33
-
34
- // Validation/Testing/Preview - READ (only validate, don't modify)
35
- 'snow_widget_test': { permission: 'read', reason: 'Testing function - validates widget without modifying' },
36
- 'snow_preview_widget': { permission: 'read', reason: 'Preview function - renders widget without saving' },
37
- 'snow_debug_widget_fetch': { permission: 'read', reason: 'Debug function - fetches widget data for debugging' },
38
-
39
- // Discovery/Inspection - READ
40
- 'snow_uib_discover': { permission: 'read', reason: 'Discovery function - reads UI Builder configuration' },
41
-
42
- // Security Assessment/Scanning - READ (analyze but don't modify)
43
- 'snow_vulnerability_risk_assessment': { permission: 'read', reason: 'Assessment function - analyzes vulnerabilities without modifying' },
44
- 'snow_security_risk_assessment': { permission: 'read', reason: 'Assessment function - analyzes security risks without modifying' },
45
- 'snow_security_dashboard': { permission: 'read', reason: 'Dashboard function - displays security metrics without modifying' },
46
- 'snow_scan_vulnerabilities': { permission: 'read', reason: 'Scan function - scans for vulnerabilities without modifying' },
47
- 'snow_run_compliance_scan': { permission: 'read', reason: 'Scan function - scans compliance without modifying' },
48
-
49
- // Data transformation - READ (transforms data in-memory, doesn't modify ServiceNow)
50
- 'snow_transform_data': { permission: 'read', reason: 'Transformation function - transforms data locally without ServiceNow modification' },
51
-
52
- // Virtual Agent - WRITE (sends messages, modifies state)
53
- 'snow_train_va_nlu': { permission: 'write', reason: 'Training function - modifies NLU model in ServiceNow' },
54
- 'snow_send_va_message': { permission: 'write', reason: 'Message function - sends messages and modifies conversation state' },
55
- 'snow_handoff_to_agent': { permission: 'write', reason: 'Handoff function - modifies conversation assignment' },
56
-
57
- // Update Sets - WRITE (modifies update set state)
58
- 'snow_ensure_active_update_set': { permission: 'write', reason: 'Update set function - creates or switches active update set' },
59
-
60
- // Property Management - WRITE (bulk operations modify properties)
61
- 'snow_property_io': { permission: 'write', reason: 'Property I/O - imports properties which modifies ServiceNow' },
62
- 'snow_property_bulk': { permission: 'write', reason: 'Bulk operation - modifies multiple properties' },
63
-
64
- // Security Actions - WRITE (modify permissions, automate responses)
65
- 'snow_escalate_permissions': { permission: 'write', reason: 'Permission escalation - modifies user permissions' },
66
- 'snow_automate_threat_response': { permission: 'write', reason: 'Automation - executes automated threat response actions' },
67
-
68
- // Reporting/KPI - WRITE (defines/creates KPIs)
69
- 'snow_define_kpi': { permission: 'write', reason: 'Definition function - creates KPI definition in ServiceNow' },
70
-
71
- // Predictive Intelligence - WRITE (trains models)
72
- 'snow_train_pi_solution': { permission: 'write', reason: 'Training function - trains predictive intelligence model' },
73
-
74
- // Plugins - WRITE (custom plugins likely modify state)
75
- 'snow_custom_plugin': { permission: 'write', reason: 'Plugin function - executes custom plugin which can modify data' },
76
-
77
- // Record management with actions - WRITE
78
- 'snow_record_manage': { permission: 'write', reason: 'Management function - creates/updates/deletes records based on action' },
79
- 'snow_catalog_item_manager': { permission: 'write', reason: 'Management function - manages catalog items' },
80
- 'snow_property_manager': { permission: 'write', reason: 'Management function - manages properties' },
81
-
82
- // Operations that can be both read and write - classify as WRITE (most restrictive)
83
- 'snow_assign_task': { permission: 'write', reason: 'Assignment function - modifies task assignment' },
84
- 'snow_auto_resolve_incident': { permission: 'write', reason: 'Resolution function - closes incidents automatically' },
85
- 'snow_manage_group_membership': { permission: 'write', reason: 'Management function - modifies group memberships' },
86
- 'snow_cleanup_test_artifacts': { permission: 'write', reason: 'Cleanup function - deletes test artifacts' },
87
-
88
- // Workflow/Process - WRITE
89
- 'snow_execute_workflow': { permission: 'write', reason: 'Execution function - triggers workflow execution' },
90
-
91
- // CI/Asset operations - WRITE
92
- 'snow_reconcile_ci': { permission: 'write', reason: 'Reconciliation function - updates CI records' },
93
- 'snow_track_asset_lifecycle': { permission: 'write', reason: 'Tracking function - updates asset lifecycle state' },
94
- 'snow_optimize_licenses': { permission: 'write', reason: 'Optimization function - modifies license allocations' },
95
- 'snow_asset_discovery': { permission: 'write', reason: 'Discovery function - creates/updates asset records' },
96
-
97
- // Advanced analysis with ML predictions - READ (predictions don't modify source data)
98
- 'snow_ml_predict': { permission: 'read', reason: 'Prediction function - generates predictions without modifying data' },
99
- 'snow_ai_classify': { permission: 'read', reason: 'Classification function - classifies data without modifying' },
100
- 'snow_anomaly_detection': { permission: 'read', reason: 'Detection function - detects anomalies without modifying' },
101
- 'snow_duplicate_detection': { permission: 'read', reason: 'Detection function - finds duplicates without modifying' },
102
- 'snow_fuzzy_search': { permission: 'read', reason: 'Search function - performs fuzzy search without modifying' },
103
- 'snow_autocomplete': { permission: 'read', reason: 'Autocomplete function - suggests completions without modifying' },
104
- 'snow_recommendation_engine': { permission: 'read', reason: 'Recommendation function - generates recommendations without modifying' },
105
- 'snow_sentiment_analysis': { permission: 'read', reason: 'Analysis function - analyzes sentiment without modifying' },
106
-
107
- // Aggregation/Metrics - READ
108
- 'snow_aggregate_metrics': { permission: 'read', reason: 'Aggregation function - aggregates metrics without modifying' },
109
-
110
- // Pattern/Predictive analysis - READ
111
- 'snow_pattern_analysis': { permission: 'read', reason: 'Analysis function - analyzes patterns without modifying' },
112
- 'snow_predictive_analysis': { permission: 'read', reason: 'Analysis function - performs predictive analysis without modifying' },
113
-
114
- // Data quality/optimization analysis - READ
115
- 'snow_analyze_data_quality': { permission: 'read', reason: 'Analysis function - analyzes data quality without modifying' },
116
- 'snow_optimize_queries': { permission: 'read', reason: 'Analysis function - suggests query optimizations without modifying' },
117
-
118
- // CI operations that are primarily read
119
- 'snow_ci_health_check': { permission: 'read', reason: 'Health check - validates CI health without modifying' },
120
- 'snow_get_ci_details': { permission: 'read', reason: 'Get function - retrieves CI details' },
121
- 'snow_get_ci_history': { permission: 'read', reason: 'Get function - retrieves CI history' },
122
- 'snow_get_ci_impact': { permission: 'read', reason: 'Get function - analyzes CI impact' },
123
- 'snow_get_ci_relationships': { permission: 'read', reason: 'Get function - retrieves CI relationships' },
124
- 'snow_get_event_correlation': { permission: 'read', reason: 'Get function - retrieves event correlations' },
125
- 'snow_impact_analysis': { permission: 'read', reason: 'Analysis function - analyzes impact without modifying' },
126
-
127
- // Change operations - READ for query, WRITE for manage
128
- 'snow_change_query': { permission: 'read', reason: 'Query function - retrieves change records' },
129
-
130
- // Calendar/Schedule - READ (gets calendar info)
131
- 'snow_calendar': { permission: 'read', reason: 'Calendar function - retrieves calendar information' },
132
-
133
- // SLA calculations - READ
134
- 'snow_calculate_sla_duration': { permission: 'read', reason: 'Calculation function - calculates SLA duration locally' },
135
-
136
- // Connectors/Batch - depends on action, classify as WRITE (can modify)
137
- 'snow_batch_request': { permission: 'write', reason: 'Batch function - can execute multiple operations including writes' },
138
-
139
- // Operations analysis - READ
140
- 'snow_analyze_incident': { permission: 'read', reason: 'Analysis function - analyzes incident without modifying' },
141
- 'snow_operational_metrics': { permission: 'read', reason: 'Metrics function - retrieves operational metrics' },
142
-
143
- // User operations - depends, but lookup is READ
144
- 'snow_user_lookup': { permission: 'read', reason: 'Lookup function - retrieves user information' },
145
-
146
- // Catalog search - READ
147
- 'snow_catalog_item_search': { permission: 'read', reason: 'Search function - searches catalog items' },
148
- 'snow_comprehensive_search': { permission: 'read', reason: 'Search function - performs comprehensive search' },
149
-
150
- // Incident operations
151
- 'snow_update_incident': { permission: 'write', reason: 'Update function - modifies incident records' },
152
-
153
- // Asset reports/compliance - READ
154
- 'snow_asset_compliance_report': { permission: 'read', reason: 'Report function - generates compliance report' },
155
-
156
- // Test/ATF operations - discovery is READ, execution is WRITE
157
- 'snow_discover_atf_tests': { permission: 'read', reason: 'Discovery function - lists ATF tests' },
158
- 'snow_get_atf_results': { permission: 'read', reason: 'Get function - retrieves test results' },
159
-
160
- // Attachments operations
161
- 'snow_get_attachments': { permission: 'read', reason: 'Get function - retrieves attachments' },
162
-
163
- // Automation operations - discovery is READ, execution is WRITE
164
- 'snow_discover_automation_jobs': { permission: 'read', reason: 'Discovery function - lists automation jobs' },
165
- 'snow_discover_events': { permission: 'read', reason: 'Discovery function - lists events' },
166
- 'snow_discover_schedules': { permission: 'read', reason: 'Discovery function - lists schedules' },
167
- 'snow_get_logs': { permission: 'read', reason: 'Get function - retrieves system logs' },
168
- 'snow_get_script_output': { permission: 'read', reason: 'Get function - retrieves script execution output' },
169
-
170
- // Catalog operations
171
- 'snow_discover_catalogs': { permission: 'read', reason: 'Discovery function - lists catalogs' },
172
- 'snow_get_catalog_item_details': { permission: 'read', reason: 'Get function - retrieves catalog item details' },
173
-
174
- // Approvals - get pending is READ
175
- 'snow_get_pending_approvals': { permission: 'read', reason: 'Get function - retrieves pending approvals' },
176
- };
177
-
178
- function addPermissionFields(filePath: string, permission: 'read' | 'write', reason: string): boolean {
179
- try {
180
- let content = fs.readFileSync(filePath, 'utf-8');
181
-
182
- // Check if already classified
183
- if (content.includes('permission:') && content.includes('allowedRoles:')) {
184
- return false;
185
- }
186
-
187
- // Find insertion point
188
- const frequencyMatch = content.match(/frequency:\s*['"][\w-]+['"],?/);
189
- if (!frequencyMatch) {
190
- console.error(` โš ๏ธ Could not find frequency field in ${path.basename(filePath)}`);
191
- return false;
192
- }
193
-
194
- const roles = permission === 'read'
195
- ? "['developer', 'stakeholder', 'admin']"
196
- : "['developer', 'admin']";
197
-
198
- const permissionBlock = `\n\n // ๐Ÿ†• Permission enforcement (Q1 2025)\n` +
199
- ` // Classification: ${permission.toUpperCase()} - ${reason}\n` +
200
- ` permission: '${permission}',\n` +
201
- ` allowedRoles: ${roles},`;
202
-
203
- const insertIndex = frequencyMatch.index! + frequencyMatch[0].length;
204
- content = content.slice(0, insertIndex) + permissionBlock + content.slice(insertIndex);
205
-
206
- if (!DRY_RUN) {
207
- fs.writeFileSync(filePath, content, 'utf-8');
208
- }
209
-
210
- return true;
211
- } catch (error) {
212
- console.error(` โŒ Error updating ${path.basename(filePath)}:`, error);
213
- return false;
214
- }
215
- }
216
-
217
- async function classifyEdgeCases(): Promise<void> {
218
- console.log('๐Ÿ”ง Classifying Edge Case Tools (Second Pass)...\n');
219
-
220
- let updated = 0;
221
- let alreadyClassified = 0;
222
- let notFound = 0;
223
-
224
- for (const [toolName, classification] of Object.entries(EDGE_CASE_CLASSIFICATIONS)) {
225
- // Find the tool file
226
- const possiblePath = path.join(TOOLS_BASE_DIR, `**/${toolName}.ts`);
227
-
228
- // Simple glob implementation - search in all subdirectories
229
- let filePath: string | null = null;
230
- const searchDir = (dir: string) => {
231
- const entries = fs.readdirSync(dir, { withFileTypes: true });
232
- for (const entry of entries) {
233
- const fullPath = path.join(dir, entry.name);
234
- if (entry.isDirectory()) {
235
- searchDir(fullPath);
236
- } else if (entry.isFile() && entry.name === `${toolName}.ts`) {
237
- filePath = fullPath;
238
- }
239
- }
240
- };
241
-
242
- searchDir(TOOLS_BASE_DIR);
243
-
244
- if (!filePath) {
245
- console.log(` โš ๏ธ ${toolName} - File not found`);
246
- notFound++;
247
- continue;
248
- }
249
-
250
- const success = addPermissionFields(filePath, classification.permission, classification.reason);
251
-
252
- if (success) {
253
- updated++;
254
- console.log(` โœ… ${toolName} โ†’ ${classification.permission.toUpperCase()}`);
255
- } else {
256
- alreadyClassified++;
257
- console.log(` โ„น๏ธ ${toolName} - Already classified`);
258
- }
259
- }
260
-
261
- console.log(`\nโœ… Second pass complete!\n`);
262
- console.log(` โœ… Classified: ${updated}`);
263
- console.log(` โ„น๏ธ Already done: ${alreadyClassified}`);
264
- console.log(` โš ๏ธ Not found: ${notFound}`);
265
- console.log(`\n๐Ÿ“Š Total edge cases in dictionary: ${Object.keys(EDGE_CASE_CLASSIFICATIONS).length}\n`);
266
-
267
- if (DRY_RUN) {
268
- console.log('๐Ÿƒ DRY RUN MODE - No files were modified\n');
269
- }
270
- }
271
-
272
- classifyEdgeCases().catch(error => {
273
- console.error('โŒ Fatal error:', error);
274
- process.exit(1);
275
- });
@@ -1,96 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Script to add permission fields to operations tools
4
- # Phase 1.2: Classify Core Operations tools
5
-
6
- set -e
7
-
8
- TOOLS_DIR="/Users/nielsvanderwerf/snow-flow/src/mcp/servicenow-mcp-unified/tools/operations"
9
-
10
- echo "๐Ÿ”ง Classifying Core Operations tools..."
11
- echo ""
12
-
13
- # READ tools (query, get, discover, search, analyze, lookup, metrics)
14
- READ_TOOLS=(
15
- "snow_query_incidents"
16
- "snow_query_problems"
17
- "snow_query_requests"
18
- "snow_get_by_sysid"
19
- "snow_discover_table_fields"
20
- "snow_cmdb_search"
21
- "snow_comprehensive_search"
22
- "snow_catalog_item_search"
23
- "snow_user_lookup"
24
- "snow_operational_metrics"
25
- "snow_pattern_analysis"
26
- "snow_predictive_analysis"
27
- "snow_analyze_incident"
28
- )
29
-
30
- # WRITE tools (create, update, assign, attach, manage, cleanup, resolve)
31
- WRITE_TOOLS=(
32
- "snow_create_incident"
33
- "snow_create_user_group"
34
- "snow_update_incident"
35
- "snow_assign_task"
36
- "snow_attach_file"
37
- "snow_auto_resolve_incident"
38
- "snow_catalog_item_manager"
39
- "snow_manage_group_membership"
40
- "snow_record_manage"
41
- "snow_cleanup_test_artifacts"
42
- )
43
-
44
- echo "โœ… READ tools: ${#READ_TOOLS[@]}"
45
- echo "โŒ WRITE tools: ${#WRITE_TOOLS[@]}"
46
- echo ""
47
-
48
- # Function to add permission fields to tool file
49
- add_permissions() {
50
- local file="$1"
51
- local permission="$2"
52
- local roles="$3"
53
-
54
- if [ ! -f "$file" ]; then
55
- echo "โš ๏ธ File not found: $file"
56
- return
57
- fi
58
-
59
- # Check if already has permission field
60
- if grep -q "permission:" "$file"; then
61
- echo " โ„น๏ธ Already classified: $(basename $file)"
62
- return
63
- fi
64
-
65
- # Find the line with "frequency:" and add permission fields after it
66
- # Using perl for in-place editing with backup
67
- perl -i.bak -pe '
68
- if (/frequency:.*,?$/) {
69
- $_ .= "\n\n // ๐Ÿ†• Permission enforcement (Q1 2025)\n";
70
- $_ .= " // Classification: '"$permission"'\n";
71
- $_ .= " permission: '"$permission"',\n";
72
- $_ .= " allowedRoles: '"$roles"',\n";
73
- }
74
- ' "$file"
75
-
76
- echo " โœ… Classified: $(basename $file) โ†’ $permission"
77
- }
78
-
79
- echo "๐Ÿ“‹ Processing READ tools..."
80
- for tool in "${READ_TOOLS[@]}"; do
81
- file="$TOOLS_DIR/${tool}.ts"
82
- add_permissions "$file" "read" "['developer', 'stakeholder', 'admin']"
83
- done
84
-
85
- echo ""
86
- echo "๐Ÿ“‹ Processing WRITE tools..."
87
- for tool in "${WRITE_TOOLS[@]}"; do
88
- file="$TOOLS_DIR/${tool}.ts"
89
- add_permissions "$file" "write" "['developer', 'admin']"
90
- done
91
-
92
- echo ""
93
- echo "โœ… Done! Classified $(( ${#READ_TOOLS[@]} + ${#WRITE_TOOLS[@]} )) operations tools"
94
- echo ""
95
- echo "๐Ÿ“ To verify changes:"
96
- echo " git diff $TOOLS_DIR"
@@ -1,115 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * MCP Server Cleanup Script
5
- * Prevents duplicate MCP servers and memory exhaustion
6
- */
7
-
8
- const { exec } = require('child_process');
9
- const { promisify } = require('util');
10
- const execAsync = promisify(exec);
11
-
12
- async function cleanupMCPServers() {
13
- console.log('๐Ÿงน Cleaning up MCP servers...\n');
14
-
15
- try {
16
- // 1. Check for running MCP processes
17
- const { stdout: psOutput } = await execAsync('ps aux | grep -E "node.*mcp" | grep -v grep | wc -l');
18
- const processCount = parseInt(psOutput.trim());
19
-
20
- if (processCount > 0) {
21
- console.log(`โš ๏ธ Found ${processCount} running MCP processes`);
22
- console.log('๐Ÿ”ช Killing all MCP processes...');
23
-
24
- // Kill all MCP processes
25
- await execAsync('pkill -f "node.*mcp"').catch(() => {
26
- // Ignore errors if no processes found
27
- });
28
-
29
- // Wait for processes to terminate
30
- await new Promise(resolve => setTimeout(resolve, 2000));
31
-
32
- console.log('โœ… All MCP processes terminated\n');
33
- } else {
34
- console.log('โœ… No MCP processes running\n');
35
- }
36
-
37
- // 2. Clean up any stale lock files
38
- console.log('๐Ÿ”’ Cleaning up lock files...');
39
- await execAsync('rm -f /tmp/mcp-*.lock').catch(() => {});
40
- await execAsync('rm -f ~/.claude/mcp-*.lock').catch(() => {});
41
- await execAsync('rm -f ~/.claude/mcp-servers.lock').catch(() => {});
42
-
43
- // 3. Check memory usage
44
- const { stdout: memOutput } = await execAsync('ps aux | grep node | awk \'{sum+=$6} END {print sum/1024}\'');
45
- const nodeMemoryMB = parseFloat(memOutput.trim());
46
-
47
- console.log(`๐Ÿ“Š Node.js memory usage: ${nodeMemoryMB.toFixed(2)} MB\n`);
48
-
49
- if (nodeMemoryMB > 1000) {
50
- console.log('โš ๏ธ High memory usage detected!');
51
- console.log('๐Ÿ’ก Recommendation: Restart your terminal or run "killall node"\n');
52
- }
53
-
54
- // 4. Create singleton lock mechanism
55
- console.log('๐Ÿ” Setting up singleton lock mechanism...');
56
- const lockScript = `
57
- const fs = require('fs');
58
- const path = require('path');
59
-
60
- const lockFile = path.join(process.env.HOME, '.claude', 'mcp-singleton.lock');
61
- const pid = process.pid;
62
-
63
- // Check if lock exists
64
- if (fs.existsSync(lockFile)) {
65
- const existingPid = fs.readFileSync(lockFile, 'utf8');
66
- try {
67
- // Check if process is still running
68
- process.kill(existingPid, 0);
69
- console.error('MCP servers already running with PID:', existingPid);
70
- process.exit(1);
71
- } catch (e) {
72
- // Process not running, remove stale lock
73
- fs.unlinkSync(lockFile);
74
- }
75
- }
76
-
77
- // Create lock
78
- fs.mkdirSync(path.dirname(lockFile), { recursive: true });
79
- fs.writeFileSync(lockFile, pid.toString());
80
-
81
- // Clean up on exit
82
- process.on('exit', () => {
83
- try {
84
- fs.unlinkSync(lockFile);
85
- } catch (e) {}
86
- });
87
- `;
88
-
89
- // Save singleton script
90
- const fs = require('fs');
91
- const path = require('path');
92
- const singletonPath = path.join(__dirname, '..', 'dist', 'mcp', 'singleton-check.js');
93
- fs.writeFileSync(singletonPath, lockScript);
94
- console.log('โœ… Singleton mechanism created\n');
95
-
96
- // 5. Report status
97
- console.log('๐Ÿ“‹ Cleanup Summary:');
98
- console.log('โ”€'.repeat(40));
99
- console.log('โœ… All MCP processes terminated');
100
- console.log('โœ… Lock files cleaned');
101
- console.log('โœ… Singleton mechanism installed');
102
- console.log(`โœ… Memory usage: ${nodeMemoryMB.toFixed(2)} MB`);
103
- console.log('\n๐ŸŽฏ Next Steps:');
104
- console.log('1. Run "npm run build" to rebuild');
105
- console.log('2. Use "snow-flow mcp start" to start servers properly');
106
- console.log('3. Monitor with "snow-flow mcp status"');
107
-
108
- } catch (error) {
109
- console.error('โŒ Cleanup failed:', error.message);
110
- process.exit(1);
111
- }
112
- }
113
-
114
- // Run cleanup
115
- cleanupMCPServers().catch(console.error);