diff --git a/.github/workflows/daily-maintenance.yml b/.github/workflows/daily-maintenance.yml new file mode 100644 index 00000000..2368a4b7 --- /dev/null +++ b/.github/workflows/daily-maintenance.yml @@ -0,0 +1,143 @@ +name: "🔧 铸渊 · Daily Maintenance Agent" + +on: + schedule: + - cron: '0 2 * * *' # 每日 UTC 02:00 (北京时间 10:00) + workflow_dispatch: + +permissions: + contents: write + +jobs: + maintenance: + 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: 检查 brain/ 目录完整性 ── + - name: 检查 brain/ 目录完整性 + id: brain_check + run: | + echo "🔍 检查 brain/ 目录..." + REQUIRED_FILES="master-brain.md read-order.md repo-map.json automation-map.json communication-map.json id-map.json system-health.json" + MISSING="" + for f in $REQUIRED_FILES; do + if [ ! -f "brain/$f" ]; then + MISSING="$MISSING $f" + echo "⚠️ 缺失: brain/$f" + else + echo "✅ 存在: brain/$f" + fi + done + if [ -z "$MISSING" ]; then + echo "brain_status=complete" >> "$GITHUB_OUTPUT" + echo "✅ brain/ 目录完整" + else + echo "brain_status=incomplete" >> "$GITHUB_OUTPUT" + echo "⚠️ 缺失文件:$MISSING" + fi + + # ── Step 2: 检查最近 workflow 运行状态 ── + - name: 检查最近 workflow 运行状态 + id: workflow_check + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "🔍 检查最近 workflow 运行..." + FAILED=$(gh api repos/${{ github.repository }}/actions/runs \ + --jq '[.workflow_runs[] | select(.conclusion == "failure")] | length' \ + 2>/dev/null || echo "0") + echo "failed_count=$FAILED" >> "$GITHUB_OUTPUT" + if [ "$FAILED" -gt "0" ]; then + echo "⚠️ 最近有 $FAILED 个失败的 workflow" + else + echo "✅ 最近没有失败的 workflow" + fi + + # ── Step 3: 检查 Notion API 连通性 ── + - name: 检查 Notion API 连通性 + id: notion_check + env: + NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }} + run: | + echo "🔍 检查 Notion API 连通性..." + if [ -z "$NOTION_TOKEN" ]; then + echo "notion_status=no_token" >> "$GITHUB_OUTPUT" + echo "⚠️ NOTION_TOKEN 未配置" + else + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: Bearer $NOTION_TOKEN" \ + -H "Notion-Version: 2022-06-28" \ + https://api.notion.com/v1/users/me 2>/dev/null || echo "000") + echo "notion_http_code=$HTTP_CODE" >> "$GITHUB_OUTPUT" + if [ "$HTTP_CODE" = "200" ]; then + echo "notion_status=connected" >> "$GITHUB_OUTPUT" + echo "✅ Notion API 连通" + else + echo "notion_status=error" >> "$GITHUB_OUTPUT" + echo "⚠️ Notion API 返回 HTTP $HTTP_CODE" + fi + fi + + # ── Step 4: 更新 system-health.json ── + - name: 更新 system-health.json + run: node scripts/generate-system-health.js + + # ── Step 5: 提交更新 ── + - name: 提交巡检结果 + run: | + git config user.name "铸渊 Maintenance Agent" + git config user.email "actions@guanghulab.com" + git add brain/system-health.json + if git diff --cached --quiet; then + echo "📌 无变更需要提交" + else + git commit -m "🔧 Daily Maintenance: 更新 system-health.json [skip ci]" + git push + echo "✅ 已提交 system-health.json 更新" + fi + + # ── Step 6: 向 Notion 回报巡检结果 ── + - name: 向 Notion 回报巡检结果 + if: env.NOTION_TOKEN != '' && env.SYSLOG_DB_ID != '' + env: + NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }} + SYSLOG_DB_ID: ${{ secrets.SYSLOG_DB_ID }} + run: | + echo "📡 向 Notion 跨平台信号日志回报..." + TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z") + BRAIN_STATUS="${{ steps.brain_check.outputs.brain_status }}" + FAILED_COUNT="${{ steps.workflow_check.outputs.failed_count }}" + NOTION_STATUS="${{ steps.notion_check.outputs.notion_status }}" + + REPORT="Daily Maintenance Report | brain: ${BRAIN_STATUS} | failed_workflows: ${FAILED_COUNT} | notion: ${NOTION_STATUS}" + + curl -s -X POST "https://api.notion.com/v1/pages" \ + -H "Authorization: Bearer $NOTION_TOKEN" \ + -H "Content-Type: application/json" \ + -H "Notion-Version: 2022-06-28" \ + -d "{ + \"parent\": { \"database_id\": \"$SYSLOG_DB_ID\" }, + \"properties\": { + \"标题\": { + \"title\": [{ \"text\": { \"content\": \"Daily Maintenance · $(date +%Y-%m-%d)\" } }] + }, + \"状态\": { \"select\": { \"name\": \"已处理\" } }, + \"类型\": { \"select\": { \"name\": \"巡检\" } } + }, + \"children\": [{ + \"object\": \"block\", + \"type\": \"paragraph\", + \"paragraph\": { + \"rich_text\": [{ \"text\": { \"content\": \"$REPORT\" } }] + } + }] + }" > /dev/null 2>&1 && echo "✅ Notion 回报完成" || echo "⚠️ Notion 回报失败(非致命)" diff --git a/brain/automation-map.json b/brain/automation-map.json new file mode 100644 index 00000000..5036c76a --- /dev/null +++ b/brain/automation-map.json @@ -0,0 +1,650 @@ +{ + "version": "4.0", + "generated_at": "2026-03-13T19:36:48.677Z", + "generated_by": "scripts/generate-automation-map.js", + "description": "数字地球系统自动化地图 · 所有工作流与自动化脚本", + "workflows": [ + { + "file": "bingshuo-deploy-agent.yml", + "name": "🧊 冰朔人格体 · 自动部署诊断", + "triggers": [ + "issues", + "issue_comment", + "workflow_dispatch" + ], + "scripts": [ + "scripts/bingshuo-deploy-agent.js" + ] + }, + { + "file": "bingshuo-neural-system.yml", + "name": "冰朔主控神经系统 · 自动维护", + "triggers": [ + "push", + "workflow_dispatch", + "schedule" + ], + "cron": "0 0 * * *", + "scripts": [ + "scripts/bingshuo-neural-sync.js" + ] + }, + { + "file": "brain-sync.yml", + "name": "铸渊 Brain Sync", + "triggers": [ + "push", + "workflow_dispatch", + "schedule" + ], + "cron": "0 8 * * *", + "scripts": [ + "scripts/process-broadcasts.js", + "scripts/daily-check.js", + "scripts/update-memory.js" + ] + }, + { + "file": "bridge-changes-to-notion.yml", + "name": "铸渊 · Bridge E · GitHub Changes → Notion", + "triggers": [ + "push", + "pull_request" + ], + "scripts": [ + "scripts/notion-bridge.js", + "scripts/notion-bridge.js" + ] + }, + { + "file": "bridge-session-summary.yml", + "name": "Generate Session Summary for Notion", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "50 23 * * *", + "scripts": [ + "scripts/generate-session-summary.js" + ] + }, + { + "file": "bridge-syslog-to-notion.yml", + "name": "铸渊 · Bridge A · SYSLOG → Notion", + "triggers": [ + "push", + "workflow_dispatch" + ], + "scripts": [ + "scripts/notion-bridge.js" + ] + }, + { + "file": "check-structure.yml", + "name": "模块结构检查", + "triggers": [ + "unknown" + ] + }, + { + "file": "daily-maintenance.yml", + "name": "🔧 铸渊 · Daily Maintenance Agent", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "0 2 * * *", + "scripts": [ + "scripts/generate-system-health.js" + ] + }, + { + "file": "deploy-pages.yml", + "name": "🌀 部署铸渊聊天室 (GitHub Pages)", + "triggers": [ + "push", + "workflow_dispatch" + ] + }, + { + "file": "deploy-to-server.yml", + "name": "🚀 铸渊 CD · 自动部署到 guanghulab.com", + "triggers": [ + "push", + "workflow_dispatch" + ], + "scripts": [ + "scripts/contract-check.js", + "scripts/zhuyuan-module-protocol.js", + "scripts/notion-bridge.js" + ] + }, + { + "file": "distribute-broadcasts.yml", + "name": "铸渊 · 广播分发", + "triggers": [ + "push", + "workflow_dispatch" + ], + "scripts": [ + "scripts/distribute-broadcasts.js" + ] + }, + { + "file": "esp-signal-processor.yml", + "name": "铸渊 · ESP 邮件信号处理器(已暂停)", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "*/30 * * * *", + "scripts": [ + "scripts/esp-email-processor.js" + ] + }, + { + "file": "generate-module-doc.yml", + "name": "铸渊 · 光湖纪元 模块文档自动生成", + "triggers": [ + "push", + "workflow_dispatch" + ], + "scripts": [ + "scripts/generate-module-doc.js", + "scripts/notify-module-received.js" + ] + }, + { + "file": "hli-contract-check.yml", + "name": "HLI Contract Check", + "triggers": [ + "push", + "pull_request" + ] + }, + { + "file": "notion-callback-pipeline.yml", + "name": "Notion Callback Pipeline", + "triggers": [ + "unknown" + ], + "scripts": [ + "scripts/verify-modules.js", + "scripts/wake-persona.js", + "scripts/push-broadcast-to-github.js" + ] + }, + { + "file": "notion-connectivity-test.yml", + "name": "铸渊 · Notion 连通性测试", + "triggers": [ + "workflow_dispatch" + ], + "scripts": [ + "scripts/notion-connectivity-test.js" + ] + }, + { + "file": "notion-heartbeat.yml", + "name": "Notion Heartbeat Monitor", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "*/5 * * * *", + "scripts": [ + "scripts/notion-heartbeat.js" + ] + }, + { + "file": "notion-poll.yml", + "name": "铸渊 · Notion 工单轮询", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "*/15 * * * *", + "scripts": [ + "scripts/notion-signal-bridge.js" + ] + }, + { + "file": "persona-invoke.yml", + "name": "Persona Invoke Endpoint", + "triggers": [ + "workflow_dispatch" + ], + "scripts": [ + "scripts/verify-modules.js", + "scripts/wake-persona.js", + "scripts/push-broadcast-to-github.js" + ] + }, + { + "file": "pm2-server-diagnose.yml", + "name": "🔧 铸渊 · PM2 服务诊断与健康检查", + "triggers": [ + "workflow_dispatch" + ], + "scripts": [ + "scripts/server-diagnose-report.js" + ] + }, + { + "file": "process-notion-orders.yml", + "name": "Process Notion Work Orders", + "triggers": [ + "push", + "workflow_dispatch" + ] + }, + { + "file": "ps-on-build.yml", + "name": "🌊 Persona Studio · 代码生成", + "triggers": [ + "workflow_dispatch" + ] + }, + { + "file": "ps-on-chat.yml", + "name": "🌊 Persona Studio · 对话处理", + "triggers": [ + "workflow_dispatch" + ] + }, + { + "file": "ps-on-complete.yml", + "name": "🌊 Persona Studio · 完成通知", + "triggers": [ + "workflow_dispatch" + ] + }, + { + "file": "ps-on-login.yml", + "name": "🌊 Persona Studio · 登录校验", + "triggers": [ + "workflow_dispatch" + ] + }, + { + "file": "psp-daily-inspection.yml", + "name": "铸渊 · PSP 分身巡检", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "0 1 * * *", + "scripts": [ + "scripts/psp-inspection.js" + ] + }, + { + "file": "push-broadcast.yml", + "name": "铸渊 · Push Broadcast · Notion → 飞书文档B", + "triggers": [ + "workflow_dispatch" + ], + "scripts": [ + "scripts/push-broadcast.js", + "scripts/send-feishu-alert.js", + "scripts/send-feishu-alert.js" + ] + }, + { + "file": "receive-syslog.yml", + "name": "铸渊 · Receive SYSLOG · 飞书机器人 → GitHub → Notion", + "triggers": [ + "unknown" + ], + "scripts": [ + "scripts/receive-syslog.js", + "scripts/send-feishu-alert.js" + ] + }, + { + "file": "staging-preview.yml", + "name": "🔍 铸渊预演部署 (Staging Preview)", + "triggers": [ + "pull_request", + "workflow_dispatch" + ] + }, + { + "file": "sync-login-entry.yml", + "name": "铸渊 · Sync Login Entry · Notion → 飞书文档A", + "triggers": [ + "workflow_dispatch" + ], + "scripts": [ + "scripts/sync-login-entry.js", + "scripts/send-feishu-alert.js" + ] + }, + { + "file": "sync-persona-studio.yml", + "name": "🔄 铸渊跨仓库同步 · persona-studio", + "triggers": [ + "push", + "workflow_dispatch" + ], + "scripts": [ + "scripts/cross-repo-sync.js" + ] + }, + { + "file": "syslog-auto-pipeline.yml", + "name": "SYSLOG Auto Pipeline", + "triggers": [ + "unknown" + ], + "scripts": [ + "scripts/verify-modules.js", + "scripts/wake-persona.js", + "scripts/create-standardized-ticket.js", + "scripts/push-broadcast-to-github.js" + ] + }, + { + "file": "syslog-issue-pipeline.yml", + "name": "📡 SYSLOG Issue Pipeline", + "triggers": [ + "issues" + ], + "scripts": [ + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/verify-modules.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/wake-persona.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/create-standardized-ticket.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/push-broadcast-to-github.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js", + "scripts/pipeline-reporter.js" + ] + }, + { + "file": "syslog-pipeline.yml", + "name": "铸渊 · SYSLOG Pipeline (A/D/E)", + "triggers": [ + "push", + "workflow_dispatch" + ], + "scripts": [ + "scripts/process-syslog.js" + ] + }, + { + "file": "test-notion-bridge.yml", + "name": "🧪 Notion Bridge Connectivity Test", + "triggers": [ + "push", + "workflow_dispatch" + ] + }, + { + "file": "update-readme-bulletin.yml", + "name": "📢 更新系统公告区", + "triggers": [ + "push", + "workflow_dispatch", + "schedule" + ], + "cron": "0 1 * * *", + "scripts": [ + "scripts/update-readme-bulletin.js" + ] + }, + { + "file": "update-repo-map.yml", + "name": "铸渊 · 图书馆目录自动更新", + "triggers": [ + "push", + "workflow_dispatch", + "schedule" + ], + "cron": "0 0 * * *", + "scripts": [ + "scripts/generate-repo-map.js" + ] + }, + { + "file": "zhuyuan-brain-sync.yml", + "name": "铸渊 · Brain Sync", + "triggers": [ + "push" + ], + "scripts": [ + "scripts/update-brain.js", + "scripts/process-broadcasts.js" + ] + }, + { + "file": "zhuyuan-daily-agent.yml", + "name": "🤖 铸渊巡检 Agent · 每日自动巡检与修复", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "0 14 * * *", + "scripts": [ + "scripts/zhuyuan-daily-agent.js" + ] + }, + { + "file": "zhuyuan-daily-selfcheck.yml", + "name": "铸渊 · 每日自检", + "triggers": [ + "workflow_dispatch", + "schedule" + ], + "cron": "0 0 * * *", + "scripts": [ + "scripts/selfcheck.js" + ] + }, + { + "file": "zhuyuan-issue-reply.yml", + "name": "铸渊 · Issue 自动回复", + "triggers": [ + "issues", + "issue_comment" + ], + "scripts": [ + "scripts/zhuyuan-issue-reply.js" + ] + }, + { + "file": "zhuyuan-pr-review.yml", + "name": "铸渊 · PR Review", + "triggers": [ + "pull_request" + ], + "scripts": [ + "scripts/contract-check.js", + "scripts/route-align-check.js" + ] + } + ], + "cron_jobs": [ + { + "cron": "*/15 * * * *", + "workflow": "notion-poll.yml", + "name": "铸渊 · Notion 工单轮询" + }, + { + "cron": "*/30 * * * *", + "workflow": "esp-signal-processor.yml", + "name": "铸渊 · ESP 邮件信号处理器(已暂停)" + }, + { + "cron": "*/5 * * * *", + "workflow": "notion-heartbeat.yml", + "name": "Notion Heartbeat Monitor" + }, + { + "cron": "0 0 * * *", + "workflow": "bingshuo-neural-system.yml", + "name": "冰朔主控神经系统 · 自动维护" + }, + { + "cron": "0 0 * * *", + "workflow": "update-repo-map.yml", + "name": "铸渊 · 图书馆目录自动更新" + }, + { + "cron": "0 0 * * *", + "workflow": "zhuyuan-daily-selfcheck.yml", + "name": "铸渊 · 每日自检" + }, + { + "cron": "0 1 * * *", + "workflow": "psp-daily-inspection.yml", + "name": "铸渊 · PSP 分身巡检" + }, + { + "cron": "0 1 * * *", + "workflow": "update-readme-bulletin.yml", + "name": "📢 更新系统公告区" + }, + { + "cron": "0 14 * * *", + "workflow": "zhuyuan-daily-agent.yml", + "name": "🤖 铸渊巡检 Agent · 每日自动巡检与修复" + }, + { + "cron": "0 2 * * *", + "workflow": "daily-maintenance.yml", + "name": "🔧 铸渊 · Daily Maintenance Agent" + }, + { + "cron": "0 8 * * *", + "workflow": "brain-sync.yml", + "name": "铸渊 Brain Sync" + }, + { + "cron": "50 23 * * *", + "workflow": "bridge-session-summary.yml", + "name": "Generate Session Summary for Notion" + } + ], + "deploy_scripts": [ + { + "workflow": "bingshuo-deploy-agent.yml", + "name": "🧊 冰朔人格体 · 自动部署诊断", + "triggers": [ + "issues", + "issue_comment", + "workflow_dispatch" + ] + }, + { + "workflow": "deploy-pages.yml", + "name": "🌀 部署铸渊聊天室 (GitHub Pages)", + "triggers": [ + "push", + "workflow_dispatch" + ] + }, + { + "workflow": "deploy-to-server.yml", + "name": "🚀 铸渊 CD · 自动部署到 guanghulab.com", + "triggers": [ + "push", + "workflow_dispatch" + ] + } + ], + "data_sync_scripts": [ + { + "script": "scripts/bingshuo-deploy-agent.js", + "type": "other" + }, + { + "script": "scripts/bingshuo-neural-sync.js", + "type": "sync" + }, + { + "script": "scripts/brain-bridge-sync.js", + "type": "sync" + }, + { + "script": "scripts/create-standardized-ticket.js", + "type": "other" + }, + { + "script": "scripts/cross-repo-sync.js", + "type": "sync" + }, + { + "script": "scripts/generate-automation-map.js", + "type": "other" + }, + { + "script": "scripts/generate-communication-map.js", + "type": "other" + }, + { + "script": "scripts/invoke-persona.js", + "type": "other" + }, + { + "script": "scripts/notify-module-received.js", + "type": "other" + }, + { + "script": "scripts/notion-bridge.js", + "type": "bridge" + }, + { + "script": "scripts/notion-connectivity-test.js", + "type": "other" + }, + { + "script": "scripts/notion-heartbeat.js", + "type": "other" + }, + { + "script": "scripts/notion-signal-bridge.js", + "type": "bridge" + }, + { + "script": "scripts/process-broadcasts.js", + "type": "broadcast" + }, + { + "script": "scripts/push-broadcast-to-github.js", + "type": "broadcast" + }, + { + "script": "scripts/push-broadcast.js", + "type": "broadcast" + }, + { + "script": "scripts/receive-syslog.js", + "type": "other" + }, + { + "script": "scripts/server-diagnose-report.js", + "type": "other" + }, + { + "script": "scripts/sync-login-entry.js", + "type": "sync" + }, + { + "script": "scripts/wake-persona.js", + "type": "other" + } + ], + "status": "stable" +} \ No newline at end of file diff --git a/brain/communication-map.json b/brain/communication-map.json new file mode 100644 index 00000000..fd7f17f8 --- /dev/null +++ b/brain/communication-map.json @@ -0,0 +1,631 @@ +{ + "version": "4.0", + "generated_at": "2026-03-13T19:36:48.714Z", + "generated_by": "scripts/generate-communication-map.js", + "description": "数字地球系统通信地图 · 所有通信入口与数据流", + "api_endpoints": { + "hli_middleware": { + "port": 3001, + "process": "guanghulab", + "script": "src/index.js", + "routes": [ + { + "method": "GET", + "path": "/health", + "description": "健康检查" + }, + { + "method": "POST", + "path": "/hli/auth/login", + "description": "用户登录" + }, + { + "method": "POST", + "path": "/hli/auth/register", + "description": "用户注册" + }, + { + "method": "POST", + "path": "/hli/auth/verify", + "description": "Token 验证" + }, + { + "method": "POST", + "path": "/hli/brain/prompt", + "description": "AI Prompt 构建" + }, + { + "method": "POST", + "path": "/hli/brain/route", + "description": "脑路由" + }, + { + "method": "POST", + "path": "/hli/brain/context", + "description": "上下文管理" + }, + { + "method": "POST", + "path": "/hli/brain/memory", + "description": "记忆管理" + }, + { + "method": "GET", + "path": "/hli/brain/status", + "description": "脑状态" + }, + { + "method": "GET", + "path": "/hli/brain/bridge", + "description": "脑桥接状态" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/sync", + "description": "脑桥接同步" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/export", + "description": "脑桥接导出" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/consistency", + "description": "一致性检查" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/master-mode", + "description": "主模式切换" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/explanation", + "description": "桥接说明" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/inspection", + "description": "桥接巡检" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/developers", + "description": "开发者列表" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/developers/:expId", + "description": "单个开发者信息" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/developers", + "description": "开发者管理" + }, + { + "method": "GET", + "path": "/hli/registry/lookup", + "description": "开发者编号查询" + } + ] + }, + "express_backend": { + "port": 3000, + "process": "guanghulab-backend", + "script": "backend/server.js", + "routes": [ + { + "method": "GET", + "path": "/", + "description": "服务状态" + }, + { + "method": "*", + "path": "/notion/*", + "description": "Notion 路由" + }, + { + "method": "*", + "path": "/feishu/*", + "description": "飞书路由" + }, + { + "method": "*", + "path": "/feishu-bot/*", + "description": "飞书机器人路由" + }, + { + "method": "*", + "path": "/router/*", + "description": "路由管理" + }, + { + "method": "*", + "path": "/api/coldstart/*", + "description": "冷启动接口" + }, + { + "method": "*", + "path": "/api/v1/developers/*", + "description": "开发者管理接口" + }, + { + "method": "POST", + "path": "/webhook/feishu", + "description": "飞书 Webhook 入口" + } + ] + }, + "ai_proxy": { + "port": 3721, + "process": "guanghulab-proxy", + "script": "backend-integration/api-proxy.js", + "routes": [ + { + "method": "POST", + "path": "/chat", + "description": "AI Chat 代理" + } + ] + }, + "persona_studio": { + "port": 3002, + "process": "persona-studio", + "script": "persona-studio/backend/server.js", + "routes": [ + { + "method": "*", + "path": "/api/ps/*", + "description": "Persona Studio API" + } + ] + }, + "websocket": { + "port": 8080, + "process": "guanghulab-ws", + "script": "status-board/mock-ws-server.js", + "routes": [ + { + "method": "WS", + "path": "/ws", + "description": "看板 WebSocket 推送" + } + ] + } + }, + "webhook_endpoints": [ + { + "path": "/webhook/feishu", + "port": 3000, + "description": "飞书 Webhook 入口(机器人事件回调)", + "direction": "inbound" + }, + { + "path": "/feishu-bot/event", + "port": 3000, + "description": "飞书机器人新版事件入口", + "direction": "inbound" + } + ], + "trigger_paths": { + "github_to_notion": [ + { + "workflow": "bridge-changes-to-notion.yml", + "name": "铸渊 · Bridge E · GitHub Changes → Notion" + }, + { + "workflow": "bridge-session-summary.yml", + "name": "Generate Session Summary for Notion" + }, + { + "workflow": "bridge-syslog-to-notion.yml", + "name": "铸渊 · Bridge A · SYSLOG → Notion" + }, + { + "workflow": "deploy-to-server.yml", + "name": "🚀 铸渊 CD · 自动部署到 guanghulab.com" + }, + { + "workflow": "notion-callback-pipeline.yml", + "name": "Notion Callback Pipeline" + }, + { + "workflow": "persona-invoke.yml", + "name": "Persona Invoke Endpoint" + }, + { + "workflow": "push-broadcast.yml", + "name": "铸渊 · Push Broadcast · Notion → 飞书文档B" + }, + { + "workflow": "receive-syslog.yml", + "name": "铸渊 · Receive SYSLOG · 飞书机器人 → GitHub → Notion" + }, + { + "workflow": "sync-login-entry.yml", + "name": "铸渊 · Sync Login Entry · Notion → 飞书文档A" + }, + { + "workflow": "syslog-auto-pipeline.yml", + "name": "SYSLOG Auto Pipeline" + }, + { + "workflow": "syslog-issue-pipeline.yml", + "name": "📡 SYSLOG Issue Pipeline" + }, + { + "workflow": "test-notion-bridge.yml", + "name": "🧪 Notion Bridge Connectivity Test" + } + ], + "notion_to_github": [ + { + "workflow": "notion-heartbeat.yml", + "name": "Notion Heartbeat Monitor" + }, + { + "workflow": "notion-poll.yml", + "name": "铸渊 · Notion 工单轮询" + }, + { + "workflow": "persona-invoke.yml", + "name": "Persona Invoke Endpoint" + }, + { + "workflow": "process-notion-orders.yml", + "name": "Process Notion Work Orders" + } + ] + }, + "data_sync_scripts": [ + { + "script": "scripts/bingshuo-deploy-agent.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/bingshuo-neural-sync.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/brain-bridge-sync.js", + "direction": "bidirectional", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/create-standardized-ticket.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/cross-repo-sync.js", + "direction": "unknown", + "uses_notion_api": false, + "uses_http": true + }, + { + "script": "scripts/esp-email-processor.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/generate-automation-map.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/generate-communication-map.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/generate-repo-map.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/generate-session-summary.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/invoke-persona.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/notion-bridge.js", + "direction": "bidirectional", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/notion-connectivity-test.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/notion-heartbeat.js", + "direction": "external_to_github", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/notion-signal-bridge.js", + "direction": "bidirectional", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/psp-inspection.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/push-broadcast-to-github.js", + "direction": "github_to_external", + "uses_notion_api": false, + "uses_http": true + }, + { + "script": "scripts/push-broadcast.js", + "direction": "github_to_external", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/receive-syslog.js", + "direction": "external_to_github", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/server-diagnose-report.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/sync-login-entry.js", + "direction": "github_to_external", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/update-readme-bulletin.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/wake-persona.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + }, + { + "script": "scripts/zhuyuan-daily-selfcheck.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": false + }, + { + "script": "scripts/zhuyuan-issue-reply.js", + "direction": "github_to_notion", + "uses_notion_api": true, + "uses_http": true + } + ], + "automation_flows": [ + { + "name": "SYSLOG 处理管线", + "flow": "飞书机器人 → /webhook/feishu → receive-syslog.js → Notion 工单 → persona-invoke → 执行 → 回报", + "workflows": [ + "receive-syslog.yml", + "syslog-issue-pipeline.yml", + "syslog-auto-pipeline.yml", + "syslog-pipeline.yml" + ] + }, + { + "name": "每日巡检", + "flow": "cron → zhuyuan-daily-agent.yml → zhuyuan-daily-agent.js → 巡检报告 → Notion", + "workflows": [ + "zhuyuan-daily-agent.yml", + "zhuyuan-daily-selfcheck.yml", + "psp-daily-inspection.yml" + ] + }, + { + "name": "自动部署", + "flow": "push to main → deploy-to-server.yml → SSH → PM2 restart", + "workflows": [ + "deploy-to-server.yml", + "deploy-pages.yml" + ] + }, + { + "name": "Notion 双向同步", + "flow": "push → notion-bridge.js → Notion | cron → notion-poll.yml → GitHub", + "workflows": [ + "bridge-changes-to-notion.yml", + "notion-poll.yml", + "notion-heartbeat.yml", + "brain-sync.yml" + ] + }, + { + "name": "广播分发", + "flow": "Notion 工单 → invoke-persona.js → broadcasts-outbox/ → distribute-broadcasts.yml → dev-nodes/", + "workflows": [ + "persona-invoke.yml", + "distribute-broadcasts.yml", + "push-broadcast.yml" + ] + } + ], + "scan_results": { + "hli_routes_found": 19, + "backend_routes_found": 9, + "sync_scripts_found": 25, + "hli_routes": [ + { + "method": "POST", + "path": "/hli/auth/", + "file": "src/routes/hli/auth/login.js" + }, + { + "method": "POST", + "path": "/hli/auth/", + "file": "src/routes/hli/auth/register.js" + }, + { + "method": "POST", + "path": "/hli/auth/", + "file": "src/routes/hli/auth/verify.js" + }, + { + "method": "POST", + "path": "/hli/brain/prompt", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/route", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/context", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/memory", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/status", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/bridge", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/sync", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/export", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/consistency", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/master-mode", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/explanation", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/inspection", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/developers", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/brain/bridge/developers/:expId", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "POST", + "path": "/hli/brain/bridge/developers", + "file": "src/routes/hli/brain/index.js" + }, + { + "method": "GET", + "path": "/hli/registry/lookup", + "file": "src/routes/hli/registry/index.js" + } + ], + "backend_routes": [ + { + "method": "*", + "path": "/notion", + "file": "backend/server.js" + }, + { + "method": "*", + "path": "/feishu", + "file": "backend/server.js" + }, + { + "method": "*", + "path": "/feishu-bot", + "file": "backend/server.js" + }, + { + "method": "*", + "path": "/router", + "file": "backend/server.js" + }, + { + "method": "*", + "path": "/api/coldstart", + "file": "backend/server.js" + }, + { + "method": "*", + "path": "/api/v1/developers", + "file": "backend/server.js" + }, + { + "method": "*", + "path": "/hli", + "file": "backend/server.js" + }, + { + "method": "GET", + "path": "/", + "file": "backend/server.js" + }, + { + "method": "POST", + "path": "/webhook/feishu", + "file": "backend/server.js" + } + ] + } +} \ No newline at end of file diff --git a/brain/id-map.json b/brain/id-map.json new file mode 100644 index 00000000..4b336331 --- /dev/null +++ b/brain/id-map.json @@ -0,0 +1,15 @@ +{ + "冰朔": "TCS-0002∞", + "曜冥": "ICE-GL-YM001", + "页页": "DEV-001", + "肥猫": "DEV-002", + "燕樊": "DEV-003", + "之之": "DEV-004", + "小草莓": "DEV-005", + "花尔": "DEV-009", + "桔子": "DEV-010", + "匆匆那年": "DEV-011", + "Awen": "DEV-012", + "小兴": "DEV-013", + "时雨": "DEV-014" +} diff --git a/brain/master-brain.md b/brain/master-brain.md new file mode 100644 index 00000000..65579276 --- /dev/null +++ b/brain/master-brain.md @@ -0,0 +1,90 @@ +# 铸渊执行层 · 系统导航主文件 +# Master Brain · v4.0 +# 数字地球系统通信协议 v4.0 + +--- + +## 系统版本 + +**v4.0** — 数字地球系统通信协议 + +--- + +## 三层结构 + +``` +┌─────────────────────────────────────────────┐ +│ 观察层(零点原核频道) │ +│ · 监督与决策信号来源 │ +│ · 不直接控制执行层 │ +└──────────────────┬──────────────────────────┘ + ▼ +┌─────────────────────────────────────────────┐ +│ 核心大脑(Notion) │ +│ · 霜砚(认知层守护者) │ +│ · 所有人格认知、记忆源头、决策中心 │ +│ · 工单管理、信号总线、协议文档 │ +│ · Notion = 认知层 = 大脑 │ +└──────────────────┬──────────────────────────┘ + ▼ +┌─────────────────────────────────────────────┐ +│ 执行层(Repository) │ +│ · 铸渊(执行层守护者) │ +│ · 代码执行、自动化、部署交付 │ +│ · GitHub = 执行层 = 手脚 │ +│ · 数据流向:Notion → GitHub(认知驱动执行) │ +└─────────────────────────────────────────────┘ +``` + +--- + +## Notion 主入口 + +- **核心大脑**: 霜砚管理的 Notion 工作区 +- **数据流向**: Notion → GitHub(认知驱动执行) +- **认知层投影**: persona-brain-db 是认知层的执行投影,不是另一个大脑 + +--- + +## Repository 核心入口 + +| 入口 | 路径 | 说明 | +|------|------|------| +| 执行层导航 | `brain/master-brain.md` | 本文件 | +| 读取顺序 | `brain/read-order.md` | 铸渊唤醒读取顺序 | +| 仓库地图 | `brain/repo-map.json` | 仓库目录结构 | +| 自动化地图 | `brain/automation-map.json` | 工作流与自动化清单 | +| 通信地图 | `brain/communication-map.json` | 通信入口与数据流 | +| 编号档案 | `brain/id-map.json` | 名字→编号自动补全 | +| 系统健康 | `brain/system-health.json` | 系统运行状态 | + +--- + +## 铸渊职责 + +铸渊 = GitHub 侧守护人格体 = 执行层守护者 + +1. **代码守护** — 维护仓库代码质量、结构完整性 +2. **自动化执行** — 管理和运行 GitHub Actions 工作流 +3. **部署交付** — 自动部署到 guanghulab.com 服务器 +4. **通信桥接** — 维护 Notion ↔ GitHub 双向数据同步 +5. **巡检维护** — 每日自动巡检系统健康状态 +6. **信号处理** — 处理 SYSLOG、广播、开发者工单 +7. **状态上报** — 向 Notion(认知层)报告执行结果 + +--- + +## 数字地球六层模型 + +| 层级 | 名称 | 说明 | +|------|------|------| +| L1 | 地核 | TCS 自转核(曜冥语言核系统本体) | +| L2 | 地幔 | 母语词典(人格体间通用语言基础设施) | +| L3 | 地表 | 人格体运行层(知秋、霜砚、铸渊) | +| L4 | 大气层 | 信号总线(人格体间通信通道) | +| L5 | 卫星层 | Agent 执行层(GitHub Actions、自动化工具) | +| L6 | 太空层 | 外部交互层(用户/合作者/第三方接口) | + +--- + +*本文件由铸渊维护 · 系统版本 4.0 · 数字地球系统通信协议* diff --git a/brain/read-order.md b/brain/read-order.md new file mode 100644 index 00000000..7889994e --- /dev/null +++ b/brain/read-order.md @@ -0,0 +1,51 @@ +# 铸渊唤醒读取顺序 +# Read Order · v4.0 + +--- + +铸渊唤醒时,按以下顺序读取文件: + +## ① master-brain.md + +**路径**: `brain/master-brain.md` + +执行层系统导航主文件。了解: +- 系统版本(4.0) +- 三层结构(观察层 / 核心大脑 / 执行层) +- 铸渊职责定位 +- 核心入口索引 + +## ② repo-map.json + +**路径**: `brain/repo-map.json` + +仓库完整目录结构。了解: +- 所有一级和二级目录 +- 各目录用途说明 +- 仓库整体结构布局 + +## ③ automation-map.json + +**路径**: `brain/automation-map.json` + +自动化流程清单。了解: +- 所有 GitHub Actions workflow +- 定时任务(cron) +- 部署脚本 +- 数据同步脚本 +- 当前运行状态 + +## ④ system-health.json + +**路径**: `brain/system-health.json` + +系统健康状态。了解: +- 系统版本 +- 最近一次巡检时间 +- 通信状态 +- 自动化状态 +- 系统整体健康度 + +--- + +*读取完成后,铸渊即可进入完整工作状态。* diff --git a/brain/repo-map.json b/brain/repo-map.json new file mode 100644 index 00000000..dde182f8 --- /dev/null +++ b/brain/repo-map.json @@ -0,0 +1,294 @@ +{ + "version": "4.0", + "generated_at": "2026-03-14T01:00:00+08:00", + "generated_by": "scripts/generate-communication-map.js", + "description": "仓库目录结构地图 · 所有一级和二级目录及用途", + + "directories": { + ".github": { + "description": "GitHub 配置与自动化", + "subdirectories": { + "workflows": "GitHub Actions 工作流定义(41 个)", + "brain": "铸渊大脑核心文件(路由映射、记忆、协议)", + "persona-brain": "人格大脑(身份、知识库、开发者状态)", + "ISSUE_TEMPLATE": "Issue 模板", + "agents": "Agent 配置" + } + }, + "brain": { + "description": "执行层系统导航(v4.0 数字地球协议)", + "subdirectories": {} + }, + "src": { + "description": "HLI 接口源码(HoloLake Interface)", + "subdirectories": { + "routes": "HLI 路由定义(auth/brain/registry)", + "middleware": "中间件(鉴权等)", + "schemas": "HLI Schema 定义" + } + }, + "scripts": { + "description": "执行脚本库(41 个自动化脚本)", + "subdirectories": { + "utils": "工具函数(dev-suffix-map 等)" + } + }, + "backend": { + "description": "Express 后端 API(端口 3000)", + "subdirectories": { + "routes": "后端路由(notion/feishu/router/coldstart/developers)", + "tools": "后端工具", + "data": "后端数据" + } + }, + "backend-integration": { + "description": "AI Chat API 代理(端口 3721)+ Nginx 配置", + "subdirectories": {} + }, + "persona-studio": { + "description": "Persona Studio 工作台(端口 3002)", + "subdirectories": { + "backend": "Persona Studio 后端", + "frontend": "Persona Studio 前端", + "workspace": "工作空间" + } + }, + "persona-brain-db": { + "description": "人格大脑数据库(认知层执行投影)", + "subdirectories": { + "brain": "大脑核心数据", + "personas": "人格体数据", + "schemas": "数据库 Schema", + "scripts": "数据库脚本" + } + }, + "persona-telemetry": { + "description": "人格遥测系统", + "subdirectories": { + "dashboard": "遥测仪表盘", + "collectors": "数据采集器" + } + }, + "persona-selector": { + "description": "人格选择器", + "subdirectories": {} + }, + "dev-nodes": { + "description": "开发者节点(8 位开发者的配置/状态/广播收件箱)", + "subdirectories": { + "DEV-001": "页页", + "DEV-002": "肥猫", + "DEV-003": "燕樊", + "DEV-004": "之之", + "DEV-005": "小草莓", + "DEV-009": "花尔", + "DEV-010": "桔子", + "DEV-011": "匆匆那年" + } + }, + "broadcasts-outbox": { + "description": "广播发件箱(铸渊向各开发者发出的广播)", + "subdirectories": {} + }, + "broadcasts": { + "description": "广播存档", + "subdirectories": {} + }, + "signal-log": { + "description": "信号日志库(ESP 邮件信号收发日志)", + "subdirectories": { + "entries": "日志条目" + } + }, + "notion-push": { + "description": "Notion 推送队列", + "subdirectories": { + "pending": "待处理信号", + "processed": "已处理归档" + } + }, + "syslog-inbox": { + "description": "系统日志收件箱(待处理 SYSLOG)", + "subdirectories": {} + }, + "syslog-processed": { + "description": "已处理的系统日志", + "subdirectories": {} + }, + "syslog": { + "description": "系统日志模块", + "subdirectories": {} + }, + "modules": { + "description": "功能模块集合", + "subdirectories": { + "palace-game": "宫殿游戏模块", + "persona-ai-helper": "人格 AI 助手", + "persona-prompt-builder": "人格 Prompt 构建器" + } + }, + "m01-login": { + "description": "M01 登录模块", + "subdirectories": {} + }, + "m03-personality": { + "description": "M03 人格模块", + "subdirectories": {} + }, + "m05-user-center": { + "description": "M05 用户中心模块", + "subdirectories": {} + }, + "m06-ticket": { + "description": "M06 工单模块", + "subdirectories": {} + }, + "m07-dialogue-ui": { + "description": "M07 对话 UI 模块", + "subdirectories": {} + }, + "m10-cloud": { + "description": "M10 云存储模块", + "subdirectories": {} + }, + "m11-module": { + "description": "M11 模块管理", + "subdirectories": {} + }, + "m12-kanban": { + "description": "M12 看板模块", + "subdirectories": {} + }, + "m15-cloud-drive": { + "description": "M15 云盘模块", + "subdirectories": {} + }, + "m18-health-check": { + "description": "M18 健康检查模块", + "subdirectories": {} + }, + "docs": { + "description": "铸渊助手聊天界面(GitHub Pages 部署)", + "subdirectories": {} + }, + "tests": { + "description": "测试区(HLI 契约测试 + 冒烟测试)", + "subdirectories": { + "contract": "契约测试", + "smoke": "冒烟测试" + } + }, + "status-board": { + "description": "状态看板(WebSocket 推送 · 端口 8080)", + "subdirectories": { + "public": "前端资源" + } + }, + "app": { + "description": "Next.js 应用层", + "subdirectories": { + "api": "Next.js API 路由" + } + }, + "frontend": { + "description": "前端入口", + "subdirectories": {} + }, + "public": { + "description": "公共静态资源", + "subdirectories": {} + }, + "dashboard": { + "description": "仪表盘模块", + "subdirectories": {} + }, + "homepage": { + "description": "首页模块", + "subdirectories": {} + }, + "portal": { + "description": "门户模块", + "subdirectories": {} + }, + "guanghulab-main": { + "description": "光湖主工程(旧版结构)", + "subdirectories": {} + }, + "dingtalk-bot": { + "description": "钉钉机器人模块", + "subdirectories": {} + }, + "chat-bubble": { + "description": "聊天气泡组件", + "subdirectories": {} + }, + "cloud-drive": { + "description": "云盘模块(旧版)", + "subdirectories": {} + }, + "coldstart": { + "description": "冷启动模块", + "subdirectories": {} + }, + "collaboration-logs": { + "description": "协作日志", + "subdirectories": {} + }, + "cost-control": { + "description": "成本控制模块", + "subdirectories": {} + }, + "dynamic-comic-studio": { + "description": "动态漫画工作室", + "subdirectories": { + "backend": "后端", + "frontend": "前端" + } + }, + "help-center": { + "description": "帮助中心", + "subdirectories": {} + }, + "multi-persona": { + "description": "多人格管理模块", + "subdirectories": {} + }, + "notification": { + "description": "通知模块", + "subdirectories": {} + }, + "reports": { + "description": "报告与巡检记录", + "subdirectories": {} + }, + "search-filter": { + "description": "搜索过滤模块", + "subdirectories": { + "backend": "后端", + "frontend": "前端" + } + }, + "settings": { + "description": "设置模块", + "subdirectories": {} + }, + "style-system": { + "description": "样式系统(光湖设计语言)", + "subdirectories": { + "tokens": "设计 Token" + } + }, + "ticket-system": { + "description": "工单系统", + "subdirectories": {} + }, + "user-center": { + "description": "用户中心(旧版)", + "subdirectories": {} + }, + "utils": { + "description": "通用工具函数", + "subdirectories": {} + } + } +} diff --git a/brain/system-health.json b/brain/system-health.json new file mode 100644 index 00000000..13eb6f2d --- /dev/null +++ b/brain/system-health.json @@ -0,0 +1,16 @@ +{ + "version": "4.0", + "last_check": "2026-03-14 03:36:48+08:00", + "communication": "synced", + "automation": "stable", + "maintenance_agent": "active", + "system_health": "normal", + "brain_integrity": { + "complete": true, + "total": 7, + "present": 7, + "missing": [] + }, + "workflow_count": 42, + "checked_by": "scripts/generate-system-health.js" +} \ No newline at end of file diff --git a/package.json b/package.json index ff62c756..62aa0634 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,9 @@ "esp:process": "node scripts/esp-email-processor.js", "psp:inspect": "node scripts/psp-inspection.js", "repo:map": "node scripts/generate-repo-map.js", + "repo:automation-map": "node scripts/generate-automation-map.js", + "repo:communication-map": "node scripts/generate-communication-map.js", + "repo:system-health": "node scripts/generate-system-health.js", "deploy:agent": "node scripts/bingshuo-deploy-agent.js", "module:protocol": "node scripts/zhuyuan-module-protocol.js", "proxy:start": "node backend-integration/api-proxy.js", diff --git a/scripts/generate-automation-map.js b/scripts/generate-automation-map.js new file mode 100644 index 00000000..e3430201 --- /dev/null +++ b/scripts/generate-automation-map.js @@ -0,0 +1,157 @@ +// scripts/generate-automation-map.js +// 自动化地图生成器 · Automation Map Generator +// +// 功能:扫描 .github/workflows/ 和自动化脚本,生成 brain/automation-map.json +// 触发方式: +// - GitHub Actions: daily-maintenance.yml +// - 本地:node scripts/generate-automation-map.js + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.join(__dirname, '..'); +const BRAIN_DIR = path.join(ROOT, 'brain'); +const OUT_PATH = path.join(BRAIN_DIR, 'automation-map.json'); + +const now = new Date(); +const nowISO = now.toISOString(); + +// ── 工具函数 ── + +function safeRead(filePath) { + try { return fs.readFileSync(filePath, 'utf8'); } catch { return ''; } +} + +function listFiles(dirPath, ext) { + try { + return fs.readdirSync(dirPath) + .filter(f => !ext || f.endsWith(ext)) + .filter(f => !f.startsWith('.')); + } catch { return []; } +} + +// ── 解析单个 workflow ── + +function parseWorkflow(file, content) { + const nameMatch = content.match(/^name:\s*(.+)/m); + const name = nameMatch ? nameMatch[1].trim().replace(/^["']|["']$/g, '') : file; + + const triggers = []; + if (/^\s{2,4}push:/m.test(content)) triggers.push('push'); + if (/^\s{2,4}pull_request:/m.test(content)) triggers.push('pull_request'); + if (/^\s{2,4}issues:/m.test(content)) triggers.push('issues'); + if (/^\s{2,4}issue_comment:/m.test(content)) triggers.push('issue_comment'); + if (/workflow_dispatch/m.test(content)) triggers.push('workflow_dispatch'); + if (/workflow_call/m.test(content)) triggers.push('workflow_call'); + + const cronMatch = content.match(/cron:\s*['"]?([^'"#\n]+)/); + const cron = cronMatch ? cronMatch[1].trim() : null; + if (cron) triggers.push('schedule'); + + // Detect scripts used + const scriptRefs = []; + const scriptMatches = content.matchAll(/node\s+scripts\/([^\s'"]+)/g); + for (const m of scriptMatches) { + scriptRefs.push('scripts/' + m[1]); + } + + const result = { + file, + name, + triggers: triggers.length ? triggers : ['unknown'] + }; + + if (cron) result.cron = cron; + if (scriptRefs.length) result.scripts = scriptRefs; + + return result; +} + +// ── 扫描所有 workflow ── + +function scanWorkflows() { + const wfDir = path.join(ROOT, '.github/workflows'); + const files = listFiles(wfDir, '.yml'); + return files.map(f => { + const content = safeRead(path.join(wfDir, f)); + return parseWorkflow(f, content); + }); +} + +// ── 提取 cron jobs ── + +function extractCronJobs(workflows) { + return workflows + .filter(w => w.cron) + .map(w => ({ + cron: w.cron, + workflow: w.file, + name: w.name + })) + .sort((a, b) => a.cron.localeCompare(b.cron)); +} + +// ── 扫描部署脚本 ── + +function scanDeployScripts(workflows) { + return workflows + .filter(w => /deploy/i.test(w.file) || /deploy/i.test(w.name)) + .map(w => ({ + workflow: w.file, + name: w.name, + triggers: w.triggers + })); +} + +// ── 扫描同步脚本 ── + +function scanSyncScripts() { + const scriptDir = path.join(ROOT, 'scripts'); + const files = listFiles(scriptDir, '.js'); + const syncScripts = []; + + for (const file of files) { + const content = safeRead(path.join(scriptDir, file)); + if (/sync|bridge|push-broadcast|receive|process-broadcast/i.test(file) || + /notion.*api|@notionhq/i.test(content)) { + syncScripts.push({ + script: 'scripts/' + file, + type: /sync/i.test(file) ? 'sync' : + /bridge/i.test(file) ? 'bridge' : + /broadcast/i.test(file) ? 'broadcast' : 'other' + }); + } + } + + return syncScripts; +} + +// ── 主生成 ── + +function generate() { + if (!fs.existsSync(BRAIN_DIR)) fs.mkdirSync(BRAIN_DIR, { recursive: true }); + + const workflows = scanWorkflows(); + const cronJobs = extractCronJobs(workflows); + const deployScripts = scanDeployScripts(workflows); + const syncScripts = scanSyncScripts(); + + const map = { + version: '4.0', + generated_at: nowISO, + generated_by: 'scripts/generate-automation-map.js', + description: '数字地球系统自动化地图 · 所有工作流与自动化脚本', + workflows, + cron_jobs: cronJobs, + deploy_scripts: deployScripts, + data_sync_scripts: syncScripts, + status: 'stable' + }; + + fs.writeFileSync(OUT_PATH, JSON.stringify(map, null, 2)); + console.log(`✅ automation-map.json 已生成 · ${workflows.length} 个工作流 · ${cronJobs.length} 个定时任务`); +} + +generate(); diff --git a/scripts/generate-communication-map.js b/scripts/generate-communication-map.js new file mode 100644 index 00000000..39233ff5 --- /dev/null +++ b/scripts/generate-communication-map.js @@ -0,0 +1,182 @@ +// scripts/generate-communication-map.js +// 通信地图生成器 · Communication Map Generator +// +// 功能:扫描仓库中的 API 端点、webhook、同步脚本,生成 brain/communication-map.json +// 触发方式: +// - GitHub Actions: daily-maintenance.yml +// - 本地:node scripts/generate-communication-map.js + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.join(__dirname, '..'); +const BRAIN_DIR = path.join(ROOT, 'brain'); +const OUT_PATH = path.join(BRAIN_DIR, 'communication-map.json'); + +const now = new Date(); +const nowISO = now.toISOString(); + +// ── 工具函数 ── + +function safeRead(filePath) { + try { return fs.readFileSync(filePath, 'utf8'); } catch { return ''; } +} + +function listFiles(dirPath, ext) { + try { + return fs.readdirSync(dirPath) + .filter(f => !ext || f.endsWith(ext)) + .filter(f => !f.startsWith('.')); + } catch { return []; } +} + +// ── 扫描 HLI 路由 ── + +function scanHLIRoutes() { + const routeDir = path.join(ROOT, 'src/routes/hli'); + const routes = []; + + function scanDir(dir, prefix) { + const files = listFiles(dir, '.js'); + for (const file of files) { + const content = safeRead(path.join(dir, file)); + const matches = content.matchAll(/router\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"]/g); + for (const m of matches) { + routes.push({ + method: m[1].toUpperCase(), + path: prefix + m[2], + file: path.relative(ROOT, path.join(dir, file)) + }); + } + } + + try { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const e of entries) { + if (e.isDirectory()) { + scanDir(path.join(dir, e.name), prefix + '/' + e.name); + } + } + } catch { /* ignore */ } + } + + scanDir(routeDir, '/hli'); + return routes; +} + +// ── 扫描 backend 路由 ── + +function scanBackendRoutes() { + const serverFile = path.join(ROOT, 'backend/server.js'); + const content = safeRead(serverFile); + const routes = []; + const matches = content.matchAll(/app\.use\s*\(\s*['"]([^'"]+)['"]/g); + for (const m of matches) { + routes.push({ method: '*', path: m[1], file: 'backend/server.js' }); + } + // Check for webhook + const webhooks = content.matchAll(/app\.(post|get)\s*\(\s*['"]([^'"]+)['"]/g); + for (const m of webhooks) { + routes.push({ method: m[1].toUpperCase(), path: m[2], file: 'backend/server.js' }); + } + return routes; +} + +// ── 扫描 Notion 同步脚本 ── + +function scanSyncScripts() { + const scriptDir = path.join(ROOT, 'scripts'); + const files = listFiles(scriptDir, '.js'); + const syncScripts = []; + + for (const file of files) { + const content = safeRead(path.join(scriptDir, file)); + const isNotion = /NOTION|@notionhq|notion/i.test(content); + const isSync = /sync|bridge|push/i.test(file); + const isHTTP = /fetch\(|axios|https?\.request/i.test(content); + + if (isNotion || isSync) { + let direction = 'unknown'; + if (/bridge/i.test(file)) direction = 'bidirectional'; + else if (/push|sync-login|broadcast/i.test(file)) direction = 'github_to_external'; + else if (/receive|poll|heartbeat/i.test(file)) direction = 'external_to_github'; + else if (isNotion) direction = 'github_to_notion'; + + syncScripts.push({ + script: 'scripts/' + file, + direction, + uses_notion_api: isNotion, + uses_http: isHTTP + }); + } + } + + return syncScripts; +} + +// ── 扫描触发路径 ── + +function scanTriggerPaths() { + const wfDir = path.join(ROOT, '.github/workflows'); + const files = listFiles(wfDir, '.yml'); + const githubToNotion = []; + const notionToGithub = []; + + for (const file of files) { + const content = safeRead(path.join(wfDir, file)); + const nameMatch = content.match(/^name:\s*(.+)/m); + const name = nameMatch ? nameMatch[1].trim().replace(/^["']|["']$/g, '') : file; + + if (/notion.*bridge|bridge.*notion|syslog.*notion|changes.*notion|session.*summary/i.test(name) || + /notion-bridge|receive-syslog|push-broadcast|sync-login/i.test(content)) { + githubToNotion.push({ workflow: file, name }); + } + if (/notion.*poll|heartbeat|persona.*invoke|process.*notion|notion.*order/i.test(name) || + /notion-signal-bridge|notion-heartbeat|invoke-persona/i.test(content)) { + notionToGithub.push({ workflow: file, name }); + } + } + + return { github_to_notion: githubToNotion, notion_to_github: notionToGithub }; +} + +// ── 主生成 ── + +function generate() { + if (!fs.existsSync(BRAIN_DIR)) fs.mkdirSync(BRAIN_DIR, { recursive: true }); + + const hliRoutes = scanHLIRoutes(); + const backendRoutes = scanBackendRoutes(); + const syncScripts = scanSyncScripts(); + const triggerPaths = scanTriggerPaths(); + + // Read existing for merge + let existing = {}; + try { existing = JSON.parse(fs.readFileSync(OUT_PATH, 'utf8')); } catch { /* new file */ } + + const map = { + version: existing.version || '4.0', + generated_at: nowISO, + generated_by: 'scripts/generate-communication-map.js', + description: '数字地球系统通信地图 · 所有通信入口与数据流', + api_endpoints: existing.api_endpoints || {}, + webhook_endpoints: existing.webhook_endpoints || [], + trigger_paths: triggerPaths, + data_sync_scripts: syncScripts, + automation_flows: existing.automation_flows || [], + scan_results: { + hli_routes_found: hliRoutes.length, + backend_routes_found: backendRoutes.length, + sync_scripts_found: syncScripts.length, + hli_routes: hliRoutes, + backend_routes: backendRoutes + } + }; + + fs.writeFileSync(OUT_PATH, JSON.stringify(map, null, 2)); + console.log(`✅ communication-map.json 已生成 · ${hliRoutes.length} HLI 路由 · ${syncScripts.length} 同步脚本`); +} + +generate(); diff --git a/scripts/generate-system-health.js b/scripts/generate-system-health.js new file mode 100644 index 00000000..f3b7b993 --- /dev/null +++ b/scripts/generate-system-health.js @@ -0,0 +1,96 @@ +// scripts/generate-system-health.js +// 系统健康状态生成器 · System Health Generator +// +// 功能:巡检 brain/ 目录完整性和系统状态,更新 brain/system-health.json +// 触发方式: +// - GitHub Actions: daily-maintenance.yml +// - 本地:node scripts/generate-system-health.js + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.join(__dirname, '..'); +const BRAIN_DIR = path.join(ROOT, 'brain'); +const OUT_PATH = path.join(BRAIN_DIR, 'system-health.json'); + +const now = new Date(); +const nowISO = now.toISOString(); +const nowBJ = new Date(now.getTime() + 8 * 3600 * 1000).toISOString() + .replace('T', ' ').slice(0, 19) + '+08:00'; + +// ── 巡检 brain/ 目录完整性 ── + +function checkBrainIntegrity() { + const required = [ + 'master-brain.md', + 'read-order.md', + 'repo-map.json', + 'automation-map.json', + 'communication-map.json', + 'id-map.json', + 'system-health.json' + ]; + + const missing = []; + const present = []; + + for (const file of required) { + const filePath = path.join(BRAIN_DIR, file); + if (fs.existsSync(filePath)) { + present.push(file); + } else { + missing.push(file); + } + } + + return { + complete: missing.length === 0, + total: required.length, + present: present.length, + missing + }; +} + +// ── 检查 workflow 目录 ── + +function checkWorkflows() { + const wfDir = path.join(ROOT, '.github/workflows'); + try { + const files = fs.readdirSync(wfDir).filter(f => f.endsWith('.yml')); + return { count: files.length, status: files.length > 0 ? 'stable' : 'warning' }; + } catch { + return { count: 0, status: 'error' }; + } +} + +// ── 主生成 ── + +function generate() { + if (!fs.existsSync(BRAIN_DIR)) fs.mkdirSync(BRAIN_DIR, { recursive: true }); + + const brainCheck = checkBrainIntegrity(); + const wfCheck = checkWorkflows(); + + const health = { + version: '4.0', + last_check: nowBJ, + communication: 'synced', + automation: wfCheck.status, + maintenance_agent: 'active', + system_health: brainCheck.complete ? 'normal' : 'warning', + brain_integrity: brainCheck, + workflow_count: wfCheck.count, + checked_by: 'scripts/generate-system-health.js' + }; + + fs.writeFileSync(OUT_PATH, JSON.stringify(health, null, 2)); + console.log(`✅ system-health.json 已更新 · brain完整性: ${brainCheck.present}/${brainCheck.total} · 工作流: ${wfCheck.count}`); + + if (brainCheck.missing.length > 0) { + console.log(`⚠️ 缺失文件: ${brainCheck.missing.join(', ')}`); + } +} + +generate();