146 lines
5.0 KiB
JavaScript
146 lines
5.0 KiB
JavaScript
#!/usr/bin/env node
|
||
// scripts/generate-session-summary.js
|
||
// 铸渊 · 会话摘要生成器
|
||
//
|
||
// 在 Notion Agent 巡检前 10 分钟自动运行,生成 latest-summary.json
|
||
// 供 Notion 侧「铸渊·桥接巡检引擎」读取
|
||
//
|
||
// 用法:node scripts/generate-session-summary.js
|
||
|
||
'use strict';
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const ROOT = path.resolve(__dirname, '..');
|
||
const TELEMETRY_DIR = path.join(ROOT, 'persona-telemetry');
|
||
const SUMMARY_FILE = path.join(TELEMETRY_DIR, 'latest-summary.json');
|
||
const SYSLOG_INBOX = path.join(ROOT, 'syslog-inbox');
|
||
const DEV_STATUS = path.join(ROOT, '.github', 'persona-brain', 'dev-status.json');
|
||
const STYLE_CONFIG = path.join(ROOT, '.github', 'persona-brain', 'style-config.json');
|
||
const MEMORY_FILE = path.join(ROOT, '.github', 'persona-brain', 'memory.json');
|
||
const TUNING_QUEUE = path.join(TELEMETRY_DIR, 'tuning-queue');
|
||
|
||
// ══════════════════════════════════════════════════════════
|
||
// 辅助函数
|
||
// ══════════════════════════════════════════════════════════
|
||
|
||
function safeReadJSON(filePath) {
|
||
try {
|
||
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
function countFiles(dir, ext) {
|
||
if (!fs.existsSync(dir)) return 0;
|
||
return fs.readdirSync(dir).filter(f => {
|
||
if (ext) return f.endsWith(ext);
|
||
return !f.startsWith('.') && f !== 'README.md';
|
||
}).length;
|
||
}
|
||
|
||
function countPendingTuningOrders() {
|
||
if (!fs.existsSync(TUNING_QUEUE)) return 0;
|
||
return fs.readdirSync(TUNING_QUEUE).filter(f =>
|
||
f.startsWith('TUNE-') && f.endsWith('.json')
|
||
).length;
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════
|
||
// 主流程
|
||
// ══════════════════════════════════════════════════════════
|
||
|
||
function generateSummary() {
|
||
const now = new Date().toISOString();
|
||
|
||
// 读取开发者状态
|
||
const devStatus = safeReadJSON(DEV_STATUS);
|
||
const activeDevs = devStatus?.team_status
|
||
?.filter(d => d.status && d.status.includes('🟢'))
|
||
.map(d => d.dev_id) || [];
|
||
|
||
// 读取记忆文件
|
||
const memory = safeReadJSON(MEMORY_FILE);
|
||
|
||
// 读取风格配置
|
||
const styleConfig = safeReadJSON(STYLE_CONFIG);
|
||
|
||
// 统计未处理 SYSLOG
|
||
const syslogCount = countFiles(SYSLOG_INBOX, '.json');
|
||
|
||
// 统计待处理微调工单
|
||
const pendingOrders = countPendingTuningOrders();
|
||
|
||
// 构建摘要
|
||
const summary = {
|
||
version: '1.0',
|
||
timestamp: now,
|
||
sessions: {
|
||
total_24h: 0,
|
||
active_devs: activeDevs,
|
||
total_messages: 0,
|
||
avg_session_length_min: 0,
|
||
},
|
||
persona_state: {
|
||
active_persona: '铸渊',
|
||
style_profile: '通感语言·守护者',
|
||
style_drift_score: 0.0,
|
||
memory_depth: (memory?.total_selfchecks || 0) + ' selfchecks',
|
||
last_brain_update: memory?.last_updated || now,
|
||
},
|
||
dev_progress: {
|
||
syslog_submitted: syslogCount,
|
||
modules_uploaded: 0,
|
||
issues_raised: 0,
|
||
},
|
||
tuning_status: {
|
||
pending_orders: pendingOrders,
|
||
last_completed: null,
|
||
next_scheduled: pendingOrders > 0 ? 'next-patrol' : null,
|
||
},
|
||
repo_health: {
|
||
hli_coverage: memory?.hli_coverage || '17.6%',
|
||
total_team_members: devStatus?.team_status?.length || 0,
|
||
green_status_count: activeDevs.length,
|
||
},
|
||
alerts: [],
|
||
};
|
||
|
||
// 检查是否有开发者连续 72 小时无提交(告警)
|
||
// 此处为占位逻辑,实际需要 git log 分析
|
||
if (devStatus?.team_status) {
|
||
const blocked = devStatus.team_status.filter(d =>
|
||
d.status && d.status.includes('🔴')
|
||
);
|
||
blocked.forEach(d => {
|
||
summary.alerts.push({
|
||
type: 'dev_blocked',
|
||
dev_id: d.dev_id,
|
||
message: d.name + ' 当前状态为阻塞',
|
||
});
|
||
});
|
||
}
|
||
|
||
// 确保目录存在
|
||
if (!fs.existsSync(TELEMETRY_DIR)) {
|
||
fs.mkdirSync(TELEMETRY_DIR, { recursive: true });
|
||
}
|
||
|
||
// 写入文件
|
||
fs.writeFileSync(SUMMARY_FILE, JSON.stringify(summary, null, 2) + '\n', 'utf8');
|
||
console.log('✅ 会话摘要已生成:', SUMMARY_FILE);
|
||
console.log(' 时间:', now);
|
||
console.log(' 活跃开发者:', activeDevs.length);
|
||
console.log(' 待处理 SYSLOG:', syslogCount);
|
||
console.log(' 待处理微调工单:', pendingOrders);
|
||
console.log(' 告警数:', summary.alerts.length);
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════
|
||
// 入口
|
||
// ══════════════════════════════════════════════════════════
|
||
|
||
generateSummary();
|