guanghulab/skyeye/hibernation/readme-status-updater.js
2026-05-10 13:12:44 +08:00

252 lines
7.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* skyeye/hibernation/readme-status-updater.js
* ═══════════════════════════════════════════════
* 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001
* 📜 Copyright: 国作登字-2026-A-00037559
* ═══════════════════════════════════════════════
*
* 📢 README 状态区自动更新
* 在 README.md 的 SKYEYE-STATUS-BEGIN/END 标记区域内
* 根据休眠阶段动态更新系统状态。
*
* 用法:
* node readme-status-updater.js --phase=pre-announce --mode=daily --duration=12
* node readme-status-updater.js --phase=hibernating --mode=daily
* node readme-status-updater.js --phase=resumed --mode=daily
* node readme-status-updater.js --phase=pre-announce --mode=weekly --hours=3 --minutes=40
* node readme-status-updater.js --phase=hibernating --mode=weekly --step=A1
* node readme-status-updater.js --phase=resumed --mode=weekly
* node readme-status-updater.js --phase=normal
*/
'use strict';
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
const README_PATH = path.join(ROOT, 'README.md');
const MARKER_START = '<!-- SKYEYE-STATUS-BEGIN -->';
const MARKER_END = '<!-- SKYEYE-STATUS-END -->';
// ━━━ 工具函数 ━━━
function getBeijingDate() {
return new Date().toLocaleDateString('zh-CN', { timeZone: 'Asia/Shanghai' });
}
function getBeijingTime() {
return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
}
function getBeijingHHMM() {
const d = new Date();
const h = String(d.getUTCHours() + 8).padStart(2, '0'); // approximate CST
const m = String(d.getUTCMinutes()).padStart(2, '0');
return `${h}:${m}`;
}
function parseArgs() {
const args = process.argv.slice(2);
const result = {};
for (const arg of args) {
if (arg.startsWith('--')) {
const [key, value] = arg.slice(2).split('=');
result[key] = value || 'true';
}
}
return result;
}
// ━━━ 状态模板生成 ━━━
function generateNormalStatus() {
const date = getBeijingDate();
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| 🟢 系统状态 | 正常运转 |',
'| 🛡️ Guard 集群 | 5/5 在线 |',
`| ⏰ 上次日休眠 | ${date} · ✅ 正常 |`,
`| 📅 下次日休眠 | 明日 ~04:00天眼动态决定|`,
`| 📅 下次周休眠 | 本周六 ~20:00天眼动态决定|`
].join('\n');
}
function generateDailyPreAnnounce(duration) {
const date = getBeijingDate();
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| 🌙 系统状态 | ⏳ 即将进入日休眠 |',
`| ⏰ 预计开始 | ${date} 04:00 |`,
`| ⏱️ 预计时长 | 约 ${duration} 分钟 |`,
'| 📊 天眼评估 | 今日系统负载评估完成 |',
'| ⚠️ 注意 | 休眠期间基础心跳维持,紧急通道不受影响 |'
].join('\n');
}
function generateDailyHibernating(step) {
const date = getBeijingDate();
const stepMap = {
'check': '轻量自查',
'optimize': '微调优',
'archive': '归档'
};
const currentStep = stepMap[step] || '轻量自查';
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| 🌙 系统状态 | ⏸️ 日休眠中 |',
`| ⏰ 开始时间 | ${date} 04:00 |`,
`| 🔍 当前阶段 | ${currentStep} |`,
'| ⏱️ 预计恢复 | ~04:15 |'
].join('\n');
}
function generateDailyResumed() {
const date = getBeijingDate();
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| 🟢 系统状态 | ✅ 已从日休眠恢复 |',
`| ⏰ 休眠时段 | ${date} 04:00 完成 |`,
'| 📋 成果 | 自查 ✅ · 微调优 ✅ · 归档 ✅ |',
`| 📄 报告 | daily-checkpoint-${new Date().toISOString().slice(0, 10).replace(/-/g, '')}.json |`
].join('\n');
}
function generateWeeklyPreAnnounce(hours, minutes) {
const date = getBeijingDate();
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| ⭐ 系统状态 | ⏳ 即将进入本周完全休眠 |',
`| ⏰ 预计开始 | ${date} 20:00 |`,
`| ⏱️ 预计时长 | 约 ${hours} 小时 ${minutes} 分钟(天眼评估)|`,
'| 📊 天眼评估 | 本周变动评估完成 |',
'| ⚠️ 注意 | 休眠期间所有 workflow 完全暂停,仅 P0 告警通道保持畅通 |'
].join('\n');
}
function generateWeeklyHibernating(step) {
const stepMap = {
'A1': 'Phase A1 · 全局快照',
'A2': 'Phase A2 · 经验提炼',
'A3': 'Phase A3 · 全局修复+升级',
'A4': 'Phase A4 · 打包 Notion 升级包',
'A5': 'Phase A5 · 分发小兵升级',
'B': 'Phase B · Notion 端级联升级'
};
const currentStep = stepMap[step] || `Phase ${step}`;
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| ⭐ 系统状态 | ⏸️ 本周完全休眠中 |',
`| 🔍 当前阶段 | ${currentStep} |`,
`| ⏱️ 开始时间 | ${getBeijingDate()} 20:00 |`
].join('\n');
}
function generateWeeklyResumed() {
const date = getBeijingDate();
return [
'## 🌍 系统运行状态',
'',
'| 指标 | 状态 |',
'|------|------|',
'| 🟢 系统状态 | ✅ 已从本周完全休眠恢复 |',
`| ⏰ 休眠时段 | ${date} 完成 |`,
'| 📋 成果 | |',
'|  ├ GitHub 端 | Guard 巡检 ✅ · 升级包生成 ✅ |',
'|  ├ Notion 端 | 级联升级 ✅ |',
`|  └ 升级包 | upgrade-pack-${new Date().toISOString().slice(0, 10).replace(/-/g, '')}.json |`,
'| 📄 详情 | 周度升级报告已写入系统演进日志 |'
].join('\n');
}
// ━━━ README 更新 ━━━
function updateREADME(content) {
if (!fs.existsSync(README_PATH)) {
console.log('❌ README.md 不存在');
return false;
}
let readme = fs.readFileSync(README_PATH, 'utf8');
const startIdx = readme.indexOf(MARKER_START);
const endIdx = readme.indexOf(MARKER_END);
if (startIdx === -1 || endIdx === -1) {
console.log('⚠️ README.md 中未找到 SKYEYE-STATUS 标记,跳过更新');
return false;
}
const before = readme.slice(0, startIdx + MARKER_START.length);
const after = readme.slice(endIdx);
readme = before + '\n' + content + '\n' + after;
fs.writeFileSync(README_PATH, readme, 'utf8');
console.log('✅ README 状态区已更新');
return true;
}
// ━━━ 主流程 ━━━
function run() {
const args = parseArgs();
const phase = args.phase || 'normal';
const mode = args.mode || 'daily';
const duration = args.duration || '12';
const hours = args.hours || '3';
const minutes = args.minutes || '0';
const step = args.step || '';
console.log(`[README Status Updater] Phase: ${phase}, Mode: ${mode}`);
let content;
if (phase === 'normal') {
content = generateNormalStatus();
} else if (phase === 'pre-announce' && mode === 'daily') {
content = generateDailyPreAnnounce(duration);
} else if (phase === 'hibernating' && mode === 'daily') {
content = generateDailyHibernating(step);
} else if (phase === 'resumed' && mode === 'daily') {
content = generateDailyResumed();
} else if (phase === 'pre-announce' && mode === 'weekly') {
content = generateWeeklyPreAnnounce(hours, minutes);
} else if (phase === 'hibernating' && mode === 'weekly') {
content = generateWeeklyHibernating(step);
} else if (phase === 'resumed' && mode === 'weekly') {
content = generateWeeklyResumed();
} else {
content = generateNormalStatus();
}
const updated = updateREADME(content);
return { updated, phase, mode };
}
module.exports = { updateREADME, run };
if (require.main === module) {
run();
}