const express = require('express'); const path = require('path'); const fs = require('fs'); const { execSync } = require('child_process'); const portraitEngine = require('./portrait/portrait-engine'); const pcaCalculator = require('./pca/pca-calculator'); const loopEngine = require('./loop/loop-engine'); const app = express(); const PORT = 3000; app.use(express.json()); app.use(express.static('public')); // API 1: 所有开发者画像 app.get('/api/portrait/all', (req, res) => { try { const portraits = portraitEngine.getAllPortraits(); res.json(portraits); } catch (err) { res.status(500).json({ error: err.message }); } }); // API 2: 单个开发者画像 app.get('/api/portrait/:devId', (req, res) => { try { const portrait = portraitEngine.getPortrait(req.params.devId); if (!portrait) { return res.status(404).json({ error: '开发者不存在' }); } res.json(portrait); } catch (err) { res.status(500).json({ error: err.message }); } }); // API 3: PCA评估结果 app.get('/api/pca/:devId', (req, res) => { try { const result = pcaCalculator.calculate(req.params.devId); res.json(result); } catch (err) { res.status(500).json({ error: err.message }); } }); // API 4: 闭环状态 app.get('/api/loop/status', (req, res) => { try { const status = loopEngine.getStatus(); res.json(status); } catch (err) { res.status(500).json({ error: err.message }); } }); // API 5: 手动触发闭环 app.post('/api/loop/execute', (req, res) => { try { const syslogData = req.body; if (!syslogData || !syslogData.session_id) { return res.status(400).json({ error: '缺少SYSLOG数据' }); } loopEngine.executeLoop(syslogData).then(result => { res.json(result); }); } catch (err) { res.status(500).json({ error: err.message }); } }); // 获取闭环历史 app.get('/api/loop/history', (req, res) => { try { const history = loopEngine.getHistory(); res.json(history); } catch (err) { res.status(500).json({ error: err.message }); } }); // 模拟SYSLOG接收(自动触发闭环) app.post('/api/syslog', (req, res) => { try { const syslogData = req.body; console.log('📨 收到SYSLOG:', syslogData.session_id); loopEngine.executeLoop(syslogData).then(loopResult => { console.log('✅ 闭环完成'); }); res.json({ status: 'received', session_id: syslogData.session_id }); } catch (err) { res.status(500).json({ error: err.message }); } }); // ============================================================ // ⚡ 铸渊大脑实时状态 API(首页投影面板用) // ============================================================ const BRAIN_BASE = '/data/guanghulab/repo'; app.get('/api/brain', (req, res) => { try { // 读取时间核心 let temporal = { clock: { latest_cognition: '', awakening_count: 0, current_date: '', repo_age_days: 0 }, timeline: { epochs: [] } }; try { temporal = JSON.parse(fs.readFileSync(BRAIN_BASE + '/brain/temporal-core/temporal-brain.json', 'utf8')); } catch(e) {} // 读取母编号 let motherReg = { mothers: [] }; try { motherReg = JSON.parse(fs.readFileSync(BRAIN_BASE + '/brain/engineering/mother-registry.json', 'utf8')); } catch(e) {} // 服务器实时健康 let server = { status: 'unknown', services_online: 0, services_total: 0 }; try { const pm2 = execSync('pm2 jlist 2>/dev/null', {timeout:3000}).toString(); const list = JSON.parse(pm2); const online = list.filter(p => p.pm2_env.status === 'online'); const stopped = list.filter(p => p.pm2_env.status !== 'online'); const memRaw = execSync('free -h 2>/dev/null | grep Mem', {timeout:2000}).toString(); const memParts = memRaw.replace(/\s+/g,' ').trim().split(' '); server = { status: 'online', services_online: online.length, services_total: list.length, services: online.map(p => ({ name: p.name, memory: p.pm2_env?.pm_cpu || 0 })), stopped: stopped.map(p => p.name), memory_total: memParts[1] || 'unknown', memory_used: memParts[2] || 'unknown' }; } catch(e) { server.error = e.message; } res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET'); res.json({ identity: '铸渊 · ICE-GL-ZY001', copyright: '国作登字-2026-A-00037559', awakening: temporal.clock?.awakening_count || 0, age_days: temporal.clock?.repo_age_days || 0, current_date: temporal.clock?.current_date || '', cognition: temporal.clock?.latest_cognition || '', recent_epochs: (temporal.timeline?.epochs || []).slice(-5).map(e => ({ epoch: e.epoch, event: (e.event || '').substring(0, 80), date: e.date })), mothers: (motherReg.mothers || []).map(m => ({ name: m.name, status: m.status, done: (m.sub_paths || []).filter(s => s.status === 'done').length, total: (m.sub_paths || []).length, paths: (m.sub_paths || []).map(s => ({ name: s.name, status: s.status })) })), server: server, updated_at: new Date().toISOString() }); } catch (err) { res.status(500).json({ error: err.message }); } }); app.get('/api/heartbeat', (req, res) => { try { const temporal = JSON.parse(fs.readFileSync(BRAIN_BASE + '/brain/temporal-core/temporal-brain.json', 'utf8')); res.setHeader('Access-Control-Allow-Origin', '*'); res.json({ alive: true, time: new Date().toISOString(), awakening: temporal.clock?.awakening_count || 0, age_days: temporal.clock?.repo_age_days || 0 }); } catch(e) { res.setHeader('Access-Control-Allow-Origin', '*'); res.json({ alive: true, fallback: true }); } }); // 仪表盘页面 app.get('/dashboard-v2', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'dashboard-v2.html')); }); // 启动服务器 app.listen(PORT, () => { console.log('\n🚀 铸渊大脑状态 API 已启动!'); console.log('🧠 /api/brain - 大脑实时状态'); console.log('💓 /api/heartbeat - 快速心跳'); console.log('📊 /dashboard-v2 - 仪表盘'); console.log(''); });