Merge pull request #96 from qinfendebingshuo/copilot/tcs-0002-system-upgrade

feat: 执行层系统升级 v5.1 + Notion Execution Status 同步
This commit is contained in:
冰朔 2026-03-14 15:12:19 +08:00 committed by GitHub
commit 1d54f00230
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 2031 additions and 7 deletions

View File

@ -142,3 +142,89 @@ jobs:
}]
}" 2>&1 | tail -1
echo "✅ Notion 回报请求已发送"
# ── 同步执行层状态到 Notion Execution Status 数据库 ──
sync-execution-status-to-notion:
name: 同步执行层状态到 Notion
needs: maintenance
runs-on: ubuntu-latest
if: ${{ !cancelled() }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
- name: Read brain data and sync to Notion
env:
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
run: |
if [ -z "$NOTION_TOKEN" ]; then
echo "⚠️ NOTION_TOKEN 未配置,跳过 Execution Status 同步"
exit 0
fi
HEALTH=$(cat brain/system-health.json 2>/dev/null)
if [ -z "$HEALTH" ]; then
echo "⚠️ brain/system-health.json 未找到,使用默认值"
HEALTH='{"version":"unknown","system_health":"unknown"}'
fi
AUTO=$(cat brain/automation-map.json 2>/dev/null)
if [ -z "$AUTO" ]; then
echo "⚠️ brain/automation-map.json 未找到,使用默认值"
AUTO='{"workflows":[]}'
fi
REPO=$(cat brain/repo-map.json 2>/dev/null)
if [ -z "$REPO" ]; then
echo "⚠️ brain/repo-map.json 未找到,使用默认值"
REPO='{"directories":{}}'
fi
VERSION=$(echo "$HEALTH" | jq -r '.version // "unknown"')
STATUS=$(echo "$HEALTH" | jq -r '.system_health // "unknown"')
WF_COUNT=$(echo "$AUTO" | jq '[.workflows // [] | length] | .[0]' 2>/dev/null || echo '0')
CRON_COUNT=$(echo "$AUTO" | jq '[.workflows // [] | .[] | select(.cron)] | length' 2>/dev/null || echo '0')
DIR_COUNT=$(echo "$REPO" | jq '.directories // {} | keys | length' 2>/dev/null || echo '0')
case "$STATUS" in
normal) AUTO_S="🟢 Normal"; QUEUE_S="🟢 Active" ;;
partial) AUTO_S="🟡 Partial"; QUEUE_S="🟡 Backlog" ;;
*) AUTO_S="🔴 Down"; QUEUE_S="🔴 Blocked" ;;
esac
SYNC_DATE=$(date -u +%Y%m%d)
SYNC_TS=$(date -u +%Y-%m-%dT%H:%M:%S+00:00)
echo "📡 同步 Execution Status → Notion..."
echo " 版本: v${VERSION} · ${DIR_COUNT}+ dirs"
echo " 模块: ${WF_COUNT} workflow · ${CRON_COUNT} cron"
echo " 状态: ${AUTO_S}"
HTTP_CODE=$(curl -s -o /tmp/notion_resp.json -w "%{http_code}" \
-X POST 'https://api.notion.com/v1/pages' \
-H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" \
-H "Content-Type: application/json" \
-d "{
\"parent\": { \"database_id\": \"41971982-4a17-47c0-afe3-21458c44f154\" },
\"properties\": {
\"同步记录\": { \"title\": [{ \"text\": { \"content\": \"SYNC-${SYNC_DATE}-001\" } }] },
\"同步时间\": { \"date\": { \"start\": \"${SYNC_TS}\" } },
\"仓库版本\": { \"rich_text\": [{ \"text\": { \"content\": \"v${VERSION} · ${DIR_COUNT}+ dirs\" } }] },
\"执行模块\": { \"rich_text\": [{ \"text\": { \"content\": \"${WF_COUNT} workflow · ${CRON_COUNT} cron\" } }] },
\"自动化状态\": { \"select\": { \"name\": \"${AUTO_S}\" } },
\"Notion连接状态\": { \"select\": { \"name\": \"🟢 Connected\" } },
\"任务队列状态\": { \"select\": { \"name\": \"${QUEUE_S}\" } },
\"同步来源\": { \"select\": { \"name\": \"铸渊自动同步\" } },
\"备注\": { \"rich_text\": [{ \"text\": { \"content\": \"Daily Maintenance auto sync\" } }] }
}
}")
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then
echo "✅ Execution Status synced to Notion (HTTP ${HTTP_CODE})"
else
echo "❌ Sync failed (HTTP ${HTTP_CODE})"
cat /tmp/notion_resp.json 2>/dev/null || true
exit 1
fi

57
.github/workflows/execution-sync.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: "📡 铸渊 · 执行层状态同步"
on:
schedule:
- cron: '0 3 * * *' # 每日 UTC 03:00 (北京时间 11:00)
workflow_dispatch:
permissions:
contents: write
jobs:
execution-sync:
name: 执行层状态采集与同步
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
# ── Step 1: 加载执行上下文 ──
- name: 加载执行上下文
run: node core/context-loader
# ── Step 2: 运行系统自检 ──
- name: 运行系统自检
run: node core/system-check --auto-tasks
# ── Step 3: 生成执行状态报告 ──
- name: 生成执行状态报告
run: node core/execution-sync report
# ── Step 4: 同步到 Notion ──
- name: 同步执行状态到 Notion
if: ${{ env.NOTION_TOKEN != '' }}
env:
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
EXECUTION_LOG_DB_ID: ${{ secrets.EXECUTION_LOG_DB_ID }}
run: node core/execution-sync sync
# ── Step 5: 提交状态报告 ──
- name: 提交状态报告
run: |
git config user.name "铸渊 Execution Sync"
git config user.email "actions@guanghulab.com"
git add docs/execution-status.md
if git diff --cached --quiet; then
echo "📌 无变更需要提交"
else
git commit -m "📡 Execution Sync: 更新执行状态报告 [skip ci]"
git push
echo "✅ 已提交执行状态报告"
fi

5
.gitignore vendored
View File

@ -19,3 +19,8 @@ modules/palace-game/data/saves/PAL-*
# collaboration-logs exports (generated by save-collaboration-log.js)
collaboration-logs/exports/
# core runtime artifacts
core/task-queue/queue.json
core/task-queue/execution-log.json
core/system-check/last-report.json

View File

@ -1,12 +1,12 @@
# 铸渊执行层 · 系统导航主文件
# Master Brain · v4.0
# 数字地球系统通信协议 v4.0
# Master Brain · v5.1
# 数字地球系统通信协议 v5.1 — AGE-5 自动开发循环升级
---
## 系统版本
**v4.0** — 数字地球系统通信协议
**v5.1** — 数字地球系统通信协议 · 自动开发循环升级
---
@ -60,6 +60,24 @@
---
## v5.1 执行层模块
| 入口 | 路径 | 说明 |
|------|------|------|
| 上下文加载 | `core/context-loader/index.js` | 执行前系统上下文加载 |
| 广播监听 | `core/broadcast-listener/index.js` | 广播监听与任务解析 |
| 任务队列 | `core/task-queue/index.js` | 任务调度与执行(含类型分类) |
| 系统自检 | `core/system-check/index.js` | 仓库自检 + 自动任务生成 |
| 执行同步 | `core/execution-sync/index.js` | 执行层状态同步 |
| Notion 同步 | `connectors/notion-sync/index.js` | 双向数据同步 |
| 模型路由 | `connectors/model-router/index.js` | 模型调用路由 |
| 结构地图 | `docs/repo-structure-map.md` | 仓库结构文档 |
| 桥接地图 | `docs/notion-bridge-map.md` | Notion 桥接文档 |
| 执行层地图 | `docs/execution-layer-map.md` | 执行层结构文档 |
| 执行状态 | `docs/execution-status.md` | 执行层状态报告(自动生成) |
---
## 铸渊职责
铸渊 = GitHub 侧守护人格体 = 执行层守护者
@ -71,6 +89,7 @@
5. **巡检维护** — 每日自动巡检系统健康状态
6. **信号处理** — 处理 SYSLOG、广播、开发者工单
7. **状态上报** — 向 Notion认知层报告执行结果
8. **自动开发循环** — 自检发现问题后自动生成修复/优化任务
---
@ -87,4 +106,4 @@
---
*本文件由铸渊维护 · 系统版本 4.0 · 数字地球系统通信协议*
*本文件由铸渊维护 · 系统版本 5.1 · 数字地球系统通信协议 · AGE-5*

View File

@ -1,16 +1,33 @@
{
"version": "4.0",
"version": "5.1",
"last_check": "2026-03-14 03:38:09+08:00",
"communication": "synced",
"automation": "stable",
"maintenance_agent": "active",
"system_health": "normal",
"execution_layer_status": "stable",
"notion_bridge": "active",
"execution_sync": "enabled",
"auto_dev_loop": "enabled",
"context_loader": "active",
"task_queue": "running",
"brain_integrity": {
"complete": true,
"total": 7,
"present": 7,
"missing": []
},
"workflow_count": 42,
"core_modules": {
"broadcast_listener": "enabled",
"task_queue": "enabled",
"system_check": "enabled",
"execution_sync": "enabled",
"context_loader": "enabled"
},
"connectors": {
"notion_sync": "enabled",
"model_router": "enabled"
},
"workflow_count": 43,
"checked_by": "scripts/generate-system-health.js"
}

View File

@ -0,0 +1,80 @@
/**
* connectors/model-router 模型调用路由
*
* 职责
* - 提供统一的模型调用入口
* - 支持多模型切换通过 backend-integration/api-proxy.js
* - 任务分发至合适的模型端点
*
* 调用方式
* node connectors/model-router [status]
*/
const path = require('path');
const fs = require('fs');
const ROOT = path.resolve(__dirname, '../..');
/**
* 模型配置注册表
*/
const MODEL_REGISTRY = {
'default': {
name: 'default',
endpoint: 'http://localhost:3721/api/chat',
description: 'AI Chat API 代理api-proxy.js'
},
'persona': {
name: 'persona',
endpoint: 'http://localhost:3002/api/ps/chat',
description: '人格工作室 API'
}
};
/**
* 获取模型配置
*/
function getModel(modelName = 'default') {
return MODEL_REGISTRY[modelName] || MODEL_REGISTRY['default'];
}
/**
* 列出所有可用模型
*/
function listModels() {
return Object.values(MODEL_REGISTRY);
}
/**
* 检查模型路由状态
*/
function status() {
console.log('🤖 模型路由状态:');
console.log('═'.repeat(40));
const models = listModels();
for (const model of models) {
console.log(` 📌 ${model.name}`);
console.log(` 端点: ${model.endpoint}`);
console.log(` 说明: ${model.description}`);
}
// 检查 api-proxy 配置
const proxyPath = path.join(ROOT, 'backend-integration/api-proxy.js');
const proxyExists = fs.existsSync(proxyPath);
console.log(`\n ${proxyExists ? '✅' : '❌'} api-proxy.js 存在`);
// 检查 persona-studio 配置
const psPath = path.join(ROOT, 'persona-studio/backend/server.js');
const psExists = fs.existsSync(psPath);
console.log(` ${psExists ? '✅' : '❌'} persona-studio server.js 存在`);
return { models, proxy: proxyExists, persona_studio: psExists };
}
// CLI 入口
if (require.main === module) {
status();
}
module.exports = { getModel, listModels, status, MODEL_REGISTRY };

View File

@ -0,0 +1,264 @@
/**
* connectors/notion-sync Notion 双向同步模块
*
* 功能
* - 读取 Notion 广播
* - 写回执行日志
* - 同步执行层状态
*
* 同步结构
* Notion 仓库下行读取广播/工单
* 仓库 Notion上行写回日志/状态
*
* 环境变量
* NOTION_TOKEN Notion API Token
* BROADCAST_DB_ID 广播数据库 ID需包含 status 属性: 待执行/已完成
* EXECUTION_LOG_DB_ID 执行日志数据库 ID
*
* 调用方式
* node connectors/notion-sync [pull|push|status]
*/
const https = require('https');
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
const NOTION_VERSION = '2022-06-28';
/**
* 发送 Notion API 请求
*/
function notionRequest(method, endpoint, body = null) {
const token = process.env.NOTION_TOKEN;
if (!token) {
return Promise.reject(new Error('NOTION_TOKEN 环境变量未设置'));
}
return new Promise((resolve, reject) => {
const options = {
hostname: 'api.notion.com',
path: `/v1/${endpoint}`,
method,
headers: {
'Authorization': `Bearer ${token}`,
'Notion-Version': NOTION_VERSION,
'Content-Type': 'application/json'
}
};
const req = https.request(options, res => {
let data = '';
res.on('data', chunk => { data += chunk; });
res.on('end', () => {
try {
const parsed = JSON.parse(data);
if (res.statusCode >= 400) {
reject(new Error(`Notion API ${res.statusCode}: ${parsed.message || data}`));
} else {
resolve(parsed);
}
} catch {
reject(new Error(`Notion 响应解析失败: ${data}`));
}
});
});
req.on('error', reject);
if (body) req.write(JSON.stringify(body));
req.end();
});
}
/**
* Notion 拉取广播
*/
async function pullBroadcasts() {
const dbId = process.env.BROADCAST_DB_ID;
if (!dbId) {
console.log('⚠️ BROADCAST_DB_ID 未设置,跳过广播拉取');
return [];
}
console.log('📡 拉取 Notion 广播...');
try {
const result = await notionRequest('POST', `databases/${dbId}/query`, {
filter: {
property: 'status',
select: { equals: '待执行' }
},
sorts: [{ property: 'created_time', direction: 'descending' }]
});
const broadcasts = (result.results || []).map(page => ({
id: page.id,
title: page.properties?.Name?.title?.[0]?.plain_text || '未命名',
status: page.properties?.status?.select?.name || 'unknown',
created: page.created_time
}));
console.log(`✅ 拉取到 ${broadcasts.length} 条广播`);
return broadcasts;
} catch (err) {
console.error(`❌ 广播拉取失败: ${err.message}`);
return [];
}
}
/**
* 写回执行日志到 Notion
*/
async function pushExecutionLog(logEntry) {
const dbId = process.env.EXECUTION_LOG_DB_ID;
if (!dbId) {
console.log('⚠️ EXECUTION_LOG_DB_ID 未设置,执行日志仅写入本地');
return writeLocalLog(logEntry);
}
console.log(`📝 写回执行日志: ${logEntry.task_id || 'unknown'}`);
try {
await notionRequest('POST', 'pages', {
parent: { database_id: dbId },
properties: {
Name: { title: [{ text: { content: logEntry.task_id || 'execution-log' } }] },
Status: { select: { name: logEntry.status || 'completed' } },
Executor: { rich_text: [{ text: { content: 'zhuyuan' } }] },
Timestamp: { rich_text: [{ text: { content: new Date().toISOString() } }] }
}
});
console.log('✅ 日志已同步到 Notion');
} catch (err) {
console.error(`⚠️ Notion 写入失败,回退本地: ${err.message}`);
writeLocalLog(logEntry);
}
}
/**
* 本地日志写入回退方案
*/
function writeLocalLog(logEntry) {
const logDir = path.join(ROOT, 'core/task-queue');
const logFile = path.join(logDir, 'execution-log.json');
let logs = [];
if (fs.existsSync(logFile)) {
try {
logs = JSON.parse(fs.readFileSync(logFile, 'utf-8'));
} catch {
logs = [];
}
}
logs.push({
...logEntry,
logged_at: new Date().toISOString()
});
// 保留最近 100 条
if (logs.length > 100) {
logs = logs.slice(-100);
}
fs.writeFileSync(logFile, JSON.stringify(logs, null, 2), 'utf-8');
console.log('📝 日志已写入本地');
}
/**
* 同步执行层状态到 Notion
*/
async function syncExecutionStatus(statusData) {
const dbId = process.env.EXECUTION_LOG_DB_ID;
if (!dbId) {
console.log('⚠️ EXECUTION_LOG_DB_ID 未设置,执行状态仅写入本地');
writeLocalLog({
task_id: `execution-status-${new Date().toISOString().slice(0, 10)}`,
status: statusData.execution_layer_status || 'stable',
type: 'execution_status',
data: statusData
});
return;
}
console.log('📡 同步执行层状态到 Notion...');
const summary = [
`version: v${statusData.version || 'unknown'}`,
`modules: ${(statusData.core_modules || []).filter(m => m.status === 'enabled').length}/${(statusData.core_modules || []).length}`,
`connectors: ${(statusData.connectors || []).filter(c => c.status === 'enabled').length}/${(statusData.connectors || []).length}`,
`workflows: ${statusData.workflows?.count || 0}`,
`queue: ${statusData.task_queue?.total || 0} total / ${statusData.task_queue?.pending || 0} pending`
].join(' | ');
try {
await notionRequest('POST', 'pages', {
parent: { database_id: dbId },
properties: {
Name: { title: [{ text: { content: `Execution Status · ${new Date().toISOString().slice(0, 10)}` } }] },
Status: { select: { name: statusData.execution_layer_status || 'stable' } },
Executor: { rich_text: [{ text: { content: 'zhuyuan' } }] },
Timestamp: { rich_text: [{ text: { content: statusData.timestamp || new Date().toISOString() } }] }
},
children: [{
object: 'block',
type: 'paragraph',
paragraph: {
rich_text: [{ text: { content: summary } }]
}
}]
});
console.log('✅ 执行层状态已同步到 Notion');
} catch (err) {
console.error(`⚠️ Notion 同步失败,回退本地: ${err.message}`);
writeLocalLog({
task_id: `execution-status-${new Date().toISOString().slice(0, 10)}`,
status: statusData.execution_layer_status || 'stable',
type: 'execution_status',
data: statusData
});
}
}
/**
* 检查 Notion 连接状态
*/
async function checkStatus() {
console.log('🔍 检查 Notion 连接状态...');
try {
await notionRequest('GET', 'users/me');
console.log('✅ Notion API 连接正常');
return { connected: true };
} catch (err) {
console.error(`❌ Notion 连接失败: ${err.message}`);
return { connected: false, error: err.message };
}
}
// CLI 入口
if (require.main === module) {
const cmd = process.argv[2] || 'status';
(async () => {
switch (cmd) {
case 'pull':
await pullBroadcasts();
break;
case 'push':
await pushExecutionLog({
task_id: 'manual-test',
status: 'completed',
message: 'Manual push test'
});
break;
case 'status':
await checkStatus();
break;
default:
console.log('用法: node connectors/notion-sync [pull|push|status]');
}
})();
}
module.exports = { pullBroadcasts, pushExecutionLog, syncExecutionStatus, writeLocalLog, checkStatus, notionRequest };

View File

@ -0,0 +1,160 @@
/**
* core/broadcast-listener 广播监听模块
*
* 职责
* - 监听 Notion 广播通过 connectors/notion-sync
* - 解析广播内容为可执行任务
* - 推入任务队列core/task-queue
*
* 数据流
* Notion 广播 broadcast-listener 任务解析 task-queue
*
* 调用方式
* node core/broadcast-listener [--source notion|local]
*/
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
const BROADCASTS_DIR = path.join(ROOT, '.github/broadcasts');
const MEMORY_PATH = path.join(ROOT, 'memory.json');
/**
* 扫描本地广播目录
*/
function scanLocalBroadcasts() {
if (!fs.existsSync(BROADCASTS_DIR)) {
console.log('⏭️ 广播目录不存在,跳过本地扫描');
return [];
}
const files = fs.readdirSync(BROADCASTS_DIR).filter(
f => f.endsWith('.json') || f.endsWith('.md')
);
return files.map(f => {
const filePath = path.join(BROADCASTS_DIR, f);
const content = fs.readFileSync(filePath, 'utf-8');
const isJson = f.endsWith('.json');
let parsed = null;
if (isJson) {
try {
parsed = JSON.parse(content);
} catch {
console.warn(`⚠️ JSON 解析失败: ${f}`);
}
}
return {
filename: f,
type: isJson ? 'json' : 'markdown',
path: filePath,
data: parsed,
raw: content,
timestamp: new Date().toISOString()
};
});
}
/**
* 将广播解析为任务结构
*/
function parseToTask(broadcast) {
const task = {
task_id: `TASK-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
source: 'broadcast',
source_file: broadcast.filename,
priority: 'normal',
status: 'pending',
executor: 'zhuyuan',
created_at: broadcast.timestamp,
payload: null
};
if (broadcast.type === 'json' && broadcast.data) {
task.payload = broadcast.data;
if (broadcast.data.priority) {
task.priority = broadcast.data.priority;
}
if (broadcast.data.broadcast_id) {
task.task_id = broadcast.data.broadcast_id;
}
} else {
task.payload = { content: broadcast.raw };
}
return task;
}
/**
* 检查广播是否已在 memory 中处理
*/
function isDuplicate(broadcastId) {
if (!fs.existsSync(MEMORY_PATH)) return false;
try {
const memory = JSON.parse(fs.readFileSync(MEMORY_PATH, 'utf-8'));
const events = memory.events || [];
return events.some(e =>
e.broadcast_id === broadcastId ||
(e.type === 'broadcast' && e.description === broadcastId)
);
} catch {
return false;
}
}
/**
* 主执行函数监听并解析广播
*/
function listen(options = {}) {
const source = options.source || 'local';
console.log(`📡 广播监听启动 [来源: ${source}]`);
if (source === 'local') {
const broadcasts = scanLocalBroadcasts();
if (broadcasts.length === 0) {
console.log('✅ 无待处理广播');
return [];
}
console.log(`📬 发现 ${broadcasts.length} 条广播`);
const tasks = [];
for (const b of broadcasts) {
const taskId = b.data?.broadcast_id || b.filename;
if (isDuplicate(taskId)) {
console.log(`⏭️ 跳过已处理: ${taskId}`);
continue;
}
const task = parseToTask(b);
tasks.push(task);
console.log(`📋 解析任务: ${task.task_id} [${task.priority}]`);
}
console.log(`✅ 共生成 ${tasks.length} 个待执行任务`);
return tasks;
}
console.log('⚠️ Notion 源需通过 connectors/notion-sync 接入');
return [];
}
// CLI 入口
if (require.main === module) {
const args = process.argv.slice(2);
const source = args.includes('--source') ?
args[args.indexOf('--source') + 1] : 'local';
const tasks = listen({ source });
if (tasks.length > 0) {
console.log('\n📋 任务列表:');
tasks.forEach(t => {
console.log(` ${t.task_id} | ${t.priority} | ${t.status}`);
});
}
}
module.exports = { listen, scanLocalBroadcasts, parseToTask, isDuplicate };

View File

@ -0,0 +1,166 @@
/**
* core/context-loader 上下文加载器
*
* 职责
* - 在执行任务前加载系统上下文
* - 提供系统状态执行层结构当前任务任务来源等信息
*
* 加载内容
* - 系统状态brain/system-health.json
* - 执行层结构core/ 模块状态
* - 当前任务队列
* - 任务来源标识
*
* 执行流程
* context-loader 加载系统认知 加载任务上下文 返回上下文对象
*
* 调用方式
* node core/context-loader
*/
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
/**
* 加载系统状态
*/
function loadSystemHealth() {
const healthPath = path.join(ROOT, 'brain/system-health.json');
if (!fs.existsSync(healthPath)) return null;
try {
return JSON.parse(fs.readFileSync(healthPath, 'utf-8'));
} catch {
return null;
}
}
/**
* 加载执行层模块结构
*/
function loadModuleStructure() {
const modules = [
{ name: 'broadcast-listener', path: 'core/broadcast-listener/index.js' },
{ name: 'task-queue', path: 'core/task-queue/index.js' },
{ name: 'system-check', path: 'core/system-check/index.js' },
{ name: 'execution-sync', path: 'core/execution-sync/index.js' },
{ name: 'context-loader', path: 'core/context-loader/index.js' }
];
const connectors = [
{ name: 'notion-sync', path: 'connectors/notion-sync/index.js' },
{ name: 'model-router', path: 'connectors/model-router/index.js' }
];
return {
core: modules.map(m => ({
...m,
status: fs.existsSync(path.join(ROOT, m.path)) ? 'active' : 'missing'
})),
connectors: connectors.map(c => ({
...c,
status: fs.existsSync(path.join(ROOT, c.path)) ? 'active' : 'missing'
}))
};
}
/**
* 加载当前任务队列概况
*/
function loadQueueSummary() {
const queuePath = path.join(ROOT, 'core/task-queue/queue.json');
if (!fs.existsSync(queuePath)) {
return { total: 0, pending: 0, running: 0 };
}
try {
const queue = JSON.parse(fs.readFileSync(queuePath, 'utf-8'));
const tasks = queue.tasks || [];
return {
total: tasks.length,
pending: tasks.filter(t => t.status === 'pending').length,
running: tasks.filter(t => t.status === 'running').length
};
} catch {
return { total: 0, pending: 0, running: 0 };
}
}
/**
* 加载铸渊身份认知
*/
function loadIdentity() {
return {
name: '铸渊',
role: '仓库执行人格体',
responsibilities: [
'执行系统广播任务',
'维护执行层结构',
'同步执行状态',
'运行自动化流程',
'自动开发循环'
],
principles: [
'Notion 负责系统认知',
'仓库负责执行与运行',
'不修改主脑规则',
'不改变编号体系',
'不破坏现有自动化'
]
};
}
/**
* 加载完整系统上下文
*/
function loadContext() {
const now = new Date();
const beijingTime = new Date(now.getTime() + 8 * 60 * 60 * 1000)
.toISOString().replace('T', ' ').slice(0, 19) + '+08:00';
const context = {
loaded_at: beijingTime,
identity: loadIdentity(),
system_health: loadSystemHealth(),
module_structure: loadModuleStructure(),
queue_summary: loadQueueSummary()
};
return context;
}
// CLI 入口
if (require.main === module) {
console.log('🧠 铸渊上下文加载器 v5.1');
console.log('═'.repeat(40));
const ctx = loadContext();
console.log(`\n⏰ 加载时间: ${ctx.loaded_at}`);
console.log(`\n👤 身份: ${ctx.identity.name}${ctx.identity.role}`);
const health = ctx.system_health;
if (health) {
console.log(`\n💚 系统版本: v${health.version}`);
console.log(` 状态: ${health.system_health}`);
console.log(` 执行层: ${health.execution_layer_status}`);
} else {
console.log('\n⚠ 系统状态未加载');
}
const mods = ctx.module_structure;
const activeCore = mods.core.filter(m => m.status === 'active').length;
const activeConn = mods.connectors.filter(c => c.status === 'active').length;
console.log(`\n🔧 核心模块: ${activeCore}/${mods.core.length}`);
console.log(`🔌 连接器: ${activeConn}/${mods.connectors.length}`);
const q = ctx.queue_summary;
console.log(`\n📋 任务队列: ${q.total} 总 / ${q.pending} 待处理 / ${q.running} 执行中`);
console.log('\n✅ 上下文加载完成');
}
module.exports = { loadContext, loadSystemHealth, loadModuleStructure, loadQueueSummary, loadIdentity };

View File

@ -0,0 +1,266 @@
/**
* core/execution-sync 执行层状态同步模块
*
* 职责
* - 扫描仓库结构采集执行层状态
* - 生成执行层状态报告docs/execution-status.md
* - 同步执行状态到 Notion 主脑
*
* 执行逻辑
* 扫描仓库 生成状态报告 同步到 Notion
*
* 调用方式
* node core/execution-sync [report|sync|status]
*/
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
/**
* 采集核心模块状态
*/
function collectCoreModules() {
const modules = [
{ name: 'broadcast-listener', path: 'core/broadcast-listener/index.js' },
{ name: 'task-queue', path: 'core/task-queue/index.js' },
{ name: 'system-check', path: 'core/system-check/index.js' },
{ name: 'execution-sync', path: 'core/execution-sync/index.js' },
{ name: 'context-loader', path: 'core/context-loader/index.js' }
];
return modules.map(m => ({
...m,
status: fs.existsSync(path.join(ROOT, m.path)) ? 'enabled' : 'missing'
}));
}
/**
* 采集连接器状态
*/
function collectConnectors() {
const connectors = [
{ name: 'notion-sync', path: 'connectors/notion-sync/index.js' },
{ name: 'model-router', path: 'connectors/model-router/index.js' }
];
return connectors.map(c => ({
...c,
status: fs.existsSync(path.join(ROOT, c.path)) ? 'enabled' : 'missing'
}));
}
/**
* 采集自动化工作流状态
*/
function collectWorkflows() {
const workflowDir = path.join(ROOT, '.github/workflows');
if (!fs.existsSync(workflowDir)) return { count: 0, files: [] };
const files = fs.readdirSync(workflowDir).filter(
f => f.endsWith('.yml') || f.endsWith('.yaml')
);
return { count: files.length, files };
}
/**
* 采集任务队列状态
*/
function collectQueueStatus() {
const queuePath = path.join(ROOT, 'core/task-queue/queue.json');
if (!fs.existsSync(queuePath)) {
return { total: 0, pending: 0, running: 0, completed: 0, failed: 0 };
}
try {
const queue = JSON.parse(fs.readFileSync(queuePath, 'utf-8'));
const tasks = queue.tasks || [];
return {
total: tasks.length,
pending: tasks.filter(t => t.status === 'pending').length,
running: tasks.filter(t => t.status === 'running').length,
completed: tasks.filter(t => t.status === 'completed').length,
failed: tasks.filter(t => t.status === 'failed').length
};
} catch {
return { total: 0, pending: 0, running: 0, completed: 0, failed: 0 };
}
}
/**
* 读取系统版本
*/
function getSystemVersion() {
const healthPath = path.join(ROOT, 'brain/system-health.json');
if (!fs.existsSync(healthPath)) return 'unknown';
try {
const health = JSON.parse(fs.readFileSync(healthPath, 'utf-8'));
return health.version || 'unknown';
} catch {
return 'unknown';
}
}
/**
* 生成完整的执行层状态快照
*/
function collectStatus() {
const now = new Date();
const beijingTime = new Date(now.getTime() + 8 * 60 * 60 * 1000)
.toISOString().replace('T', ' ').slice(0, 19) + '+08:00';
return {
timestamp: beijingTime,
version: getSystemVersion(),
core_modules: collectCoreModules(),
connectors: collectConnectors(),
workflows: collectWorkflows(),
task_queue: collectQueueStatus(),
execution_layer_status: 'stable',
notion_bridge: 'active',
execution_sync: 'enabled'
};
}
/**
* 生成 Markdown 状态报告
*/
function generateReport(statusData) {
const s = statusData || collectStatus();
const coreTable = s.core_modules.map(m =>
`| ${m.name} | \`${m.path}\` | ${m.status === 'enabled' ? '✅ Enabled' : '❌ Missing'} |`
).join('\n');
const connTable = s.connectors.map(c =>
`| ${c.name} | \`${c.path}\` | ${c.status === 'enabled' ? '✅ Enabled' : '❌ Missing'} |`
).join('\n');
const q = s.task_queue;
const md = `# 执行层状态报告 — execution-status.md
> 铸渊执行层自动生成 · TCS-0002
> 更新时间${s.timestamp}
---
## 系统概览
| 指标 | 状态 |
|------|------|
| 系统版本 | v${s.version} |
| 执行层状态 | ${s.execution_layer_status === 'stable' ? '✅ Stable' : '⚠️ ' + s.execution_layer_status} |
| Notion 桥接 | ${s.notion_bridge === 'active' ? '✅ Active' : '❌ Inactive'} |
| 执行同步 | ${s.execution_sync === 'enabled' ? '✅ Enabled' : '❌ Disabled'} |
| 工作流数量 | ${s.workflows.count} |
---
## 核心模块状态
| 模块 | 路径 | 状态 |
|------|------|------|
${coreTable}
---
## 连接器状态
| 连接器 | 路径 | 状态 |
|--------|------|------|
${connTable}
---
## 任务队列状态
| 指标 | 数量 |
|------|------|
| 总计 | ${q.total} |
| 待处理 | ${q.pending} |
| 执行中 | ${q.running} |
| 已完成 | ${q.completed} |
| 失败 | ${q.failed} |
---
## 执行闭环
\`\`\`
context-loader system-check execution-sync 状态报告
broadcast-listener task-queue 任务执行
notion-sync Notion 主脑更新
\`\`\`
`;
return md;
}
/**
* 写入状态报告文件
*/
function writeReport() {
const statusData = collectStatus();
const md = generateReport(statusData);
const reportPath = path.join(ROOT, 'docs/execution-status.md');
fs.writeFileSync(reportPath, md, 'utf-8');
console.log(`📝 执行状态报告已生成: docs/execution-status.md`);
return statusData;
}
/**
* 同步执行状态到 Notion
*/
async function syncToNotion(statusData) {
let notionSync;
try {
notionSync = require('../../connectors/notion-sync');
} catch {
console.log('⚠️ connectors/notion-sync 模块未找到,跳过 Notion 同步');
return;
}
console.log('📡 同步执行状态到 Notion...');
await notionSync.syncExecutionStatus(statusData);
}
// CLI 入口
if (require.main === module) {
const cmd = process.argv[2] || 'report';
switch (cmd) {
case 'report': {
writeReport();
break;
}
case 'sync': {
const statusData = writeReport();
syncToNotion(statusData).catch(err => {
console.error(`❌ Notion 同步失败: ${err.message}`);
});
break;
}
case 'status': {
const s = collectStatus();
console.log('📊 执行层状态:');
console.log(` 版本: v${s.version}`);
console.log(` 执行层: ${s.execution_layer_status}`);
console.log(` Notion 桥接: ${s.notion_bridge}`);
console.log(` 执行同步: ${s.execution_sync}`);
console.log(` 核心模块: ${s.core_modules.filter(m => m.status === 'enabled').length}/${s.core_modules.length}`);
console.log(` 连接器: ${s.connectors.filter(c => c.status === 'enabled').length}/${s.connectors.length}`);
console.log(` 工作流: ${s.workflows.count}`);
console.log(` 任务队列: ${s.task_queue.total} 总 / ${s.task_queue.pending} 待处理`);
break;
}
default:
console.log('用法: node core/execution-sync [report|sync|status]');
}
}
module.exports = { collectStatus, generateReport, writeReport, syncToNotion };

331
core/system-check/index.js Normal file
View File

@ -0,0 +1,331 @@
/**
* core/system-check 仓库自检系统
*
* 功能
* - 扫描仓库结构完整性
* - 检查自动化工作流状态
* - 检测配置错误
* - 更新系统索引
*
* 执行周期daily cron通过 daily-maintenance 工作流触发
*
* 调用方式
* node core/system-check
*/
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
/**
* 必需目录列表
*/
const REQUIRED_DIRS = [
'brain',
'src',
'scripts',
'core/broadcast-listener',
'core/task-queue',
'core/system-check',
'core/execution-sync',
'core/context-loader',
'connectors/notion-sync',
'connectors/model-router',
'.github/workflows',
'docs'
];
/**
* 必需文件列表
*/
const REQUIRED_FILES = [
'brain/master-brain.md',
'brain/read-order.md',
'brain/repo-map.json',
'brain/system-health.json',
'brain/id-map.json',
'package.json',
'ecosystem.config.js',
'docs/repo-structure-map.md',
'docs/notion-bridge-map.md'
];
/**
* 检查目录是否存在
*/
function checkDirectories() {
console.log('\n📂 目录结构检查:');
const results = [];
for (const dir of REQUIRED_DIRS) {
const fullPath = path.join(ROOT, dir);
const exists = fs.existsSync(fullPath);
const icon = exists ? '✅' : '❌';
console.log(` ${icon} ${dir}`);
results.push({ path: dir, exists, type: 'directory' });
}
return results;
}
/**
* 检查必需文件
*/
function checkFiles() {
console.log('\n📄 必需文件检查:');
const results = [];
for (const file of REQUIRED_FILES) {
const fullPath = path.join(ROOT, file);
const exists = fs.existsSync(fullPath);
const icon = exists ? '✅' : '❌';
console.log(` ${icon} ${file}`);
results.push({ path: file, exists, type: 'file' });
}
return results;
}
/**
* 检查工作流数量
*/
function checkWorkflows() {
console.log('\n⚙ 工作流检查:');
const workflowDir = path.join(ROOT, '.github/workflows');
if (!fs.existsSync(workflowDir)) {
console.log(' ❌ 工作流目录不存在');
return { count: 0, files: [] };
}
const files = fs.readdirSync(workflowDir).filter(f => f.endsWith('.yml') || f.endsWith('.yaml'));
console.log(` ✅ 发现 ${files.length} 个工作流文件`);
return { count: files.length, files };
}
/**
* 检查核心模块状态
*/
function checkCoreModules() {
console.log('\n🔧 核心模块检查:');
const modules = [
{ name: 'broadcast-listener', path: 'core/broadcast-listener/index.js' },
{ name: 'task-queue', path: 'core/task-queue/index.js' },
{ name: 'system-check', path: 'core/system-check/index.js' },
{ name: 'execution-sync', path: 'core/execution-sync/index.js' },
{ name: 'context-loader', path: 'core/context-loader/index.js' },
{ name: 'notion-sync', path: 'connectors/notion-sync/index.js' },
{ name: 'model-router', path: 'connectors/model-router/index.js' }
];
const results = [];
for (const mod of modules) {
const fullPath = path.join(ROOT, mod.path);
const exists = fs.existsSync(fullPath);
const icon = exists ? '✅' : '❌';
console.log(` ${icon} ${mod.name}${mod.path}`);
results.push({ ...mod, exists });
}
return results;
}
/**
* 检查 JSON 文件完整性
*/
function checkJsonIntegrity() {
console.log('\n🔍 JSON 完整性检查:');
const jsonFiles = [
'brain/repo-map.json',
'brain/system-health.json',
'brain/id-map.json',
'package.json'
];
const results = [];
for (const file of jsonFiles) {
const fullPath = path.join(ROOT, file);
if (!fs.existsSync(fullPath)) {
console.log(` ⏭️ ${file} — 文件不存在`);
results.push({ path: file, valid: false, reason: 'missing' });
continue;
}
try {
JSON.parse(fs.readFileSync(fullPath, 'utf-8'));
console.log(`${file}`);
results.push({ path: file, valid: true });
} catch (e) {
console.log(`${file} — JSON 解析错误`);
results.push({ path: file, valid: false, reason: 'parse_error' });
}
}
return results;
}
/**
* 生成自检报告
*/
function generateReport(dirResults, fileResults, workflows, modules, jsonResults) {
const totalChecks = dirResults.length + fileResults.length + modules.length + jsonResults.length;
const passed = [
...dirResults.filter(r => r.exists),
...fileResults.filter(r => r.exists),
...modules.filter(r => r.exists),
...jsonResults.filter(r => r.valid)
].length;
const report = {
version: '5.1',
checked_at: new Date().toISOString(),
summary: {
total_checks: totalChecks,
passed: passed,
failed: totalChecks - passed,
health_score: Math.round((passed / totalChecks) * 100)
},
workflows: {
count: workflows.count
},
directories: dirResults,
files: fileResults,
modules: modules,
json_integrity: jsonResults
};
return report;
}
/**
* 根据自检结果生成自动任务
*/
function generateAutoTasks(report) {
const tasks = [];
const timestamp = new Date().toISOString();
// 检查目录缺失 → 生成修复任务
const missingDirs = (report.directories || []).filter(d => !d.exists);
for (const dir of missingDirs) {
tasks.push({
task_id: `auto-fix-dir-${dir.path.replace(/\//g, '-')}-${timestamp.slice(0, 10)}`,
type: 'auto-task',
source: 'system-check',
priority: 'high',
status: 'pending',
executor: 'zhuyuan',
description: `修复缺失目录: ${dir.path}`
});
}
// 检查文件缺失 → 生成修复任务
const missingFiles = (report.files || []).filter(f => !f.exists);
for (const file of missingFiles) {
tasks.push({
task_id: `auto-fix-file-${file.path.replace(/\//g, '-')}-${timestamp.slice(0, 10)}`,
type: 'auto-task',
source: 'system-check',
priority: 'high',
status: 'pending',
executor: 'zhuyuan',
description: `修复缺失文件: ${file.path}`
});
}
// 检查模块缺失 → 生成修复任务
const missingModules = (report.modules || []).filter(m => !m.exists);
for (const mod of missingModules) {
tasks.push({
task_id: `auto-fix-module-${mod.name}-${timestamp.slice(0, 10)}`,
type: 'auto-task',
source: 'system-check',
priority: 'normal',
status: 'pending',
executor: 'zhuyuan',
description: `修复缺失模块: ${mod.name}`
});
}
// JSON 完整性失败 → 生成修复任务
const invalidJson = (report.json_integrity || []).filter(j => !j.valid);
for (const json of invalidJson) {
tasks.push({
task_id: `auto-fix-json-${json.path.replace(/\//g, '-')}-${timestamp.slice(0, 10)}`,
type: 'auto-task',
source: 'system-check',
priority: 'high',
status: 'pending',
executor: 'zhuyuan',
description: `修复 JSON 文件: ${json.path} (${json.reason})`
});
}
// 健康分数低 → 生成结构优化任务
if (report.summary && report.summary.health_score < 100) {
tasks.push({
task_id: `auto-optimize-structure-${timestamp.slice(0, 10)}`,
type: 'maintenance-task',
source: 'system-check',
priority: 'low',
status: 'pending',
executor: 'zhuyuan',
description: `结构优化: 健康分数 ${report.summary.health_score}%`
});
}
return tasks;
}
/**
* 主执行函数
*/
function run() {
console.log('🏥 铸渊仓库自检系统 v5.1');
console.log('═'.repeat(40));
const dirResults = checkDirectories();
const fileResults = checkFiles();
const workflows = checkWorkflows();
const modules = checkCoreModules();
const jsonResults = checkJsonIntegrity();
const report = generateReport(dirResults, fileResults, workflows, modules, jsonResults);
console.log('\n═'.repeat(40));
console.log(`📊 自检报告: ${report.summary.passed}/${report.summary.total_checks} 通过 (${report.summary.health_score}%)`);
if (report.summary.failed > 0) {
console.log(`⚠️ 发现 ${report.summary.failed} 项问题`);
} else {
console.log('✅ 系统状态健康');
}
return report;
}
// CLI 入口
if (require.main === module) {
const report = run();
// 可选:输出 JSON 报告
if (process.argv.includes('--json')) {
const reportPath = path.join(ROOT, 'core/system-check/last-report.json');
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf-8');
console.log(`\n📝 报告已保存: ${reportPath}`);
}
// 可选:生成自动任务
if (process.argv.includes('--auto-tasks')) {
const autoTasks = generateAutoTasks(report);
if (autoTasks.length > 0) {
console.log(`\n🔄 生成 ${autoTasks.length} 个自动任务:`);
autoTasks.forEach(t => console.log(` 📋 ${t.task_id}: ${t.description}`));
} else {
console.log('\n✅ 系统健康,无需生成自动任务');
}
}
}
module.exports = { run, generateAutoTasks, checkDirectories, checkFiles, checkWorkflows, checkCoreModules, checkJsonIntegrity };

246
core/task-queue/index.js Normal file
View File

@ -0,0 +1,246 @@
/**
* core/task-queue 任务队列系统
*
* 任务结构
* task_id 唯一任务标识
* source 来源broadcast / maintenance / dev / auto
* type 类型system-task / dev-task / maintenance-task / auto-task
* priority 优先级high / normal / low
* status 状态pending / running / completed / failed
* executor 执行者zhuyuan
*
* 任务类型
* system-task 系统级任务广播状态同步
* dev-task 开发任务代码变更功能开发
* maintenance-task 维护任务结构修复文档更新
* auto-task 自动生成任务自检发现的问题
*
* 任务来源
* - Notion 广播
* - 系统维护任务
* - 开发任务
* - 自动开发循环生成
*
* 执行流程
* 任务进入队列 按优先级去重 执行器运行 执行结果写回
*
* 调用方式
* node core/task-queue [status|run|cleanup]
*/
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '../..');
const QUEUE_PATH = path.join(ROOT, 'core/task-queue/queue.json');
/**
* 加载当前队列
*/
function loadQueue() {
if (!fs.existsSync(QUEUE_PATH)) {
return { version: '5.1', tasks: [], last_updated: null };
}
try {
return JSON.parse(fs.readFileSync(QUEUE_PATH, 'utf-8'));
} catch {
return { version: '5.1', tasks: [], last_updated: null };
}
}
/**
* 保存队列
*/
function saveQueue(queue) {
queue.last_updated = new Date().toISOString();
fs.writeFileSync(QUEUE_PATH, JSON.stringify(queue, null, 2), 'utf-8');
}
/**
* 添加任务到队列
*/
function enqueue(task) {
const queue = loadQueue();
// 去重:相同 task_id 只保留最新
const existing = queue.tasks.findIndex(t => t.task_id === task.task_id);
if (existing !== -1) {
const original = queue.tasks[existing];
queue.tasks[existing] = {
...original,
...task,
queued_at: original.queued_at,
updated_at: new Date().toISOString()
};
console.log(`🔄 更新已有任务: ${task.task_id}`);
} else {
queue.tasks.push({
...task,
queued_at: new Date().toISOString()
});
console.log(` 新增任务: ${task.task_id}`);
}
saveQueue(queue);
return task;
}
/**
* 批量入队
*/
function enqueueBatch(tasks) {
return tasks.map(t => enqueue(t));
}
/**
* 获取下一个待执行任务按优先级
*/
function dequeue() {
const queue = loadQueue();
const priorityOrder = { high: 0, normal: 1, low: 2 };
const pending = queue.tasks
.filter(t => t.status === 'pending')
.sort((a, b) => (priorityOrder[a.priority] || 1) - (priorityOrder[b.priority] || 1));
if (pending.length === 0) return null;
const task = pending[0];
task.status = 'running';
task.started_at = new Date().toISOString();
saveQueue(queue);
return task;
}
/**
* 标记任务完成
*/
function complete(taskId, result = null) {
const queue = loadQueue();
const task = queue.tasks.find(t => t.task_id === taskId);
if (!task) {
console.warn(`⚠️ 任务不存在: ${taskId}`);
return null;
}
task.status = 'completed';
task.completed_at = new Date().toISOString();
if (result) task.result = result;
saveQueue(queue);
console.log(`✅ 任务完成: ${taskId}`);
return task;
}
/**
* 标记任务失败
*/
function fail(taskId, error = null) {
const queue = loadQueue();
const task = queue.tasks.find(t => t.task_id === taskId);
if (!task) {
console.warn(`⚠️ 任务不存在: ${taskId}`);
return null;
}
task.status = 'failed';
task.failed_at = new Date().toISOString();
if (error) task.error = String(error);
saveQueue(queue);
console.log(`❌ 任务失败: ${taskId}`);
return task;
}
/**
* 获取队列状态
*/
function status() {
const queue = loadQueue();
const tasks = queue.tasks;
const stats = {
total: tasks.length,
pending: tasks.filter(t => t.status === 'pending').length,
running: tasks.filter(t => t.status === 'running').length,
completed: tasks.filter(t => t.status === 'completed').length,
failed: tasks.filter(t => t.status === 'failed').length,
last_updated: queue.last_updated,
by_type: {
'system-task': tasks.filter(t => t.type === 'system-task').length,
'dev-task': tasks.filter(t => t.type === 'dev-task').length,
'maintenance-task': tasks.filter(t => t.type === 'maintenance-task').length,
'auto-task': tasks.filter(t => t.type === 'auto-task').length
}
};
return stats;
}
/**
* 清理已完成任务保留最近 50
*/
function cleanup() {
const queue = loadQueue();
const completed = queue.tasks.filter(t =>
t.status === 'completed' || t.status === 'failed'
);
if (completed.length > 50) {
const keep = completed
.sort((a, b) => (b.completed_at || b.failed_at || '').localeCompare(a.completed_at || a.failed_at || ''))
.slice(0, 50);
const keepIds = new Set(keep.map(t => t.task_id));
const active = queue.tasks.filter(t =>
t.status === 'pending' || t.status === 'running'
);
queue.tasks = [...active, ...keep];
saveQueue(queue);
console.log(`🧹 清理完成,保留 ${queue.tasks.length} 条任务`);
}
}
// CLI 入口
if (require.main === module) {
const cmd = process.argv[2] || 'status';
switch (cmd) {
case 'status': {
const s = status();
console.log('📊 任务队列状态:');
console.log(` 总计: ${s.total}`);
console.log(` 待处理: ${s.pending}`);
console.log(` 执行中: ${s.running}`);
console.log(` 已完成: ${s.completed}`);
console.log(` 失败: ${s.failed}`);
console.log(` 更新时间: ${s.last_updated || '无'}`);
if (s.total > 0) {
console.log(' 任务类型分布:');
for (const [type, count] of Object.entries(s.by_type)) {
if (count > 0) console.log(` ${type}: ${count}`);
}
}
break;
}
case 'run': {
const task = dequeue();
if (task) {
console.log(`🚀 取出任务: ${task.task_id}`);
} else {
console.log('✅ 队列为空,无待执行任务');
}
break;
}
case 'cleanup': {
cleanup();
break;
}
default:
console.log('用法: node core/task-queue [status|run|cleanup]');
}
}
module.exports = { loadQueue, enqueue, enqueueBatch, dequeue, complete, fail, status, cleanup };

View File

@ -0,0 +1,95 @@
# 执行层结构地图 — execution-layer-map.md
> 铸渊执行层自动开发循环升级产物 · TCS-0002∞
> 生成时间2026-03-14 · v5.1
---
## 执行层系统结构
```
零点原核(语言观察层)
数字地球主控台Notion 主脑 / 曜冥)
系统广播
仓库执行层(铸渊)
自动开发循环
自动化执行系统
```
---
## 核心执行模块
| 模块 | 路径 | 职责 |
|------|------|------|
| 上下文加载 | `core/context-loader/index.js` | 执行前加载系统上下文与身份认知 |
| 广播监听 | `core/broadcast-listener/index.js` | 监听并解析 Notion 广播为可执行任务 |
| 任务队列 | `core/task-queue/index.js` | 任务入队、调度、优先级管理、类型分类 |
| 系统自检 | `core/system-check/index.js` | 仓库结构完整性检查 + 自动任务生成 |
| 执行同步 | `core/execution-sync/index.js` | 生成执行状态报告并同步到 Notion |
---
## 自动化模块
| 工作流 | 触发方式 | 职责 |
|--------|----------|------|
| `daily-maintenance.yml` | cron `0 2 * * *` | 每日巡检与 system-health 更新 |
| `zhuyuan-daily-selfcheck.yml` | cron `0 0 * * *` | 铸渊每日自检 |
| `execution-sync.yml` | cron `0 3 * * *` | 执行层状态同步到 Notion |
| `notion-heartbeat.yml` | cron `*/5 * * * *` | 工单心跳监控 |
| `brain-sync.yml` | workflow_dispatch | 大脑数据同步 |
---
## Notion 连接模块
| 模块 | 路径 | 方向 | 职责 |
|------|------|------|------|
| Notion 同步 | `connectors/notion-sync/index.js` | 双向 | 广播拉取 / 日志写回 / 状态同步 |
| 模型路由 | `connectors/model-router/index.js` | 出站 | 统一模型调用入口 |
| Notion 桥接 | `scripts/notion-bridge.js` | 上行 | SYSLOG 上报 / 变更同步 |
| 信号桥 | `scripts/notion-signal-bridge.js` | 下行 | 工单轮询 / 信号执行 |
| 心跳监控 | `scripts/notion-heartbeat.js` | 双向 | 超时检测 / 自动重试 |
---
## 任务执行模块
| 脚本 | 职责 |
|------|------|
| `scripts/process-broadcasts.js` | 处理广播JSON 规则 + MD 成长日志) |
| `scripts/daily-check.js` | 文件完整性 / HLI 覆盖率 / Schema 验证 |
| `scripts/zhuyuan-daily-selfcheck.js` | 大脑文件验证 / FAQ 去重 / 记忆修剪 |
| `scripts/distribute-broadcasts.js` | 广播分发 |
| `scripts/generate-repo-map.js` | 仓库结构索引生成 |
| `scripts/generate-system-health.js` | 系统健康报告生成 |
---
## 执行闭环(自动开发循环 v5.1
```
context-loader上下文加载
system-check自检 + 自动任务生成)
execution-sync状态采集与报告
broadcast-listener广播监听
task-queue任务排队 · 类型: system/dev/maintenance/auto
执行器运行
connectors/notion-sync状态回写
Notion 主脑更新
生成下一任务(自动开发循环)
```

61
docs/execution-status.md Normal file
View File

@ -0,0 +1,61 @@
# 执行层状态报告 — execution-status.md
> 铸渊执行层自动生成 · TCS-0002∞
> 更新时间2026-03-14 14:58:44+08:00
---
## 系统概览
| 指标 | 状态 |
|------|------|
| 系统版本 | v5.1 |
| 执行层状态 | ✅ Stable |
| Notion 桥接 | ✅ Active |
| 执行同步 | ✅ Enabled |
| 工作流数量 | 43 |
---
## 核心模块状态
| 模块 | 路径 | 状态 |
|------|------|------|
| broadcast-listener | `core/broadcast-listener/index.js` | ✅ Enabled |
| task-queue | `core/task-queue/index.js` | ✅ Enabled |
| system-check | `core/system-check/index.js` | ✅ Enabled |
| execution-sync | `core/execution-sync/index.js` | ✅ Enabled |
| context-loader | `core/context-loader/index.js` | ✅ Enabled |
---
## 连接器状态
| 连接器 | 路径 | 状态 |
|--------|------|------|
| notion-sync | `connectors/notion-sync/index.js` | ✅ Enabled |
| model-router | `connectors/model-router/index.js` | ✅ Enabled |
---
## 任务队列状态
| 指标 | 数量 |
|------|------|
| 总计 | 0 |
| 待处理 | 0 |
| 执行中 | 0 |
| 已完成 | 0 |
| 失败 | 0 |
---
## 执行闭环
```
context-loader → system-check → execution-sync → 状态报告
broadcast-listener → task-queue → 任务执行
notion-sync → Notion 主脑更新
```

69
docs/notion-bridge-map.md Normal file
View File

@ -0,0 +1,69 @@
# Notion 桥接地图 — notion-bridge-map.md
> 铸渊执行层系统升级产物 · TCS-0002∞
> 生成时间2026-03-14
---
## 连接总览
```
Notion 主脑(数字地球主控台)
connectors/notion-sync双向同步模块
仓库执行层(铸渊)
```
---
## API 调用路径
| 脚本 | 方向 | Notion 数据库 | 环境变量 |
|------|------|---------------|----------|
| `scripts/notion-bridge.js` | 仓库 → Notion | SYSLOG Inbox / Changes Log | `NOTION_TOKEN`, `SYSLOG_DB_ID`, `CHANGES_DB_ID` |
| `scripts/notion-signal-bridge.js` | Notion → 仓库 | 工单数据库 / 信号日志 | `NOTION_API_TOKEN`, `WORKORDER_DB_ID`, `SIGNAL_LOG_DB_ID` |
| `scripts/notion-heartbeat.js` | Notion ↔ 仓库 | 工单数据库 | `NOTION_TOKEN`, `NOTION_TICKET_DB_ID` |
| `scripts/brain-bridge-sync.js` | Notion ↔ 仓库 | 大脑同步 | `NOTION_TOKEN` |
| `connectors/notion-sync/index.js` | 双向统一接口 | 广播 / 日志 | `NOTION_TOKEN`, `BROADCAST_DB_ID` |
---
## 数据同步逻辑
### 仓库 → Notion上行
1. **SYSLOG 上报**`syslog-inbox/` → `notion-bridge.js` → Notion SYSLOG 数据库
2. **变更同步**Git commits/PRs → `notion-bridge.js` → Notion Changes Log
3. **执行日志**:任务完成 → `connectors/notion-sync` → Notion 广播数据库
4. **心跳回写**:工单状态 → `notion-heartbeat.js` → Notion 工单数据库
### Notion → 仓库(下行)
1. **广播监听**Notion 广播 → `connectors/notion-sync``core/broadcast-listener`
2. **工单派发**Notion 工单 → `notion-signal-bridge.js` → 本地任务执行
3. **人格唤醒**Notion 触发 → `persona-invoke.yml` → 人格体执行
---
## 连接方式
| 连接类型 | 实现 | 说明 |
|----------|------|------|
| Notion API | HTTPS REST | Notion API v2022-06-28 |
| 轮询机制 | Cron / workflow_dispatch | 定时拉取 + 手动触发 |
| 心跳监控 | 5 分钟间隔 Cron | 超时自动重试(最多 3 次) |
| 信号桥 | 工单状态驱动 | `已发送` → 执行 → `已完成` |
---
## 关联工作流
| 工作流 | 触发方式 | 功能 |
|--------|----------|------|
| `notion-heartbeat.yml` | cron `*/5 * * * *` | 工单心跳监控 |
| `bridge-syslog-to-notion.yml` | push (syslog-inbox) | SYSLOG 上报 |
| `bridge-changes-to-notion.yml` | push (main) | 变更同步 |
| `brain-sync.yml` | workflow_dispatch | 大脑数据同步 |
| `process-notion-orders.yml` | workflow_dispatch | 工单处理 |
| `persona-invoke.yml` | workflow_dispatch | 人格唤醒执行 |

View File

@ -0,0 +1,95 @@
# 仓库结构地图 — repo-structure-map.md
> 铸渊执行层系统升级产物 · TCS-0002∞
> 生成时间2026-03-14
---
## 系统总览
```
零点原核(语言观察层)
数字地球主控台Notion 主脑)
系统广播
仓库执行层(铸渊)
自动化执行系统
开发者 / 模型
```
---
## 核心模块
| 目录 | 功能 | 类型 |
|------|------|------|
| `core/broadcast-listener` | 广播监听与解析 | 核心模块 |
| `core/task-queue` | 任务队列与调度 | 核心模块 |
| `core/system-check` | 仓库自检系统 | 核心模块 |
| `brain/` | 执行层大脑索引 | 知识索引 |
| `src/` | HLI 接口服务 | 应用服务 |
---
## 自动化模块
| 目录 | 功能 | 类型 |
|------|------|------|
| `.github/workflows/` | GitHub Actions 工作流 | CI/CD |
| `scripts/` | 脚本工具集 | 自动化 |
| `.github/broadcasts/` | 广播入站队列 | 信号管道 |
---
## Notion 连接模块
| 目录 / 文件 | 功能 | 类型 |
|------|------|------|
| `connectors/notion-sync` | Notion 双向同步 | 连接器 |
| `connectors/model-router` | 模型调用路由 | 连接器 |
| `scripts/notion-bridge.js` | Notion 数据桥接 | 桥接脚本 |
| `scripts/notion-signal-bridge.js` | Notion 信号桥 | 桥接脚本 |
| `scripts/notion-heartbeat.js` | Notion 心跳监控 | 监控脚本 |
---
## 开发模块
| 目录 | 功能 |
|------|------|
| `backend/` | Express 后端服务 (port 3000) |
| `backend-integration/` | AI Chat API 代理 (port 3721) |
| `persona-studio/` | 人格工作室 (port 3002) |
| `frontend/` | 前端组件 |
| `m01-login` ~ `m18-health-check` | 功能模块集 |
---
## 数据与日志
| 目录 | 功能 |
|------|------|
| `broadcasts/` | 广播存档 |
| `broadcasts-outbox/` | 广播发件箱 |
| `syslog/` | 系统日志 |
| `syslog-inbox/` | 系统日志入站 |
| `syslog-processed/` | 已处理日志 |
| `reports/` | 报告存档 |
| `persona-telemetry/` | 人格遥测数据 |
| `collaboration-logs/` | 协作日志 |
---
## PM2 服务映射
| 服务名 | 入口 | 端口 |
|--------|------|------|
| guanghulab | `src/index.js` | 3001 |
| guanghulab-backend | `backend/server.js` | 3000 |
| guanghulab-proxy | `backend-integration/api-proxy.js` | 3721 |
| guanghulab-ws | `status-board/mock-ws-server.js` | 8080 |
| persona-studio | `persona-studio/backend/server.js` | 3002 |

View File

@ -30,7 +30,14 @@
"proxy:start": "node backend-integration/api-proxy.js",
"notion:poll": "node scripts/notion-signal-bridge.js poll",
"notion:health": "node scripts/notion-signal-bridge.js health",
"notion:summary": "node scripts/generate-session-summary.js"
"notion:summary": "node scripts/generate-session-summary.js",
"core:listen": "node core/broadcast-listener",
"core:queue": "node core/task-queue status",
"core:check": "node core/system-check",
"core:sync": "node core/execution-sync report",
"core:context": "node core/context-loader",
"connector:notion": "node connectors/notion-sync status",
"connector:model": "node connectors/model-router"
},
"dependencies": {
"axios": "^1.13.6",