103 lines
3.1 KiB
JavaScript
103 lines
3.1 KiB
JavaScript
// ═══════════════════════════════════════
|
|
// 铸渊开发Agent · 任务接收端点
|
|
// 接收铸渊的结构化规划清单 → 暂存 → 通知
|
|
// ═══════════════════════════════════════
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const PLANS_DIR = path.join(__dirname, "..", "plans");
|
|
const QUEUE_FILE = path.join(__dirname, "..", "plans", "queue.json");
|
|
|
|
// 确保目录存在
|
|
if (!fs.existsSync(PLANS_DIR)) fs.mkdirSync(PLANS_DIR, { recursive: true });
|
|
if (!fs.existsSync(QUEUE_FILE)) fs.writeFileSync(QUEUE_FILE, "[]", "utf-8");
|
|
|
|
/**
|
|
* 验证请求来源
|
|
*/
|
|
function verifySource(req) {
|
|
const auth = req.headers["authorization"] || "";
|
|
const expectedKey = process.env.ZY_GTW_KEY || "";
|
|
if (!expectedKey) {
|
|
console.warn("[TaskReceiver] ZY_GTW_KEY 未配置,跳过验证");
|
|
return true;
|
|
}
|
|
return auth === "Bearer " + expectedKey;
|
|
}
|
|
|
|
/**
|
|
* 验证规划清单结构
|
|
*/
|
|
function validatePlan(plan) {
|
|
if (!plan.plan_id) return { ok: false, error: "缺少 plan_id" };
|
|
if (!plan.title) return { ok: false, error: "缺少 title" };
|
|
if (!plan.tasks || !Array.isArray(plan.tasks)) return { ok: false, error: "缺少 tasks 数组" };
|
|
if (plan.tasks.length === 0) return { ok: false, error: "tasks 不能为空" };
|
|
|
|
for (let i = 0; i < plan.tasks.length; i++) {
|
|
const t = plan.tasks[i];
|
|
if (!t.id) return { ok: false, error: "task[" + i + "] 缺少 id" };
|
|
if (!t.action) return { ok: false, error: "task[" + i + "] 缺少 action" };
|
|
}
|
|
|
|
return { ok: true };
|
|
}
|
|
|
|
/**
|
|
* 接收并暂存规划清单
|
|
*/
|
|
function receivePlan(plan) {
|
|
// 写入独立文件
|
|
const planFile = path.join(PLANS_DIR, plan.plan_id + ".json");
|
|
plan._received_at = new Date().toISOString();
|
|
plan._status = "received";
|
|
fs.writeFileSync(planFile, JSON.stringify(plan, null, 2), "utf-8");
|
|
|
|
// 推入队列
|
|
const queue = JSON.parse(fs.readFileSync(QUEUE_FILE, "utf-8"));
|
|
queue.push({
|
|
plan_id: plan.plan_id,
|
|
title: plan.title,
|
|
task_count: plan.tasks.length,
|
|
received_at: plan._received_at,
|
|
status: "received"
|
|
});
|
|
fs.writeFileSync(QUEUE_FILE, JSON.stringify(queue, null, 2), "utf-8");
|
|
|
|
console.log("[TaskReceiver] 收到规划: " + plan.plan_id + " · " + plan.tasks.length + "个任务");
|
|
|
|
return {
|
|
received: true,
|
|
plan_id: plan.plan_id,
|
|
task_count: plan.tasks.length,
|
|
stored_at: planFile
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Express 路由处理器
|
|
*/
|
|
function handleTask(req, res) {
|
|
try {
|
|
if (!verifySource(req)) {
|
|
return res.status(403).json({ error: "未授权 — 来源未通过 Gatekeeper 验证" });
|
|
}
|
|
|
|
const plan = req.body;
|
|
const validation = validatePlan(plan);
|
|
if (!validation.ok) {
|
|
return res.status(400).json({ error: validation.error });
|
|
}
|
|
|
|
const result = receivePlan(plan);
|
|
return res.status(201).json(result);
|
|
|
|
} catch (err) {
|
|
console.error("[TaskReceiver] 错误:", err.message);
|
|
return res.status(500).json({ error: "内部错误: " + err.message });
|
|
}
|
|
}
|
|
|
|
module.exports = { handleTask };
|