@stackmemoryai/stackmemory 0.3.21 ā 0.3.24
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/dist/cli/commands/linear-unified.js +2 -3
- package/dist/cli/commands/linear-unified.js.map +2 -2
- package/dist/cli/commands/ralph.js +294 -0
- package/dist/cli/commands/ralph.js.map +7 -0
- package/dist/cli/commands/tasks.js +1 -1
- package/dist/cli/commands/tasks.js.map +2 -2
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +2 -2
- package/dist/integrations/mcp/handlers/code-execution-handlers.js +262 -0
- package/dist/integrations/mcp/handlers/code-execution-handlers.js.map +7 -0
- package/dist/integrations/mcp/tool-definitions-code.js +121 -0
- package/dist/integrations/mcp/tool-definitions-code.js.map +7 -0
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js +586 -0
- package/dist/integrations/ralph/bridge/ralph-stackmemory-bridge.js.map +7 -0
- package/dist/integrations/ralph/context/context-budget-manager.js +297 -0
- package/dist/integrations/ralph/context/context-budget-manager.js.map +7 -0
- package/dist/integrations/ralph/context/stackmemory-context-loader.js +356 -0
- package/dist/integrations/ralph/context/stackmemory-context-loader.js.map +7 -0
- package/dist/integrations/ralph/index.js +14 -0
- package/dist/integrations/ralph/index.js.map +7 -0
- package/dist/integrations/ralph/learning/pattern-learner.js +397 -0
- package/dist/integrations/ralph/learning/pattern-learner.js.map +7 -0
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js +444 -0
- package/dist/integrations/ralph/lifecycle/iteration-lifecycle.js.map +7 -0
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js +459 -0
- package/dist/integrations/ralph/orchestration/multi-loop-orchestrator.js.map +7 -0
- package/dist/integrations/ralph/performance/performance-optimizer.js +354 -0
- package/dist/integrations/ralph/performance/performance-optimizer.js.map +7 -0
- package/dist/integrations/ralph/ralph-integration-demo.js +178 -0
- package/dist/integrations/ralph/ralph-integration-demo.js.map +7 -0
- package/dist/integrations/ralph/state/state-reconciler.js +400 -0
- package/dist/integrations/ralph/state/state-reconciler.js.map +7 -0
- package/dist/integrations/ralph/swarm/swarm-coordinator.js +487 -0
- package/dist/integrations/ralph/swarm/swarm-coordinator.js.map +7 -0
- package/dist/integrations/ralph/types.js +1 -0
- package/dist/integrations/ralph/types.js.map +7 -0
- package/dist/integrations/ralph/visualization/ralph-debugger.js +581 -0
- package/dist/integrations/ralph/visualization/ralph-debugger.js.map +7 -0
- package/dist/servers/railway/index.js +98 -92
- package/dist/servers/railway/index.js.map +3 -3
- package/package.json +1 -2
- package/scripts/claude-sm-autostart.js +1 -1
- package/scripts/clean-linear-backlog.js +2 -2
- package/scripts/debug-linear-update.js +1 -1
- package/scripts/debug-railway-build.js +87 -0
- package/scripts/delete-linear-tasks.js +2 -2
- package/scripts/deploy-ralph-swarm.sh +365 -0
- package/scripts/install-code-execution-hooks.sh +96 -0
- package/scripts/linear-task-review.js +1 -1
- package/scripts/ralph-integration-test.js +274 -0
- package/scripts/ralph-loop-implementation.js +404 -0
- package/scripts/swarm-monitor.js +509 -0
- package/scripts/sync-and-clean-tasks.js +1 -1
- package/scripts/sync-linear-graphql.js +3 -3
- package/scripts/sync-linear-tasks.js +1 -1
- package/scripts/test-code-execution.js +143 -0
- package/scripts/test-parallel-swarms.js +443 -0
- package/scripts/testing/ralph-cli-test.js +88 -0
- package/scripts/testing/ralph-integration-validation.js +727 -0
- package/scripts/testing/ralph-swarm-test-scenarios.js +613 -0
- package/scripts/update-linear-tasks-fixed.js +1 -1
- package/scripts/validate-railway-deployment.js +137 -0
- package/templates/claude-hooks/hook-config.json +59 -0
- package/templates/claude-hooks/pre-tool-use +189 -0
- package/dist/servers/railway/minimal.js +0 -91
- package/dist/servers/railway/minimal.js.map +0 -7
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate Railway deployment and check all services
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
async function checkEndpoint(url, expectedKeys = []) {
|
|
8
|
+
try {
|
|
9
|
+
console.log(`\nš Checking: ${url}`);
|
|
10
|
+
const response = await fetch(url);
|
|
11
|
+
const data = await response.json();
|
|
12
|
+
|
|
13
|
+
console.log(` Status: ${response.status}`);
|
|
14
|
+
console.log(` Response:`, JSON.stringify(data, null, 2));
|
|
15
|
+
|
|
16
|
+
// Check for expected keys
|
|
17
|
+
for (const key of expectedKeys) {
|
|
18
|
+
if (key in data) {
|
|
19
|
+
console.log(` ā
Found key: ${key}`);
|
|
20
|
+
} else {
|
|
21
|
+
console.log(` ā Missing key: ${key}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return { success: response.ok, data };
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.log(` ā Error: ${error.message}`);
|
|
28
|
+
return { success: false, error: error.message };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function testAuth(baseUrl) {
|
|
33
|
+
console.log('\nš Testing Authentication Endpoints:');
|
|
34
|
+
|
|
35
|
+
// Test signup
|
|
36
|
+
const signupData = {
|
|
37
|
+
email: `test${Date.now()}@example.com`,
|
|
38
|
+
password: 'TestPass123!',
|
|
39
|
+
name: 'Test User'
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
console.log('\nš Testing POST /auth/signup');
|
|
43
|
+
try {
|
|
44
|
+
const response = await fetch(`${baseUrl}/auth/signup`, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'Content-Type': 'application/json' },
|
|
47
|
+
body: JSON.stringify(signupData)
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const data = await response.json();
|
|
51
|
+
console.log(` Status: ${response.status}`);
|
|
52
|
+
|
|
53
|
+
if (response.ok) {
|
|
54
|
+
console.log(' ā
Signup endpoint works!');
|
|
55
|
+
console.log(` Response:`, JSON.stringify(data, null, 2));
|
|
56
|
+
} else {
|
|
57
|
+
console.log(' ā Signup failed:', data.error || data.message);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.log(' ā Signup endpoint not available:', error.message);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Test login
|
|
64
|
+
console.log('\nš Testing POST /auth/login');
|
|
65
|
+
try {
|
|
66
|
+
const response = await fetch(`${baseUrl}/auth/login`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
headers: { 'Content-Type': 'application/json' },
|
|
69
|
+
body: JSON.stringify({
|
|
70
|
+
email: signupData.email,
|
|
71
|
+
password: signupData.password
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const data = await response.json();
|
|
76
|
+
console.log(` Status: ${response.status}`);
|
|
77
|
+
|
|
78
|
+
if (response.ok) {
|
|
79
|
+
console.log(' ā
Login endpoint works!');
|
|
80
|
+
console.log(` Token received:`, data.token ? 'Yes' : 'No');
|
|
81
|
+
console.log(` API Key:`, data.apiKey ? 'Yes' : 'No');
|
|
82
|
+
} else {
|
|
83
|
+
console.log(' ā Login failed:', data.error || data.message);
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.log(' ā Login endpoint not available:', error.message);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function main() {
|
|
91
|
+
const baseUrl = process.argv[2] || 'https://stackmemory-production.up.railway.app';
|
|
92
|
+
|
|
93
|
+
console.log('š StackMemory Railway Deployment Validator');
|
|
94
|
+
console.log('==========================================');
|
|
95
|
+
console.log(`Base URL: ${baseUrl}`);
|
|
96
|
+
console.log(`Timestamp: ${new Date().toISOString()}`);
|
|
97
|
+
|
|
98
|
+
// Check root endpoint
|
|
99
|
+
const root = await checkEndpoint(baseUrl, ['message', 'version', 'endpoints']);
|
|
100
|
+
|
|
101
|
+
// Detect server type
|
|
102
|
+
if (root.data?.message?.includes('Minimal')) {
|
|
103
|
+
console.log('\nā ļø WARNING: Minimal server is running!');
|
|
104
|
+
console.log(' The full server with auth endpoints is not deployed.');
|
|
105
|
+
} else if (root.data?.message?.includes('API Server')) {
|
|
106
|
+
console.log('\nā
Full API server is running!');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Check health
|
|
110
|
+
await checkEndpoint(`${baseUrl}/health`, ['status']);
|
|
111
|
+
|
|
112
|
+
// Check database connections
|
|
113
|
+
const dbTest = await checkEndpoint(`${baseUrl}/test-db`, ['postgresql', 'redis']);
|
|
114
|
+
|
|
115
|
+
if (dbTest.data) {
|
|
116
|
+
console.log('\nš Database Status:');
|
|
117
|
+
if (dbTest.data.postgresql?.status === 'connected') {
|
|
118
|
+
console.log(' ā
PostgreSQL: Connected');
|
|
119
|
+
} else {
|
|
120
|
+
console.log(' ā PostgreSQL:', dbTest.data.postgresql?.status || 'Not configured');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (dbTest.data.redis?.status === 'connected') {
|
|
124
|
+
console.log(' ā
Redis: Connected');
|
|
125
|
+
} else {
|
|
126
|
+
console.log(' ā Redis:', dbTest.data.redis?.status || 'Not configured');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Test auth endpoints
|
|
131
|
+
await testAuth(baseUrl);
|
|
132
|
+
|
|
133
|
+
console.log('\n==========================================');
|
|
134
|
+
console.log('Validation complete!');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pre-tool-use": {
|
|
3
|
+
"description": "Controls tool usage based on configured policies",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"modes": {
|
|
6
|
+
"permissive": {
|
|
7
|
+
"description": "Allow all tools but log dangerous operations",
|
|
8
|
+
"default": true,
|
|
9
|
+
"restrictions": []
|
|
10
|
+
},
|
|
11
|
+
"restrictive": {
|
|
12
|
+
"description": "Block potentially dangerous tools",
|
|
13
|
+
"restrictions": ["Bash", "Write", "Edit", "Delete", "WebFetch"],
|
|
14
|
+
"allowed": ["TodoWrite", "TodoRead", "Read", "Grep", "LS"]
|
|
15
|
+
},
|
|
16
|
+
"code_only": {
|
|
17
|
+
"description": "Only allow code execution tools - pure computational environment",
|
|
18
|
+
"restrictions": ["*"],
|
|
19
|
+
"allowed": ["mcp__stackmemory__code.execute", "mcp__code-executor__execute_code", "TodoWrite", "TodoRead"]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"alwaysAllowed": [
|
|
23
|
+
"mcp__stackmemory__save_context",
|
|
24
|
+
"mcp__stackmemory__load_context",
|
|
25
|
+
"TodoWrite",
|
|
26
|
+
"TodoRead"
|
|
27
|
+
],
|
|
28
|
+
"dangerousTools": [
|
|
29
|
+
"Bash",
|
|
30
|
+
"Write",
|
|
31
|
+
"Edit",
|
|
32
|
+
"Delete",
|
|
33
|
+
"WebFetch",
|
|
34
|
+
"MultiEdit"
|
|
35
|
+
],
|
|
36
|
+
"codeExecutionTools": [
|
|
37
|
+
"mcp__code-executor__execute_code",
|
|
38
|
+
"mcp__stackmemory__code.execute"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"installation": {
|
|
42
|
+
"commands": [
|
|
43
|
+
"# Install pre-tool-use hook",
|
|
44
|
+
"cp templates/claude-hooks/pre-tool-use ~/.claude/hooks/",
|
|
45
|
+
"chmod +x ~/.claude/hooks/pre-tool-use",
|
|
46
|
+
"",
|
|
47
|
+
"# Set mode (optional, defaults to permissive)",
|
|
48
|
+
"export STACKMEMORY_TOOL_MODE=permissive # or restrictive, code_only",
|
|
49
|
+
"",
|
|
50
|
+
"# View tool usage logs",
|
|
51
|
+
"tail -f ~/.stackmemory/tool-use.log"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"usage": {
|
|
55
|
+
"permissive_mode": "Default mode - all tools allowed with logging",
|
|
56
|
+
"restrictive_mode": "Blocks dangerous tools like Bash, Write, Edit",
|
|
57
|
+
"code_only_mode": "Only code execution allowed - ideal for pure computation tasks"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pre-Tool-Use Hook for StackMemory
|
|
5
|
+
* Controls and filters tool usage based on configured policies
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
// Configuration for tool restrictions
|
|
16
|
+
const CONFIG = {
|
|
17
|
+
// Mode: 'restrictive' | 'permissive' | 'code_only'
|
|
18
|
+
mode: process.env.STACKMEMORY_TOOL_MODE || 'permissive',
|
|
19
|
+
|
|
20
|
+
// Tools that are always allowed
|
|
21
|
+
alwaysAllowed: [
|
|
22
|
+
'mcp__stackmemory__save_context',
|
|
23
|
+
'mcp__stackmemory__load_context',
|
|
24
|
+
'TodoWrite',
|
|
25
|
+
'TodoRead',
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
// Tools that are blocked in restrictive mode
|
|
29
|
+
restrictedTools: [
|
|
30
|
+
'Bash',
|
|
31
|
+
'Write',
|
|
32
|
+
'Edit',
|
|
33
|
+
'Delete',
|
|
34
|
+
'WebFetch',
|
|
35
|
+
],
|
|
36
|
+
|
|
37
|
+
// Code execution tools
|
|
38
|
+
codeExecutionTools: [
|
|
39
|
+
'mcp__code-executor__execute_code',
|
|
40
|
+
'mcp__stackmemory__code.execute',
|
|
41
|
+
],
|
|
42
|
+
|
|
43
|
+
// Log file for audit
|
|
44
|
+
logFile: path.join(process.env.HOME || '/tmp', '.stackmemory', 'tool-use.log'),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Read input from stdin
|
|
48
|
+
async function readInput() {
|
|
49
|
+
let input = '';
|
|
50
|
+
for await (const chunk of process.stdin) {
|
|
51
|
+
input += chunk;
|
|
52
|
+
}
|
|
53
|
+
return JSON.parse(input);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Log tool usage
|
|
57
|
+
function logToolUse(toolName, allowed, reason) {
|
|
58
|
+
try {
|
|
59
|
+
const logDir = path.dirname(CONFIG.logFile);
|
|
60
|
+
if (!fs.existsSync(logDir)) {
|
|
61
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const logEntry = {
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
tool: toolName,
|
|
67
|
+
allowed,
|
|
68
|
+
reason,
|
|
69
|
+
mode: CONFIG.mode,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
fs.appendFileSync(CONFIG.logFile, JSON.stringify(logEntry) + '\n');
|
|
73
|
+
} catch (error) {
|
|
74
|
+
// Silently fail logging
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check if tool should be allowed
|
|
79
|
+
function shouldAllowTool(toolName, params) {
|
|
80
|
+
// Always allowed tools
|
|
81
|
+
if (CONFIG.alwaysAllowed.includes(toolName)) {
|
|
82
|
+
return { allowed: true, reason: 'Always allowed tool' };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Mode-specific logic
|
|
86
|
+
switch (CONFIG.mode) {
|
|
87
|
+
case 'code_only':
|
|
88
|
+
// Only allow code execution tools
|
|
89
|
+
if (CONFIG.codeExecutionTools.includes(toolName)) {
|
|
90
|
+
return { allowed: true, reason: 'Code execution tool in code_only mode' };
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
allowed: false,
|
|
94
|
+
reason: 'Only code execution is allowed in code_only mode',
|
|
95
|
+
suggestion: 'Use mcp__stackmemory__code.execute to run Python/JavaScript code',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
case 'restrictive':
|
|
99
|
+
// Block restricted tools
|
|
100
|
+
if (CONFIG.restrictedTools.includes(toolName)) {
|
|
101
|
+
return {
|
|
102
|
+
allowed: false,
|
|
103
|
+
reason: `Tool '${toolName}' is restricted in current mode`,
|
|
104
|
+
suggestion: 'This tool is blocked for safety. Consider using code execution instead.',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return { allowed: true, reason: 'Not in restricted list' };
|
|
108
|
+
|
|
109
|
+
case 'permissive':
|
|
110
|
+
default:
|
|
111
|
+
// Allow everything but log dangerous operations
|
|
112
|
+
if (CONFIG.restrictedTools.includes(toolName)) {
|
|
113
|
+
logToolUse(toolName, true, 'Potentially dangerous tool in permissive mode');
|
|
114
|
+
}
|
|
115
|
+
return { allowed: true, reason: 'Permissive mode' };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Main hook logic
|
|
120
|
+
async function main() {
|
|
121
|
+
try {
|
|
122
|
+
const input = await readInput();
|
|
123
|
+
const { tool_name, parameters } = input;
|
|
124
|
+
|
|
125
|
+
// Check if tool should be allowed
|
|
126
|
+
const decision = shouldAllowTool(tool_name, parameters);
|
|
127
|
+
|
|
128
|
+
// Log the decision
|
|
129
|
+
logToolUse(tool_name, decision.allowed, decision.reason);
|
|
130
|
+
|
|
131
|
+
if (!decision.allowed) {
|
|
132
|
+
// Block the tool
|
|
133
|
+
console.error(JSON.stringify({
|
|
134
|
+
status: 'blocked',
|
|
135
|
+
tool: tool_name,
|
|
136
|
+
reason: decision.reason,
|
|
137
|
+
suggestion: decision.suggestion,
|
|
138
|
+
message: `Tool '${tool_name}' is blocked. ${decision.suggestion || ''}`,
|
|
139
|
+
}));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Special handling for code execution
|
|
144
|
+
if (CONFIG.codeExecutionTools.includes(tool_name)) {
|
|
145
|
+
// Add safety warnings
|
|
146
|
+
if (parameters.code && parameters.code.includes('import os')) {
|
|
147
|
+
console.error(JSON.stringify({
|
|
148
|
+
status: 'warning',
|
|
149
|
+
message: 'Code contains potentially dangerous imports. Reviewing...',
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Allow the tool
|
|
155
|
+
console.log(JSON.stringify({
|
|
156
|
+
status: 'allowed',
|
|
157
|
+
tool: tool_name,
|
|
158
|
+
mode: CONFIG.mode,
|
|
159
|
+
}));
|
|
160
|
+
|
|
161
|
+
} catch (error) {
|
|
162
|
+
// On error, allow by default (fail open)
|
|
163
|
+
console.error(JSON.stringify({
|
|
164
|
+
status: 'error',
|
|
165
|
+
message: error.message,
|
|
166
|
+
fallback: 'allowing tool due to hook error',
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Handle environment info request
|
|
172
|
+
if (process.argv.includes('--info')) {
|
|
173
|
+
console.log(JSON.stringify({
|
|
174
|
+
hook: 'pre-tool-use',
|
|
175
|
+
version: '1.0.0',
|
|
176
|
+
mode: CONFIG.mode,
|
|
177
|
+
modes: ['permissive', 'restrictive', 'code_only'],
|
|
178
|
+
description: 'Controls tool usage based on configured policies',
|
|
179
|
+
}));
|
|
180
|
+
process.exit(0);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
main().catch(error => {
|
|
184
|
+
console.error(JSON.stringify({
|
|
185
|
+
status: 'error',
|
|
186
|
+
message: error.message,
|
|
187
|
+
}));
|
|
188
|
+
process.exit(1);
|
|
189
|
+
});
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import http from "http";
|
|
3
|
-
const PORT = process.env.PORT || 3e3;
|
|
4
|
-
const server = http.createServer(async (req, res) => {
|
|
5
|
-
console.log(`${(/* @__PURE__ */ new Date()).toISOString()} ${req.method} ${req.url}`);
|
|
6
|
-
if (req.url === "/health" || req.url === "/api/health") {
|
|
7
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
8
|
-
res.end(
|
|
9
|
-
JSON.stringify({
|
|
10
|
-
status: "healthy",
|
|
11
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12
|
-
port: PORT,
|
|
13
|
-
env: process.env.NODE_ENV || "development"
|
|
14
|
-
})
|
|
15
|
-
);
|
|
16
|
-
} else if (req.url === "/test-db") {
|
|
17
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
18
|
-
const testResults = { postgresql: {}, redis: {} };
|
|
19
|
-
if (process.env.DATABASE_URL) {
|
|
20
|
-
try {
|
|
21
|
-
const { Client } = (await import("pg")).default;
|
|
22
|
-
const pgClient = new Client({ connectionString: process.env.DATABASE_URL });
|
|
23
|
-
await pgClient.connect();
|
|
24
|
-
const result = await pgClient.query("SELECT NOW() as time, version() as version");
|
|
25
|
-
testResults.postgresql = {
|
|
26
|
-
status: "connected",
|
|
27
|
-
time: result.rows[0].time,
|
|
28
|
-
version: result.rows[0].version.split(" ")[0]
|
|
29
|
-
};
|
|
30
|
-
await pgClient.end();
|
|
31
|
-
} catch (error) {
|
|
32
|
-
testResults.postgresql = { status: "error", message: error.message };
|
|
33
|
-
}
|
|
34
|
-
} else {
|
|
35
|
-
testResults.postgresql = { status: "not_configured" };
|
|
36
|
-
}
|
|
37
|
-
const redisUrl = process.env.REDIS_URL || (process.env.REDISHOST ? `redis://${process.env.REDISHOST}:${process.env.REDISPORT || 6379}` : null);
|
|
38
|
-
if (redisUrl) {
|
|
39
|
-
try {
|
|
40
|
-
const { createClient } = await import("redis");
|
|
41
|
-
const redisClient = createClient({ url: redisUrl });
|
|
42
|
-
await redisClient.connect();
|
|
43
|
-
await redisClient.ping();
|
|
44
|
-
const info = await redisClient.info("server");
|
|
45
|
-
const version = info.match(/redis_version:(.+)/)?.[1];
|
|
46
|
-
testResults.redis = {
|
|
47
|
-
status: "connected",
|
|
48
|
-
version,
|
|
49
|
-
url: redisUrl.replace(/:\/\/[^@]+@/, "://***:***@")
|
|
50
|
-
// Hide credentials
|
|
51
|
-
};
|
|
52
|
-
await redisClient.disconnect();
|
|
53
|
-
} catch (error) {
|
|
54
|
-
testResults.redis = { status: "error", message: error.message };
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
testResults.redis = { status: "not_configured" };
|
|
58
|
-
}
|
|
59
|
-
res.end(JSON.stringify(testResults, null, 2));
|
|
60
|
-
} else if (req.url === "/") {
|
|
61
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
62
|
-
res.end(
|
|
63
|
-
JSON.stringify({
|
|
64
|
-
message: "StackMemory Minimal Server Running",
|
|
65
|
-
version: "1.0.0",
|
|
66
|
-
endpoints: ["/health", "/api/health", "/test-db"]
|
|
67
|
-
})
|
|
68
|
-
);
|
|
69
|
-
} else {
|
|
70
|
-
res.writeHead(404, { "Content-Type": "application/json" });
|
|
71
|
-
res.end(JSON.stringify({ error: "Not found" }));
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
server.listen(PORT, "0.0.0.0", () => {
|
|
75
|
-
console.log(`
|
|
76
|
-
=================================
|
|
77
|
-
Minimal Server Started
|
|
78
|
-
Port: ${PORT}
|
|
79
|
-
Time: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
80
|
-
=================================
|
|
81
|
-
`);
|
|
82
|
-
});
|
|
83
|
-
process.on("SIGTERM", () => {
|
|
84
|
-
console.log("SIGTERM received");
|
|
85
|
-
server.close(() => process.exit(0));
|
|
86
|
-
});
|
|
87
|
-
process.on("SIGINT", () => {
|
|
88
|
-
console.log("SIGINT received");
|
|
89
|
-
server.close(() => process.exit(0));
|
|
90
|
-
});
|
|
91
|
-
//# sourceMappingURL=minimal.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/servers/railway/minimal.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n/**\n * Minimal Railway Server - Absolute minimum for testing\n */\n\nimport http from 'http';\n\nconst PORT = process.env.PORT || 3000;\n\nconst server = http.createServer(async (req, res) => {\n console.log(`${new Date().toISOString()} ${req.method} ${req.url}`);\n\n if (req.url === '/health' || req.url === '/api/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n status: 'healthy',\n timestamp: new Date().toISOString(),\n port: PORT,\n env: process.env.NODE_ENV || 'development',\n })\n );\n } else if (req.url === '/test-db') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n \n // Test database connections\n const testResults = { postgresql: {}, redis: {} };\n \n // Test PostgreSQL\n if (process.env.DATABASE_URL) {\n try {\n const { Client } = (await import('pg')).default;\n const pgClient = new Client({ connectionString: process.env.DATABASE_URL });\n await pgClient.connect();\n \n const result = await pgClient.query('SELECT NOW() as time, version() as version');\n testResults.postgresql = {\n status: 'connected',\n time: result.rows[0].time,\n version: result.rows[0].version.split(' ')[0]\n };\n \n await pgClient.end();\n } catch (error) {\n testResults.postgresql = { status: 'error', message: error.message };\n }\n } else {\n testResults.postgresql = { status: 'not_configured' };\n }\n \n // Test Redis\n const redisUrl = process.env.REDIS_URL || \n (process.env.REDISHOST ? `redis://${process.env.REDISHOST}:${process.env.REDISPORT || 6379}` : null);\n \n if (redisUrl) {\n try {\n const { createClient } = await import('redis');\n const redisClient = createClient({ url: redisUrl });\n await redisClient.connect();\n \n await redisClient.ping();\n const info = await redisClient.info('server');\n const version = info.match(/redis_version:(.+)/)?.[1];\n \n testResults.redis = {\n status: 'connected',\n version: version,\n url: redisUrl.replace(/:\\/\\/[^@]+@/, '://***:***@') // Hide credentials\n };\n \n await redisClient.disconnect();\n } catch (error) {\n testResults.redis = { status: 'error', message: error.message };\n }\n } else {\n testResults.redis = { status: 'not_configured' };\n }\n \n res.end(JSON.stringify(testResults, null, 2));\n } else if (req.url === '/') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n message: 'StackMemory Minimal Server Running',\n version: '1.0.0',\n endpoints: ['/health', '/api/health', '/test-db']\n })\n );\n } else {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n }\n});\n\nserver.listen(PORT, '0.0.0.0', () => {\n console.log(`\n=================================\nMinimal Server Started\nPort: ${PORT}\nTime: ${new Date().toISOString()}\n=================================\n `);\n});\n\n// Keep alive\nprocess.on('SIGTERM', () => {\n console.log('SIGTERM received');\n server.close(() => process.exit(0));\n});\n\nprocess.on('SIGINT', () => {\n console.log('SIGINT received');\n server.close(() => process.exit(0));\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|