snow-flow 8.3.2 โ 8.4.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.
- package/OPENCODE-SETUP.md +312 -0
- package/OPENCODE-TROUBLESHOOTING.md +381 -0
- package/dist/agents/index.d.ts +2 -2
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -4
- package/dist/agents/index.js.map +1 -1
- package/dist/cli.js +208 -244
- package/dist/cli.js.map +1 -1
- package/dist/memory/session-memory.d.ts +80 -0
- package/dist/memory/session-memory.d.ts.map +1 -0
- package/dist/memory/session-memory.js +468 -0
- package/dist/memory/session-memory.js.map +1 -0
- package/dist/sdk/claude-agent-sdk-integration.d.ts +4 -1
- package/dist/sdk/claude-agent-sdk-integration.d.ts.map +1 -1
- package/dist/sdk/claude-agent-sdk-integration.js.map +1 -1
- package/dist/sdk/index.d.ts +2 -7
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +2 -7
- package/dist/sdk/index.js.map +1 -1
- package/dist/snow-flow-system.d.ts +3 -7
- package/dist/snow-flow-system.d.ts.map +1 -1
- package/dist/snow-flow-system.js +59 -40
- package/dist/snow-flow-system.js.map +1 -1
- package/dist/utils/mcp-output-formatter.d.ts +128 -0
- package/dist/utils/mcp-output-formatter.d.ts.map +1 -0
- package/dist/utils/mcp-output-formatter.js +442 -0
- package/dist/utils/mcp-output-formatter.js.map +1 -0
- package/dist/utils/opencode-output-interceptor.d.ts +40 -0
- package/dist/utils/opencode-output-interceptor.d.ts.map +1 -0
- package/dist/utils/opencode-output-interceptor.js +258 -0
- package/dist/utils/opencode-output-interceptor.js.map +1 -0
- package/package.json +4 -2
- package/scripts/bulk-optimize-tools.js +486 -0
- package/scripts/cleanup-mcp-servers.js +115 -0
- package/scripts/generate-mcp-config.js +45 -0
- package/scripts/mcp-server-manager.sh +320 -0
- package/scripts/optimize-mcp-tools.ts +410 -0
- package/scripts/reset-mcp-servers.js +266 -0
- package/scripts/safe-mcp-cleanup.js +151 -0
- package/scripts/setup-mcp.js +106 -0
- package/scripts/start-mcp-proper.js +76 -0
- package/scripts/start-opencode.sh +123 -0
- package/scripts/start-sysprops-mcp.js +43 -0
- package/scripts/test-todowrite-timeout.js +108 -0
- package/scripts/update-version.js +31 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Safe MCP Cleanup Script
|
|
5
|
+
* Manual cleanup for MCP servers without causing memory crashes
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
const readline = require('readline');
|
|
10
|
+
|
|
11
|
+
const rl = readline.createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function getProcesses() {
|
|
17
|
+
try {
|
|
18
|
+
const output = execSync('ps aux | grep -E "mcp|servicenow.*mcp" | grep -v grep', {
|
|
19
|
+
encoding: 'utf8'
|
|
20
|
+
}).trim();
|
|
21
|
+
|
|
22
|
+
if (!output) return [];
|
|
23
|
+
|
|
24
|
+
const lines = output.split('\n');
|
|
25
|
+
const processes = [];
|
|
26
|
+
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
const parts = line.split(/\s+/);
|
|
29
|
+
if (parts.length > 10) {
|
|
30
|
+
processes.push({
|
|
31
|
+
pid: parseInt(parts[1]),
|
|
32
|
+
memory: Math.round(parseInt(parts[5]) / 1024), // MB
|
|
33
|
+
name: parts.slice(10).join(' ').substring(0, 80)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return processes;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function main() {
|
|
45
|
+
console.log('๐งน Safe MCP Cleanup Utility\n');
|
|
46
|
+
console.log('โ ๏ธ WARNING: This will terminate MCP server processes');
|
|
47
|
+
console.log('Only use if experiencing memory issues or crashes\n');
|
|
48
|
+
|
|
49
|
+
const processes = getProcesses();
|
|
50
|
+
|
|
51
|
+
if (processes.length === 0) {
|
|
52
|
+
console.log('โ
No MCP processes found');
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log(`Found ${processes.length} MCP processes:\n`);
|
|
57
|
+
|
|
58
|
+
// Group by type
|
|
59
|
+
const groups = {};
|
|
60
|
+
let totalMemory = 0;
|
|
61
|
+
|
|
62
|
+
for (const proc of processes) {
|
|
63
|
+
const match = proc.name.match(/servicenow-([^-]+)-mcp/);
|
|
64
|
+
const type = match ? match[1] : 'other';
|
|
65
|
+
|
|
66
|
+
if (!groups[type]) {
|
|
67
|
+
groups[type] = [];
|
|
68
|
+
}
|
|
69
|
+
groups[type].push(proc);
|
|
70
|
+
totalMemory += proc.memory;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Display summary
|
|
74
|
+
for (const [type, procs] of Object.entries(groups)) {
|
|
75
|
+
const memSum = procs.reduce((sum, p) => sum + p.memory, 0);
|
|
76
|
+
console.log(` ${type}: ${procs.length} process(es), ${memSum}MB`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`\nTotal memory usage: ${totalMemory}MB`);
|
|
80
|
+
|
|
81
|
+
// Ask for confirmation
|
|
82
|
+
const answer = await new Promise(resolve => {
|
|
83
|
+
rl.question('\nOptions:\n1. Kill ALL MCP processes\n2. Kill duplicates only (keep 1 of each type)\n3. Kill high memory processes (>100MB)\n4. Cancel\n\nChoice (1-4): ', resolve);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
switch (answer.trim()) {
|
|
87
|
+
case '1':
|
|
88
|
+
console.log('\n๐ด Killing ALL MCP processes...');
|
|
89
|
+
for (const proc of processes) {
|
|
90
|
+
try {
|
|
91
|
+
process.kill(proc.pid, 'SIGTERM');
|
|
92
|
+
console.log(` Killed PID ${proc.pid}`);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
// Already dead
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
console.log('โ
All MCP processes terminated');
|
|
98
|
+
break;
|
|
99
|
+
|
|
100
|
+
case '2':
|
|
101
|
+
console.log('\n๐ก Killing duplicate processes...');
|
|
102
|
+
for (const [type, procs] of Object.entries(groups)) {
|
|
103
|
+
if (procs.length > 1) {
|
|
104
|
+
// Keep the first one, kill the rest
|
|
105
|
+
for (let i = 1; i < procs.length; i++) {
|
|
106
|
+
try {
|
|
107
|
+
process.kill(procs[i].pid, 'SIGTERM');
|
|
108
|
+
console.log(` Killed duplicate ${type} (PID ${procs[i].pid})`);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// Already dead
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.log('โ
Duplicates removed');
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case '3':
|
|
119
|
+
console.log('\n๐ Killing high memory processes...');
|
|
120
|
+
const highMem = processes.filter(p => p.memory > 100);
|
|
121
|
+
for (const proc of highMem) {
|
|
122
|
+
try {
|
|
123
|
+
process.kill(proc.pid, 'SIGTERM');
|
|
124
|
+
console.log(` Killed PID ${proc.pid} (${proc.memory}MB)`);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
// Already dead
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
console.log('โ
High memory processes terminated');
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
default:
|
|
133
|
+
console.log('โ Cancelled');
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
rl.close();
|
|
138
|
+
|
|
139
|
+
// Show final status
|
|
140
|
+
setTimeout(() => {
|
|
141
|
+
console.log('\n๐ Final status:');
|
|
142
|
+
const remaining = getProcesses();
|
|
143
|
+
console.log(` Remaining processes: ${remaining.length}`);
|
|
144
|
+
if (remaining.length > 0) {
|
|
145
|
+
const memSum = remaining.reduce((sum, p) => sum + p.memory, 0);
|
|
146
|
+
console.log(` Memory usage: ${memSum}MB`);
|
|
147
|
+
}
|
|
148
|
+
}, 1000);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Dynamic MCP Configuration Generator
|
|
4
|
+
* Generates .mcp.json from template with absolute paths and actual environment variables
|
|
5
|
+
* This ensures compatibility with Claude Code while keeping the project portable
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
// Try to load .env file if it exists, but don't fail if it doesn't
|
|
11
|
+
try {
|
|
12
|
+
require('dotenv').config();
|
|
13
|
+
} catch (err) {
|
|
14
|
+
// .env file not found, that's OK
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Determine if we're in a global npm installation
|
|
18
|
+
const isGlobalInstall = __dirname.includes('node_modules/snow-flow') ||
|
|
19
|
+
__dirname.includes('.nvm/versions/node');
|
|
20
|
+
|
|
21
|
+
// For global installs, use the package directory, not cwd
|
|
22
|
+
const packageRoot = isGlobalInstall
|
|
23
|
+
? path.resolve(__dirname, '..') // Go up from scripts/ to package root
|
|
24
|
+
: process.cwd();
|
|
25
|
+
|
|
26
|
+
// The actual project root where we're running the command
|
|
27
|
+
const projectRoot = process.cwd();
|
|
28
|
+
|
|
29
|
+
const templatePath = path.join(packageRoot, '.mcp.json.template');
|
|
30
|
+
const mcpFilePath = path.join(projectRoot, '.mcp.json');
|
|
31
|
+
|
|
32
|
+
// Check if template exists
|
|
33
|
+
if (!fs.existsSync(templatePath)) {
|
|
34
|
+
console.error('โ Error: .mcp.json.template not found!');
|
|
35
|
+
console.error(' This file should be in the project root.');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Check if required environment variables are set
|
|
40
|
+
const requiredEnvVars = ['SNOW_INSTANCE', 'SNOW_CLIENT_ID', 'SNOW_CLIENT_SECRET'];
|
|
41
|
+
const missingVars = requiredEnvVars.filter(varName => !process.env[varName]);
|
|
42
|
+
|
|
43
|
+
if (missingVars.length > 0) {
|
|
44
|
+
console.warn('โ ๏ธ Warning: Missing environment variables:', missingVars.join(', '));
|
|
45
|
+
console.warn(' MCP servers may not work without proper ServiceNow credentials.');
|
|
46
|
+
console.warn(' Copy .env.example to .env and configure your ServiceNow credentials.');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Read template
|
|
50
|
+
const template = fs.readFileSync(templatePath, 'utf8');
|
|
51
|
+
|
|
52
|
+
// Replace placeholders
|
|
53
|
+
const replacements = {
|
|
54
|
+
'{{PROJECT_ROOT}}': packageRoot, // Use packageRoot for MCP server paths
|
|
55
|
+
'{{SNOW_INSTANCE}}': process.env.SNOW_INSTANCE || 'your-instance.service-now.com',
|
|
56
|
+
'{{SNOW_CLIENT_ID}}': process.env.SNOW_CLIENT_ID || 'your-oauth-client-id',
|
|
57
|
+
'{{SNOW_CLIENT_SECRET}}': process.env.SNOW_CLIENT_SECRET || 'your-oauth-client-secret',
|
|
58
|
+
'{{NEO4J_URI}}': process.env.NEO4J_URI || 'bolt://localhost:7687',
|
|
59
|
+
'{{NEO4J_USER}}': process.env.NEO4J_USER || 'neo4j',
|
|
60
|
+
'{{NEO4J_PASSWORD}}': process.env.NEO4J_PASSWORD || 'password'
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
let mcpConfig = template;
|
|
64
|
+
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
65
|
+
mcpConfig = mcpConfig.replace(new RegExp(placeholder, 'g'), value);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Write the configuration file
|
|
69
|
+
fs.writeFileSync(mcpFilePath, mcpConfig);
|
|
70
|
+
|
|
71
|
+
// Make all MCP server files executable
|
|
72
|
+
const mcpServerFiles = [
|
|
73
|
+
'servicenow-deployment-mcp.js',
|
|
74
|
+
'servicenow-update-set-mcp.js',
|
|
75
|
+
'servicenow-intelligent-mcp.js',
|
|
76
|
+
'servicenow-graph-memory-mcp.js',
|
|
77
|
+
'servicenow-operations-mcp.js',
|
|
78
|
+
'servicenow-platform-development-mcp.js',
|
|
79
|
+
'servicenow-integration-mcp.js',
|
|
80
|
+
'servicenow-automation-mcp.js',
|
|
81
|
+
'servicenow-security-compliance-mcp.js',
|
|
82
|
+
'servicenow-reporting-analytics-mcp.js',
|
|
83
|
+
'servicenow-memory-mcp.js'
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
mcpServerFiles.forEach(file => {
|
|
87
|
+
const filePath = path.join(packageRoot, 'dist/mcp', file);
|
|
88
|
+
if (fs.existsSync(filePath)) {
|
|
89
|
+
fs.chmodSync(filePath, '755');
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
console.log('โ
Generated .mcp.json with dynamic configuration');
|
|
94
|
+
console.log('๐ Project directory:', projectRoot);
|
|
95
|
+
console.log('๐ฆ Package directory:', packageRoot);
|
|
96
|
+
console.log('๐ง Environment variables:', requiredEnvVars.filter(v => process.env[v]).length + '/' + requiredEnvVars.length + ' configured');
|
|
97
|
+
console.log('๐ Made MCP server files executable');
|
|
98
|
+
console.log('๐ Using node + args format for Claude Code compatibility');
|
|
99
|
+
|
|
100
|
+
if (missingVars.length === 0) {
|
|
101
|
+
console.log('๐ All ServiceNow environment variables are configured!');
|
|
102
|
+
console.log('๐ก MCP servers should now work properly in Claude Code');
|
|
103
|
+
} else {
|
|
104
|
+
console.log('โ ๏ธ Configure missing environment variables in .env file');
|
|
105
|
+
console.log('๐ See .env.example for setup instructions');
|
|
106
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Proper MCP Server Starter using MCPServerManager
|
|
5
|
+
* REPLACES the legacy start-all-mcp-servers.ts approach
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
async function startMCPServersProper() {
|
|
11
|
+
console.log('๐ Starting MCP servers using proper MCPServerManager...\n');
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
// Import the proper MCPServerManager
|
|
15
|
+
const { MCPServerManager } = require('../dist/utils/mcp-server-manager.js');
|
|
16
|
+
|
|
17
|
+
// Initialize manager
|
|
18
|
+
const manager = new MCPServerManager();
|
|
19
|
+
await manager.initialize();
|
|
20
|
+
|
|
21
|
+
console.log('๐ Initializing MCP server configuration...');
|
|
22
|
+
|
|
23
|
+
// Start all servers with singleton protection built-in
|
|
24
|
+
await manager.startAllServers();
|
|
25
|
+
|
|
26
|
+
console.log('โ
All MCP servers started successfully!\n');
|
|
27
|
+
console.log('๐ Server Status:');
|
|
28
|
+
|
|
29
|
+
// Show server status
|
|
30
|
+
const servers = manager.getServerList();
|
|
31
|
+
for (const server of servers) {
|
|
32
|
+
const status = server.status === 'running' ? '๐ข' :
|
|
33
|
+
server.status === 'starting' ? '๐ก' :
|
|
34
|
+
server.status === 'error' ? '๐ด' : 'โซ';
|
|
35
|
+
console.log(` ${status} ${server.name}: ${server.status}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log('\n๐ก Benefits of using MCPServerManager:');
|
|
39
|
+
console.log(' โข โ
Singleton protection (no duplicates)');
|
|
40
|
+
console.log(' โข โ
Process lifecycle management');
|
|
41
|
+
console.log(' โข โ
Configuration management');
|
|
42
|
+
console.log(' โข โ
Proper logging and monitoring');
|
|
43
|
+
console.log(' โข โ
Graceful shutdown handling');
|
|
44
|
+
console.log(' โข โ
OAuth integration');
|
|
45
|
+
|
|
46
|
+
console.log('\n๐ง Management commands:');
|
|
47
|
+
console.log(' โข Status: manager.getServerStatus()');
|
|
48
|
+
console.log(' โข Stop: manager.stopAllServers()');
|
|
49
|
+
console.log(' โข Restart: manager.restartServer(name)');
|
|
50
|
+
|
|
51
|
+
// Keep process alive to monitor servers
|
|
52
|
+
process.on('SIGINT', async () => {
|
|
53
|
+
console.log('\n๐ Gracefully shutting down all MCP servers...');
|
|
54
|
+
await manager.stopAllServers();
|
|
55
|
+
console.log('โ
All servers stopped. Goodbye!');
|
|
56
|
+
process.exit(0);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
console.log('\nโณ MCP servers running. Press Ctrl+C to stop.');
|
|
60
|
+
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('โ Failed to start MCP servers:', error.message);
|
|
63
|
+
console.error('\n๐ง Troubleshooting:');
|
|
64
|
+
console.error(' 1. Run "npm run build" first');
|
|
65
|
+
console.error(' 2. Check if servers are already running');
|
|
66
|
+
console.error(' 3. Run "npm run cleanup-mcp" to clean state');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Run if executed directly
|
|
72
|
+
if (require.main === module) {
|
|
73
|
+
startMCPServersProper().catch(console.error);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { startMCPServersProper };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# OpenCode Launcher with MCP Server Pre-flight Checks
|
|
4
|
+
# Ensures MCP servers are running before starting OpenCode
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
11
|
+
MCP_MANAGER="$SCRIPT_DIR/mcp-server-manager.sh"
|
|
12
|
+
|
|
13
|
+
# Colors
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
GREEN='\033[0;32m'
|
|
16
|
+
YELLOW='\033[1;33m'
|
|
17
|
+
BLUE='\033[0;34m'
|
|
18
|
+
NC='\033[0m'
|
|
19
|
+
|
|
20
|
+
echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}"
|
|
21
|
+
echo -e "${BLUE} Snow-Flow OpenCode Launcher${NC}"
|
|
22
|
+
echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}"
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
# Check if opencode is installed
|
|
26
|
+
if ! command -v opencode &> /dev/null; then
|
|
27
|
+
echo -e "${RED}โ OpenCode not found!${NC}"
|
|
28
|
+
echo ""
|
|
29
|
+
echo "Install OpenCode:"
|
|
30
|
+
echo " npm install -g @opencode-ai/cli"
|
|
31
|
+
echo ""
|
|
32
|
+
echo "Or visit: https://opencode.ai"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
echo -e "${GREEN}โ OpenCode found${NC}"
|
|
37
|
+
|
|
38
|
+
# Check if .env exists
|
|
39
|
+
if [ ! -f "$PROJECT_ROOT/.env" ]; then
|
|
40
|
+
echo -e "${RED}โ .env file not found!${NC}"
|
|
41
|
+
echo ""
|
|
42
|
+
echo "Create .env from template:"
|
|
43
|
+
echo " cp .env.example .env"
|
|
44
|
+
echo " # Then edit .env with your ServiceNow credentials"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
echo -e "${GREEN}โ .env file found${NC}"
|
|
49
|
+
|
|
50
|
+
# Check if dist/ exists (built)
|
|
51
|
+
if [ ! -d "$PROJECT_ROOT/dist" ]; then
|
|
52
|
+
echo -e "${YELLOW}Building Snow-Flow...${NC}"
|
|
53
|
+
cd "$PROJECT_ROOT"
|
|
54
|
+
npm run build
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
echo -e "${GREEN}โ Snow-Flow built${NC}"
|
|
58
|
+
|
|
59
|
+
# Check if MCP servers are running
|
|
60
|
+
echo -e "\n${BLUE}Checking MCP servers...${NC}"
|
|
61
|
+
|
|
62
|
+
if "$MCP_MANAGER" status > /dev/null 2>&1; then
|
|
63
|
+
echo -e "${GREEN}โ MCP servers already running${NC}"
|
|
64
|
+
else
|
|
65
|
+
echo -e "${YELLOW}Starting MCP servers...${NC}"
|
|
66
|
+
"$MCP_MANAGER" start
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Run health check
|
|
70
|
+
echo -e "\n${BLUE}Running health check...${NC}"
|
|
71
|
+
if "$MCP_MANAGER" health; then
|
|
72
|
+
echo -e "${GREEN}โ All systems operational${NC}"
|
|
73
|
+
else
|
|
74
|
+
echo -e "${RED}โ Health check failed${NC}"
|
|
75
|
+
echo ""
|
|
76
|
+
echo "Troubleshooting:"
|
|
77
|
+
echo " 1. Check logs: $MCP_MANAGER logs"
|
|
78
|
+
echo " 2. Verify .env credentials"
|
|
79
|
+
echo " 3. Test manually: $MCP_MANAGER health"
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Check if opencode-config.json exists
|
|
84
|
+
if [ ! -f "$PROJECT_ROOT/opencode-config.json" ]; then
|
|
85
|
+
echo -e "${YELLOW}Creating opencode-config.json...${NC}"
|
|
86
|
+
|
|
87
|
+
if [ -f "$PROJECT_ROOT/opencode-config.example.json" ]; then
|
|
88
|
+
cp "$PROJECT_ROOT/opencode-config.example.json" "$PROJECT_ROOT/opencode-config.json"
|
|
89
|
+
|
|
90
|
+
# Replace variables in config
|
|
91
|
+
source "$PROJECT_ROOT/.env"
|
|
92
|
+
|
|
93
|
+
sed -i.bak "s|\${SNOW_INSTANCE}|${SNOW_INSTANCE}|g" "$PROJECT_ROOT/opencode-config.json"
|
|
94
|
+
sed -i.bak "s|\${SNOW_CLIENT_ID}|${SNOW_CLIENT_ID}|g" "$PROJECT_ROOT/opencode-config.json"
|
|
95
|
+
sed -i.bak "s|\${SNOW_CLIENT_SECRET}|${SNOW_CLIENT_SECRET}|g" "$PROJECT_ROOT/opencode-config.json"
|
|
96
|
+
sed -i.bak "s|\${SNOW_USERNAME}|${SNOW_USERNAME}|g" "$PROJECT_ROOT/opencode-config.json"
|
|
97
|
+
sed -i.bak "s|\${SNOW_PASSWORD}|${SNOW_PASSWORD}|g" "$PROJECT_ROOT/opencode-config.json"
|
|
98
|
+
sed -i.bak "s|/path/to/your/snow-flow/installation|${PROJECT_ROOT}|g" "$PROJECT_ROOT/opencode-config.json"
|
|
99
|
+
|
|
100
|
+
rm -f "$PROJECT_ROOT/opencode-config.json.bak"
|
|
101
|
+
|
|
102
|
+
echo -e "${GREEN}โ opencode-config.json created${NC}"
|
|
103
|
+
else
|
|
104
|
+
echo -e "${RED}โ opencode-config.example.json not found${NC}"
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
echo -e "${GREEN}โ OpenCode configuration ready${NC}"
|
|
110
|
+
|
|
111
|
+
# Start OpenCode
|
|
112
|
+
echo -e "\n${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}"
|
|
113
|
+
echo -e "${GREEN}Starting OpenCode...${NC}"
|
|
114
|
+
echo -e "${BLUE}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${NC}"
|
|
115
|
+
echo ""
|
|
116
|
+
echo -e "${YELLOW}Tips:${NC}"
|
|
117
|
+
echo -e " โข MCP tools are loaded: snow_update_set_manage, snow_deploy, etc."
|
|
118
|
+
echo -e " โข Start with: ${GREEN}Create an Update Set${NC}"
|
|
119
|
+
echo -e " โข Check tools: Type ${GREEN}list available tools${NC}"
|
|
120
|
+
echo ""
|
|
121
|
+
|
|
122
|
+
cd "$PROJECT_ROOT"
|
|
123
|
+
exec opencode "$@"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Start ServiceNow System Properties MCP Server
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { spawn } = require('child_process');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const serverPath = path.join(__dirname, '..', 'dist', 'mcp', 'servicenow-system-properties-mcp.js');
|
|
11
|
+
|
|
12
|
+
console.log('๐ Starting ServiceNow System Properties MCP Server...');
|
|
13
|
+
console.log(`๐ Server path: ${serverPath}`);
|
|
14
|
+
|
|
15
|
+
const child = spawn('node', [serverPath], {
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
env: {
|
|
18
|
+
...process.env,
|
|
19
|
+
NODE_ENV: 'production'
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
child.on('error', (error) => {
|
|
24
|
+
console.error('โ Failed to start MCP server:', error);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
child.on('exit', (code) => {
|
|
29
|
+
if (code !== 0) {
|
|
30
|
+
console.error(`โ MCP server exited with code ${code}`);
|
|
31
|
+
process.exit(code);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
process.on('SIGINT', () => {
|
|
36
|
+
console.log('\nโน๏ธ Stopping MCP server...');
|
|
37
|
+
child.kill('SIGINT');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
process.on('SIGTERM', () => {
|
|
41
|
+
console.log('\nโน๏ธ Stopping MCP server...');
|
|
42
|
+
child.kill('SIGTERM');
|
|
43
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test TodoWrite timeout fix
|
|
5
|
+
* Verifies that memory operations no longer timeout after 5 seconds
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
console.log('๐งช Testing TodoWrite timeout configuration...\n');
|
|
12
|
+
console.log('โฑ๏ธ Previous timeout: 5 seconds (causing failures)');
|
|
13
|
+
console.log('โ
New default: NO TIMEOUT (operations run until completion)');
|
|
14
|
+
console.log('๐๏ธ Optional: Set MCP_MEMORY_TIMEOUT if you want timeouts\n');
|
|
15
|
+
|
|
16
|
+
// Test data for TodoWrite
|
|
17
|
+
const testTodos = [
|
|
18
|
+
{ id: '1', content: 'Test todo 1', status: 'pending' },
|
|
19
|
+
{ id: '2', content: 'Test todo 2', status: 'pending' },
|
|
20
|
+
{ id: '3', content: 'Test todo 3', status: 'pending' },
|
|
21
|
+
{ id: '4', content: 'Test todo 4', status: 'pending' },
|
|
22
|
+
{ id: '5', content: 'Test todo 5', status: 'pending' }
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
async function testMemoryOperation() {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
|
|
29
|
+
// Run MCP server in test mode
|
|
30
|
+
const mcpProcess = spawn('node', [
|
|
31
|
+
path.join(__dirname, '..', 'dist', 'mcp', 'snow-flow-mcp.js')
|
|
32
|
+
], {
|
|
33
|
+
env: {
|
|
34
|
+
...process.env,
|
|
35
|
+
// No timeout by default - operations run until completion
|
|
36
|
+
// MCP_MEMORY_TIMEOUT: '30000', // Uncomment to test with timeout
|
|
37
|
+
SNOW_FLOW_DEBUG: 'true'
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
let output = '';
|
|
42
|
+
let errorOutput = '';
|
|
43
|
+
|
|
44
|
+
mcpProcess.stdout.on('data', (data) => {
|
|
45
|
+
output += data.toString();
|
|
46
|
+
process.stdout.write(`๐ ${data.toString()}`);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
mcpProcess.stderr.on('data', (data) => {
|
|
50
|
+
errorOutput += data.toString();
|
|
51
|
+
process.stderr.write(`โ ๏ธ ${data.toString()}`);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Simulate memory operation
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
const elapsed = Date.now() - startTime;
|
|
57
|
+
console.log(`\nโ
Memory operation completed in ${elapsed}ms`);
|
|
58
|
+
|
|
59
|
+
if (elapsed > 5000) {
|
|
60
|
+
console.log('โ
No-timeout configuration confirmed - operation exceeded 5s without failing!');
|
|
61
|
+
console.log('๐ฏ Operation ran for ' + (elapsed/1000).toFixed(1) + 's with no timeout!');
|
|
62
|
+
resolve(true);
|
|
63
|
+
} else {
|
|
64
|
+
console.log('โก Operation completed quickly (< 5s)');
|
|
65
|
+
resolve(true);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
mcpProcess.kill();
|
|
69
|
+
}, 6000); // Test at 6 seconds (would have failed before)
|
|
70
|
+
|
|
71
|
+
mcpProcess.on('error', (err) => {
|
|
72
|
+
console.error('โ Process error:', err);
|
|
73
|
+
reject(err);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
mcpProcess.on('exit', (code) => {
|
|
77
|
+
if (code !== 0 && code !== null) {
|
|
78
|
+
console.log(`Process exited with code ${code}`);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function runTest() {
|
|
85
|
+
console.log('๐ Starting TodoWrite timeout test...\n');
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const success = await testMemoryOperation();
|
|
89
|
+
|
|
90
|
+
if (success) {
|
|
91
|
+
console.log('\nโ
SUCCESS: No-timeout configuration is working!');
|
|
92
|
+
console.log('๐ก TodoWrite operations have NO timeout by default');
|
|
93
|
+
console.log('๐ Set MCP_MEMORY_TIMEOUT env var only if you need timeouts');
|
|
94
|
+
console.log('\nExample timeout configurations (all optional):');
|
|
95
|
+
console.log(' MCP_MEMORY_TIMEOUT=30000 # 30 seconds');
|
|
96
|
+
console.log(' MCP_MEMORY_TIMEOUT=60000 # 1 minute');
|
|
97
|
+
console.log(' MCP_MEMORY_TIMEOUT=120000 # 2 minutes');
|
|
98
|
+
} else {
|
|
99
|
+
console.log('\nโ ๏ธ Test completed but results inconclusive');
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('\nโ Test failed:', error.message);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Run the test
|
|
108
|
+
runTest().catch(console.error);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Update version.ts with the current version from package.json
|
|
5
|
+
* This script runs automatically after npm version
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
// Read package.json
|
|
12
|
+
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
13
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
14
|
+
const version = packageJson.version;
|
|
15
|
+
|
|
16
|
+
// Path to version.ts
|
|
17
|
+
const versionTsPath = path.join(__dirname, '..', 'src', 'version.ts');
|
|
18
|
+
|
|
19
|
+
// Read current version.ts content
|
|
20
|
+
const versionTsContent = fs.readFileSync(versionTsPath, 'utf8');
|
|
21
|
+
|
|
22
|
+
// Replace the VERSION constant
|
|
23
|
+
const updatedContent = versionTsContent.replace(
|
|
24
|
+
/export const VERSION = '[^']+';/,
|
|
25
|
+
`export const VERSION = '${version}';`
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Write updated content back
|
|
29
|
+
fs.writeFileSync(versionTsPath, updatedContent, 'utf8');
|
|
30
|
+
|
|
31
|
+
console.log(`โ
Updated version.ts to ${version}`);
|