Skip to content

Commit 68aa4b1

Browse files
committed
Add gateway diagnostics and improved UI proxy with better error handling
1 parent 75d4eaf commit 68aa4b1

File tree

7 files changed

+536
-17
lines changed

7 files changed

+536
-17
lines changed

claude-home/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: "Claude Home"
22
description: "AI-powered terminal and chat interface with Claude Code CLI"
3-
version: "2.3.15"
3+
version: "2.3.16"
44
slug: "claude_home"
55
init: false
66

claude-home/fix-gateway-proxy.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Fixed server.js with better error handling and logging
2+
const http = require('http');
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
const PORT = 8080;
7+
8+
// Simple proxy function with better error handling
9+
function proxy(req, res, targetHost, targetPort, targetPath) {
10+
console.log(`Proxying ${req.url} to ${targetHost}:${targetPort}${targetPath}`);
11+
12+
const options = {
13+
hostname: targetHost,
14+
port: targetPort,
15+
path: targetPath || req.url,
16+
method: req.method,
17+
headers: {...req.headers, host: `${targetHost}:${targetPort}`}
18+
};
19+
20+
const proxyReq = http.request(options, (proxyRes) => {
21+
console.log(`Proxy response: ${proxyRes.statusCode}`);
22+
res.writeHead(proxyRes.statusCode, proxyRes.headers);
23+
proxyRes.pipe(res);
24+
});
25+
26+
proxyReq.on('error', (err) => {
27+
console.error(`Proxy error to ${targetHost}:${targetPort}:`, err.message);
28+
res.writeHead(502, {'Content-Type': 'application/json'});
29+
res.end(JSON.stringify({error: 'Gateway error', details: err.message}));
30+
});
31+
32+
req.pipe(proxyReq);
33+
}
34+
35+
const server = http.createServer((req, res) => {
36+
console.log(`Request: ${req.method} ${req.url}`);
37+
38+
// Add CORS headers for all responses
39+
res.setHeader('Access-Control-Allow-Origin', '*');
40+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
41+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
42+
43+
// Handle OPTIONS for CORS
44+
if (req.method === 'OPTIONS') {
45+
res.writeHead(200);
46+
res.end();
47+
return;
48+
}
49+
50+
// Route based on path
51+
if (req.url === '/' || req.url === '/index.html') {
52+
// Serve the main UI
53+
fs.readFile(path.join(__dirname, 'index.html'), (err, data) => {
54+
if (err) {
55+
console.error('Error reading index.html:', err);
56+
res.writeHead(500);
57+
res.end('Error loading page');
58+
return;
59+
}
60+
res.writeHead(200, {'Content-Type': 'text/html'});
61+
res.end(data);
62+
});
63+
} else if (req.url.startsWith('/chat')) {
64+
// Proxy to chat UI
65+
const targetPath = req.url.substring(5) || '/';
66+
proxy(req, res, 'localhost', 3000, targetPath);
67+
} else if (req.url.startsWith('/terminal')) {
68+
// Proxy to ttyd
69+
const targetPath = req.url.substring(9) || '/';
70+
proxy(req, res, 'localhost', 7681, targetPath);
71+
} else if (req.url.startsWith('/v1/')) {
72+
// Proxy to gateway API - THIS IS THE IMPORTANT ONE
73+
proxy(req, res, 'localhost', 8001, req.url);
74+
} else {
75+
res.writeHead(404);
76+
res.end(`Not found: ${req.url}`);
77+
}
78+
});
79+
80+
// Handle WebSocket upgrades
81+
server.on('upgrade', (req, socket, head) => {
82+
console.log(`WebSocket upgrade request: ${req.url}`);
83+
84+
if (req.url.startsWith('/terminal')) {
85+
// Proxy WebSocket to ttyd
86+
const net = require('net');
87+
const upstream = net.connect(7681, 'localhost');
88+
89+
upstream.on('connect', () => {
90+
console.log('Connected to ttyd WebSocket');
91+
const targetPath = req.url.substring(9) || '/';
92+
upstream.write(`GET ${targetPath} HTTP/1.1\r\n`);
93+
for (const [key, value] of Object.entries(req.headers)) {
94+
if (key.toLowerCase() !== 'host') {
95+
upstream.write(`${key}: ${value}\r\n`);
96+
}
97+
}
98+
upstream.write('Host: localhost:7681\r\n');
99+
upstream.write('\r\n');
100+
upstream.write(head);
101+
102+
socket.pipe(upstream);
103+
upstream.pipe(socket);
104+
});
105+
106+
upstream.on('error', (err) => {
107+
console.error('WebSocket upstream error:', err);
108+
socket.destroy();
109+
});
110+
111+
socket.on('error', (err) => {
112+
console.error('WebSocket socket error:', err);
113+
upstream.destroy();
114+
});
115+
} else {
116+
socket.destroy();
117+
}
118+
});
119+
120+
server.listen(PORT, '0.0.0.0', () => {
121+
console.log(`UI server running on port ${PORT}`);
122+
console.log('Routes:');
123+
console.log(' / -> UI (this server)');
124+
console.log(' /chat/* -> localhost:3000');
125+
console.log(' /terminal/* -> localhost:7681');
126+
console.log(' /v1/* -> localhost:8001 (Gateway API)');
127+
128+
// Test gateway connectivity on startup
129+
setTimeout(() => {
130+
const testReq = http.get('http://localhost:8001/health', (res) => {
131+
console.log(`Gateway health check: ${res.statusCode}`);
132+
});
133+
testReq.on('error', (err) => {
134+
console.error('Gateway not responding:', err.message);
135+
});
136+
}, 1000);
137+
});

claude-home/quick-gateway-fix.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/bin/bash
2+
# Quick fix for gateway connectivity issue
3+
4+
echo "=== Quick Gateway Fix ==="
5+
echo
6+
7+
# 1. Check if gateway is running
8+
echo "1. Checking gateway status..."
9+
if supervisorctl status chat-gateway | grep -q RUNNING; then
10+
echo " ✓ Gateway is running"
11+
else
12+
echo " ✗ Gateway is not running"
13+
echo " Starting gateway..."
14+
supervisorctl start chat-gateway
15+
fi
16+
17+
# 2. Test gateway directly
18+
echo
19+
echo "2. Testing gateway on port 8001..."
20+
if curl -s http://localhost:8001/health | grep -q "ok"; then
21+
echo " ✓ Gateway responding on 8001"
22+
else
23+
echo " ✗ Gateway not responding"
24+
25+
# Try to start it manually to see errors
26+
echo
27+
echo "3. Testing gateway manually..."
28+
timeout 5 /opt/gateway-venv/bin/python /opt/chat_gateway_mcp.py --http 8001 2>&1 | head -20
29+
fi
30+
31+
# 4. Check if the issue is with the proxy
32+
echo
33+
echo "4. Testing UI proxy..."
34+
# Replace the server.js with fixed version if needed
35+
if [ -f fix-gateway-proxy.js ]; then
36+
echo " Updating UI server with better proxy..."
37+
cp /opt/ui/server.js /opt/ui/server.js.bak
38+
cp fix-gateway-proxy.js /opt/ui/server.js
39+
supervisorctl restart responsive-ui
40+
sleep 2
41+
fi
42+
43+
# 5. Final test
44+
echo
45+
echo "5. Final connectivity test..."
46+
echo -n " Gateway direct: "
47+
curl -s http://localhost:8001/health | jq -r .status || echo "FAILED"
48+
49+
echo -n " Gateway via proxy: "
50+
curl -s -X POST http://localhost:8080/v1/chat/completions/test \
51+
-H "Content-Type: application/json" \
52+
-d '{"messages":[{"role":"user","content":"test"}]}' \
53+
| jq -r .status 2>/dev/null || echo "FAILED"
54+
55+
echo
56+
echo "=== Status ==="
57+
supervisorctl status | grep -E "chat-gateway|responsive-ui"
58+
59+
echo
60+
echo "If gateway still fails, check:"
61+
echo "1. Python venv: ls -la /opt/gateway-venv/bin/"
62+
echo "2. Gateway script: ls -la /opt/chat_gateway_mcp.py"
63+
echo "3. Import errors: /opt/gateway-venv/bin/python -c 'import mcp, httpx, pydantic, aiohttp'"

claude-home/test-gateway.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
# Test gateway connectivity
3+
4+
echo "=== Testing Gateway Connectivity ==="
5+
echo
6+
7+
# 1. Direct gateway test
8+
echo "1. Testing gateway directly on port 8001..."
9+
echo -n " Health check: "
10+
curl -s http://localhost:8001/health 2>/dev/null | jq . || echo "FAILED"
11+
12+
echo
13+
echo "2. Testing gateway through UI proxy on port 8080..."
14+
echo -n " Health check via proxy: "
15+
curl -s http://localhost:8080/v1/chat/completions/test \
16+
-H "Content-Type: application/json" \
17+
-d '{"messages":[{"role":"user","content":"test"}]}' 2>/dev/null | jq . || echo "FAILED"
18+
19+
echo
20+
echo "3. Checking if gateway is actually running..."
21+
ps aux | grep -E "chat_gateway_mcp|gateway-venv" | grep -v grep || echo " Gateway process not found!"
22+
23+
echo
24+
echo "4. Checking gateway logs..."
25+
echo " === Last 10 lines of gateway.log ==="
26+
tail -n 10 /var/log/gateway.log 2>/dev/null || echo " No log file"
27+
echo
28+
echo " === Last 10 lines of gateway.err ==="
29+
tail -n 10 /var/log/gateway.err 2>/dev/null || echo " No error log"
30+
31+
echo
32+
echo "5. Testing gateway port directly..."
33+
nc -zv localhost 8001 2>&1 || echo " Port 8001 not open"
34+
35+
echo
36+
echo "6. Checking supervisord status..."
37+
supervisorctl status chat-gateway
38+
39+
echo
40+
echo "=== Quick Fixes ==="
41+
echo "1. Restart gateway: supervisorctl restart chat-gateway"
42+
echo "2. Check python path: which python3"
43+
echo "3. Test gateway manually:"
44+
echo " /opt/gateway-venv/bin/python /opt/chat_gateway_mcp.py --http 8001"
45+
echo "4. Check if venv exists: ls -la /opt/gateway-venv/"

claude-home/ui/server-fixed.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Fixed server.js with better error handling and logging
2+
const http = require('http');
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
const PORT = 8080;
7+
8+
// Simple proxy function with better error handling
9+
function proxy(req, res, targetHost, targetPort, targetPath) {
10+
console.log(`Proxying ${req.url} to ${targetHost}:${targetPort}${targetPath}`);
11+
12+
const options = {
13+
hostname: targetHost,
14+
port: targetPort,
15+
path: targetPath || req.url,
16+
method: req.method,
17+
headers: {...req.headers, host: `${targetHost}:${targetPort}`}
18+
};
19+
20+
const proxyReq = http.request(options, (proxyRes) => {
21+
console.log(`Proxy response: ${proxyRes.statusCode}`);
22+
res.writeHead(proxyRes.statusCode, proxyRes.headers);
23+
proxyRes.pipe(res);
24+
});
25+
26+
proxyReq.on('error', (err) => {
27+
console.error(`Proxy error to ${targetHost}:${targetPort}:`, err.message);
28+
res.writeHead(502, {'Content-Type': 'application/json'});
29+
res.end(JSON.stringify({error: 'Gateway error', details: err.message}));
30+
});
31+
32+
req.pipe(proxyReq);
33+
}
34+
35+
const server = http.createServer((req, res) => {
36+
console.log(`Request: ${req.method} ${req.url}`);
37+
38+
// Add CORS headers for all responses
39+
res.setHeader('Access-Control-Allow-Origin', '*');
40+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
41+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
42+
43+
// Handle OPTIONS for CORS
44+
if (req.method === 'OPTIONS') {
45+
res.writeHead(200);
46+
res.end();
47+
return;
48+
}
49+
50+
// Route based on path
51+
if (req.url === '/' || req.url === '/index.html') {
52+
// Serve the main UI
53+
fs.readFile(path.join(__dirname, 'index.html'), (err, data) => {
54+
if (err) {
55+
console.error('Error reading index.html:', err);
56+
res.writeHead(500);
57+
res.end('Error loading page');
58+
return;
59+
}
60+
res.writeHead(200, {'Content-Type': 'text/html'});
61+
res.end(data);
62+
});
63+
} else if (req.url.startsWith('/chat')) {
64+
// Proxy to chat UI
65+
const targetPath = req.url.substring(5) || '/';
66+
proxy(req, res, 'localhost', 3000, targetPath);
67+
} else if (req.url.startsWith('/terminal')) {
68+
// Proxy to ttyd
69+
const targetPath = req.url.substring(9) || '/';
70+
proxy(req, res, 'localhost', 7681, targetPath);
71+
} else if (req.url.startsWith('/v1/')) {
72+
// Proxy to gateway API - THIS IS THE IMPORTANT ONE
73+
proxy(req, res, 'localhost', 8001, req.url);
74+
} else {
75+
res.writeHead(404);
76+
res.end(`Not found: ${req.url}`);
77+
}
78+
});
79+
80+
// Handle WebSocket upgrades
81+
server.on('upgrade', (req, socket, head) => {
82+
console.log(`WebSocket upgrade request: ${req.url}`);
83+
84+
if (req.url.startsWith('/terminal')) {
85+
// Proxy WebSocket to ttyd
86+
const net = require('net');
87+
const upstream = net.connect(7681, 'localhost');
88+
89+
upstream.on('connect', () => {
90+
console.log('Connected to ttyd WebSocket');
91+
const targetPath = req.url.substring(9) || '/';
92+
upstream.write(`GET ${targetPath} HTTP/1.1\r\n`);
93+
for (const [key, value] of Object.entries(req.headers)) {
94+
if (key.toLowerCase() !== 'host') {
95+
upstream.write(`${key}: ${value}\r\n`);
96+
}
97+
}
98+
upstream.write('Host: localhost:7681\r\n');
99+
upstream.write('\r\n');
100+
upstream.write(head);
101+
102+
socket.pipe(upstream);
103+
upstream.pipe(socket);
104+
});
105+
106+
upstream.on('error', (err) => {
107+
console.error('WebSocket upstream error:', err);
108+
socket.destroy();
109+
});
110+
111+
socket.on('error', (err) => {
112+
console.error('WebSocket socket error:', err);
113+
upstream.destroy();
114+
});
115+
} else {
116+
socket.destroy();
117+
}
118+
});
119+
120+
server.listen(PORT, '0.0.0.0', () => {
121+
console.log(`UI server running on port ${PORT}`);
122+
console.log('Routes:');
123+
console.log(' / -> UI (this server)');
124+
console.log(' /chat/* -> localhost:3000');
125+
console.log(' /terminal/* -> localhost:7681');
126+
console.log(' /v1/* -> localhost:8001 (Gateway API)');
127+
128+
// Test gateway connectivity on startup
129+
setTimeout(() => {
130+
const testReq = http.get('http://localhost:8001/health', (res) => {
131+
console.log(`Gateway health check: ${res.statusCode}`);
132+
});
133+
testReq.on('error', (err) => {
134+
console.error('Gateway not responding:', err.message);
135+
});
136+
}, 1000);
137+
});

0 commit comments

Comments
 (0)