165 lines
5.9 KiB
JavaScript
165 lines
5.9 KiB
JavaScript
#!/usr/bin/env node
|
||
'use strict';
|
||
|
||
/**
|
||
* AOAC-03 · 合体引擎 (Chain Fusion Engine)
|
||
* ═══════════════════════════════════════════════
|
||
* AGE OS Agent Chain · 全Agent(开发全链路感知)
|
||
*
|
||
* 唤醒条件:AOAC-02完成(CI日志+开发日志双全)
|
||
* 职责:合并两半日志→生成完整开发报告→写入触发信号
|
||
* 输出:data/aoac/chain-report.json + data/aoac/readme-sync-trigger.json
|
||
*
|
||
* 版权:国作登字-2026-A-00037559 · TCS-0002∞
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const ROOT = path.resolve(__dirname, '..', '..');
|
||
const DEV_LOG_PATH = path.join(ROOT, 'data', 'aoac', 'dev-session-log.json');
|
||
const MERGE_LOG_PATH = path.join(ROOT, 'data', 'aoac', 'merge-result-log.json');
|
||
const CHAIN_REPORT_PATH = path.join(ROOT, 'data', 'aoac', 'chain-report.json');
|
||
const TRIGGER_PATH = path.join(ROOT, 'data', 'aoac', 'readme-sync-trigger.json');
|
||
const CHAIN_STATUS_PATH = path.join(ROOT, 'data', 'aoac', 'chain-status.json');
|
||
const HISTORY_DIR = path.join(ROOT, 'data', 'aoac', 'history');
|
||
const BEIJING_OFFSET_MS = 8 * 3600 * 1000;
|
||
|
||
function getBeijingTime() {
|
||
const now = new Date();
|
||
return new Date(now.getTime() + BEIJING_OFFSET_MS)
|
||
.toISOString().replace('T', ' ').slice(0, 19) + '+08:00';
|
||
}
|
||
|
||
function getDateStr() {
|
||
const now = new Date();
|
||
return new Date(now.getTime() + BEIJING_OFFSET_MS)
|
||
.toISOString().slice(0, 10);
|
||
}
|
||
|
||
function readJSON(filePath) {
|
||
try {
|
||
if (!fs.existsSync(filePath)) return null;
|
||
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||
} catch { return null; }
|
||
}
|
||
|
||
function writeJSON(filePath, data) {
|
||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||
fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
||
}
|
||
|
||
function generateChangeSummary(devLog, mergeLog) {
|
||
const parts = [];
|
||
|
||
if (devLog && devLog.pr) {
|
||
parts.push(`PR #${devLog.pr.number}: ${devLog.pr.title}`);
|
||
}
|
||
|
||
if (devLog && devLog.diff) {
|
||
parts.push(`${devLog.diff.changed_files}个文件 (+${devLog.diff.additions} -${devLog.diff.deletions})`);
|
||
}
|
||
|
||
if (devLog && devLog.categories) {
|
||
const cats = Object.keys(devLog.categories);
|
||
if (cats.length > 0) {
|
||
parts.push(`涉及: ${cats.join(', ')}`);
|
||
}
|
||
}
|
||
|
||
if (mergeLog && mergeLog.ci) {
|
||
parts.push(`CI: ${mergeLog.ci.overall_result} (✅${mergeLog.ci.summary.passed} ❌${mergeLog.ci.summary.failed})`);
|
||
}
|
||
|
||
return parts.join(' · ');
|
||
}
|
||
|
||
function main() {
|
||
console.log('⚡ AOAC-03 · 合体引擎 · 唤醒中...');
|
||
console.log(`📅 ${getBeijingTime()}`);
|
||
|
||
const devLog = readJSON(DEV_LOG_PATH);
|
||
const mergeLog = readJSON(MERGE_LOG_PATH);
|
||
|
||
if (!devLog && !mergeLog) {
|
||
console.log('⚠️ 开发日志和合并日志都不存在,生成空报告');
|
||
}
|
||
|
||
const now = new Date();
|
||
const dateStr = getDateStr();
|
||
const seq = String(Math.floor(Math.random() * 1000)).padStart(3, '0');
|
||
const reportId = `AOAC-CHAIN-${dateStr.replace(/-/g, '')}-${seq}`;
|
||
|
||
// Fuse the two halves
|
||
const chainReport = {
|
||
aoac_agent: 'AOAC-03',
|
||
aoac_agent_name: 'dev-chain-agent',
|
||
report_id: reportId,
|
||
status: 'complete',
|
||
timestamp: getBeijingTime(),
|
||
timestamp_utc: now.toISOString(),
|
||
fusion: {
|
||
dev_sentinel: devLog ? 'present' : 'missing',
|
||
merge_sentinel: mergeLog ? 'present' : 'missing',
|
||
fusion_quality: devLog && mergeLog ? 'full' : 'partial'
|
||
},
|
||
development: {
|
||
pr_number: (devLog && devLog.pr && devLog.pr.number) || (mergeLog && mergeLog.merge && mergeLog.merge.pr_number) || null,
|
||
pr_title: (devLog && devLog.pr && devLog.pr.title) || (mergeLog && mergeLog.merge && mergeLog.merge.pr_title) || 'unknown',
|
||
author: (devLog && devLog.pr && devLog.pr.author) || '',
|
||
branch: (devLog && devLog.pr && devLog.pr.branch) || '',
|
||
files_changed: (devLog && devLog.diff && devLog.diff.changed_files) || 0,
|
||
additions: (devLog && devLog.diff && devLog.diff.additions) || 0,
|
||
deletions: (devLog && devLog.diff && devLog.diff.deletions) || 0,
|
||
categories: (devLog && devLog.categories) || {}
|
||
},
|
||
ci_result: {
|
||
overall: (mergeLog && mergeLog.ci && mergeLog.ci.overall_result) || 'unknown',
|
||
passed: (mergeLog && mergeLog.ci && mergeLog.ci.summary && mergeLog.ci.summary.passed) || 0,
|
||
failed: (mergeLog && mergeLog.ci && mergeLog.ci.summary && mergeLog.ci.summary.failed) || 0,
|
||
merge_commit: (mergeLog && mergeLog.merge && mergeLog.merge.merge_commit_sha) || ''
|
||
},
|
||
changes_summary: generateChangeSummary(devLog, mergeLog),
|
||
triggered_by: 'AOAC-02',
|
||
triggers_next: 'AOAC-04 (readme-sync-module)'
|
||
};
|
||
|
||
// Write chain report
|
||
writeJSON(CHAIN_REPORT_PATH, chainReport);
|
||
console.log(`✅ 链路报告已生成: ${reportId}`);
|
||
console.log(` ${chainReport.changes_summary}`);
|
||
|
||
// Write trigger signal for AOAC-04
|
||
const trigger = {
|
||
trigger_id: `AOAC-TRIGGER-${dateStr.replace(/-/g, '')}-${seq}`,
|
||
source: 'AOAC-03',
|
||
target: 'AOAC-04',
|
||
chain_report_id: reportId,
|
||
timestamp: now.toISOString(),
|
||
action: 'readme_sync'
|
||
};
|
||
writeJSON(TRIGGER_PATH, trigger);
|
||
console.log('📡 触发信号已发送 → AOAC-04');
|
||
|
||
// Archive to history
|
||
const historyDir = path.join(HISTORY_DIR, dateStr);
|
||
fs.mkdirSync(historyDir, { recursive: true });
|
||
writeJSON(path.join(historyDir, `${reportId}.json`), chainReport);
|
||
|
||
// Update chain status
|
||
const chainStatus = readJSON(CHAIN_STATUS_PATH) || {};
|
||
if (chainStatus.agents) {
|
||
if (chainStatus.agents['AOAC-03']) {
|
||
chainStatus.agents['AOAC-03'].status = 'completed';
|
||
chainStatus.agents['AOAC-03'].last_run = now.toISOString();
|
||
chainStatus.agents['AOAC-03'].last_success = now.toISOString();
|
||
}
|
||
chainStatus.chain_health = chainReport.ci_result.overall === 'success' ? 'healthy' : 'warning';
|
||
}
|
||
writeJSON(CHAIN_STATUS_PATH, chainStatus);
|
||
|
||
console.log('⚡ AOAC-03 · 合体完成 · 链路报告已归档');
|
||
}
|
||
|
||
main();
|