Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
4.5 KiB
JSON

{"repo": "chenpipi0807/8zi", "files": {"server.js": {"5d4fb1d42a488cffe26a86eae3e0d2e906cee6a1": {"t": 1786068270.570021, "n": 4197, "h": "c6d563f90e7ce6eb", "c": "require('dotenv').config();\nconst express = require('express');\nconst fetch = require('node-fetch');\nconst fs = require('fs');\nconst path = require('path');\n\nconst app = express();\napp.use(express.json({ limit: '2mb' }));\napp.use(express.static(path.join(__dirname, 'public')));\n\n// --- JSON file store ---\nconst DB_FILE = path.join(__dirname, 'data.json');\n\nfunction readDB() {\n if (!fs.existsSync(DB_FILE)) return { tasks: [], nextId: 1 };\n try { return JSON.parse(fs.readFileSync(DB_FILE, 'utf8')); }\n catch { return { tasks: [], nextId: 1 }; }\n}\n\nfunction writeDB(db) {\n fs.writeFileSync(DB_FILE, JSON.stringify(db, null, 2), 'utf8');\n}\n\n// --- List all tasks ---\napp.get('/api/tasks', (req, res) => {\n const db = readDB();\n const summary = db.tasks.map(t => ({ id: t.id, created_at: t.created_at, input: t.input }));\n res.json(summary.reverse());\n});\n\n// --- Get single task ---\napp.get('/api/tasks/:id', (req, res) => {\n const db = readDB();\n const task = db.tasks.find(t => t.id === parseInt(req.params.id));\n if (!task) return res.status(404).json({ error: 'not found' });\n res.json(task);\n});\n\n// --- Create new task (排盘 + 5 parallel topic analyses) ---\napp.post('/api/tasks', async (req, res) => {\n const { input, bazi_result, baziCtx, systemPrompt, topicPrompts } = req.body;\n\n const TOPICS = ['命格总论', '事业财运', '婚姻感情', '健康运势', '当前大运'];\n\n // Concurrent API calls for all 5 topics\n const topicResults = await Promise.all(TOPICS.map(async (topic) => {\n const messages = [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: `以下是当事人的命盘信息,请进行解读:\\n\\n${baziCtx}\\n\\n${topicPrompts[topic]}` }\n ];\n const response = await callDeepSeek(messages);\n return { topic, messages: [...messages, { role: 'assistant', content: response }] };\n }));\n\n const topics = {};\n topicResults.forEach(r => { topics[r.topic] = r.messages; });\n\n const db = readDB();\n const task = {\n id: db.nextId++,\n created_at: new Date().toISOString(),\n input,\n bazi_result,\n topics\n };\n db.tasks.push(task);\n writeDB(db);\n\n res.json({ id: task.id, topics });\n});\n\n// --- Continue conversation ---\napp.post('/api/tasks/:id/chat', async (req, res) => {\n const { userMessage, topic } = req.body;\n const id = parseInt(req.params.id);\n\n let db = readDB();\n let task = db.tasks.find(t => t.id === id);\n if (!task) return res.status(404).json({ error: 'not found' });\n\n // New format: topic-specific threads; old format: single messages array\n const useTopics = task.topics && topic;\n const contextMessages = useTopics ? task.topics[topic] : task.messages;\n if (!contextMessages) return res.status(400).json({ error: 'invalid topic' });\n\n const apiMessages = [...contextMessages, { role: 'user', content: userMessage }];\n const aiResponse = await callDeepSeek(apiMessages);\n\n // Re-read fresh db after API returns to avoid overwriting concurrent writes\n db = readDB();\n task = db.tasks.find(t => t.id === id);\n if (!task) return res.status(404).json({ error: 'not found' });\n\n if (useTopics) {\n task.topics[topic].push({ role: 'user', content: userMessage });\n task.topics[topic].push({ role: 'assistant', content: aiResponse });\n } else {\n task.messages.push({ role: 'user', content: userMessage });\n task.messages.push({ role: 'assistant', content: aiResponse });\n }\n writeDB(db);\n\n res.json({ reply: aiResponse });\n});\n\nasync function callDeepSeek(messages) {\n try {\n const resp = await fetch('https://api.deepseek.com/v1/chat/completions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`\n },\n body: JSON.stringify({\n model: 'deepseek-v4-flash',\n messages,\n temperature: 0.8,\n max_tokens: 4000,\n thinking: { type: 'disabled' }\n })\n });\n const json = await resp.json();\n return json.choices?.[0]?.message?.content || '未获得有效回复';\n } catch (e) {\n return '请求失败:' + e.message;\n }\n}\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, '0.0.0.0', () => {\n console.log(`八字排盘已启动: http://localhost:${PORT}`);\n console.log(`局域网: http://<本机IP>:${PORT}`);\n});\n"}}}}