Replaces the problematic file:// protocol Config.html with a stable
Node.js HTTP server following industry standard patterns (n8n, Langflow).
Changes:
- Add portable/config-server/ with REST API (GET/POST /api/config)
- Add simplified Chinese/English web UI for AI model and QQ Bot config
- Update Windows-Start.bat to launch both services simultaneously
- Config Center on port 18788
- OpenClaw Gateway on port 18789
- Remove Config.html file:// protocol issues
- Use zero-dependency pure Node.js standard library
Benefits:
- No file:// CORS or WebSocket issues
- Industry-standard localhost HTTP pattern
- Simplified configuration interface for Chinese users
- Unified startup experience
🤖 Generated with Claude Code
83 lines
2.5 KiB
JavaScript
83 lines
2.5 KiB
JavaScript
#!/usr/bin/env node
|
|
const http = require('http');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const PORT = 18788;
|
|
const CONFIG_PATH = path.join(__dirname, '../data/.openclaw/openclaw.json');
|
|
|
|
const server = http.createServer((req, res) => {
|
|
// CORS headers
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
|
|
if (req.method === 'OPTIONS') {
|
|
res.writeHead(200);
|
|
res.end();
|
|
return;
|
|
}
|
|
|
|
// API: Get config
|
|
if (req.url === '/api/config' && req.method === 'GET') {
|
|
try {
|
|
const config = fs.existsSync(CONFIG_PATH)
|
|
? JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'))
|
|
: {};
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify(config));
|
|
} catch (err) {
|
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: err.message }));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// API: Save config
|
|
if (req.url === '/api/config' && req.method === 'POST') {
|
|
let body = '';
|
|
req.on('data', chunk => body += chunk);
|
|
req.on('end', () => {
|
|
try {
|
|
const config = JSON.parse(body);
|
|
const dir = path.dirname(CONFIG_PATH);
|
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ ok: true }));
|
|
} catch (err) {
|
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: err.message }));
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Serve static files
|
|
const filePath = req.url === '/'
|
|
? path.join(__dirname, 'public/index.html')
|
|
: path.join(__dirname, 'public', req.url);
|
|
|
|
if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
|
|
const ext = path.extname(filePath);
|
|
const contentType = {
|
|
'.html': 'text/html',
|
|
'.css': 'text/css',
|
|
'.js': 'application/javascript',
|
|
'.json': 'application/json'
|
|
}[ext] || 'text/plain';
|
|
|
|
res.writeHead(200, { 'Content-Type': contentType });
|
|
fs.createReadStream(filePath).pipe(res);
|
|
} else {
|
|
res.writeHead(404);
|
|
res.end('Not Found');
|
|
}
|
|
});
|
|
|
|
server.listen(PORT, '127.0.0.1', () => {
|
|
console.log(`\n🦞 U-Claw Config Center`);
|
|
console.log(` http://127.0.0.1:${PORT}`);
|
|
console.log(`\n Config file: ${CONFIG_PATH}\n`);
|
|
});
|