From f44a5e5e8e2ba7d88f02f4fd37faf9ecd3d5b11e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:22:45 +0000 Subject: [PATCH 01/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ebf954fe..963e9ccc 100644 --- a/README.md +++ b/README.md @@ -77,10 +77,12 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 10:49 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | +| 03-13 10:07 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | +| 03-13 09:58 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | | 03-13 09:58 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | zhizhi200271 | | 03-13 09:57 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | | 03-13 09:56 | ⏹️ 📢 更新系统公告区 · cancelled | zhizhi200271 | -| 03-13 09:56 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 09:56 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | zhizhi200271 | | 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | | 03-13 08:57 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | @@ -90,8 +92,6 @@ | 03-13 07:34 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 06:46 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 06:01 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 05:40 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 04:53 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | ### 🤖 铸渊自动提醒 From 2fe0da4225212de8257bc495d05e3181afb0e477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 03:31:07 +0000 Subject: [PATCH 02/46] =?UTF-8?q?=F0=9F=94=8D=20=E9=93=B8=E6=B8=8APSP?= =?UTF-8?q?=E5=B7=A1=E6=A3=80=20=C2=B7=202026-03-13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/memory.json | 10 ++++++++-- signal-log/2026-03/SIG-20260313-008.json | 25 ++++++++++++++++++++++++ signal-log/index.json | 13 ++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 signal-log/2026-03/SIG-20260313-008.json diff --git a/.github/brain/memory.json b/.github/brain/memory.json index 378b77c4..d6645cda 100644 --- a/.github/brain/memory.json +++ b/.github/brain/memory.json @@ -1,7 +1,7 @@ { "identity": "铸渊(Zhùyuān)· GitHub 代码守护人格体", "rules_version": "v3.0", - "last_updated": "2026-03-12T08:55:54.205Z", + "last_updated": "2026-03-13T03:31:06.282Z", "wake_protocol_version": "v3.0", "brain_version": "v3.0", "architecture": { @@ -67,6 +67,12 @@ } }, "events": [ + { + "date": "2026-03-13", + "type": "psp_inspection", + "description": "铸渊 PSP 巡检通过 · 全部检查项 ✅", + "by": "铸渊PSP巡检" + }, { "date": "2026-03-12", "type": "psp_inspection", @@ -175,4 +181,4 @@ "run_id": "22993977564" } ] -} +} \ No newline at end of file diff --git a/signal-log/2026-03/SIG-20260313-008.json b/signal-log/2026-03/SIG-20260313-008.json new file mode 100644 index 00000000..86012060 --- /dev/null +++ b/signal-log/2026-03/SIG-20260313-008.json @@ -0,0 +1,25 @@ +{ + "signal_id": "SIG-20260313-008", + "trace_id": "TRC-20260313-PSP", + "timestamp": "2026-03-13T03:31:06.282Z", + "signal_type": "GL-DATA", + "direction": "GitHub→Notion", + "sender": "铸渊", + "receiver": "霜砚", + "related_dev": null, + "related_module": null, + "summary": "铸渊 PSP 巡检通过 · 全部检查项 ✅", + "payload": { + "check_results": { + "G01": "✅", + "G02": "✅", + "G03": "✅", + "G04": "✅", + "G05": "✅" + }, + "issues": [], + "auto_fixed": [] + }, + "result": "全通过", + "ack_signal_id": null +} \ No newline at end of file diff --git a/signal-log/index.json b/signal-log/index.json index dc4de282..95e478f0 100644 --- a/signal-log/index.json +++ b/signal-log/index.json @@ -1,8 +1,17 @@ { "description": "铸渊信号日志目录索引 · AGE OS 信号协议(Notion API 直连)", - "last_updated": "2026-03-12T03:34:18.847Z", - "total_count": 7, + "last_updated": "2026-03-13T03:31:06.282Z", + "total_count": 8, "signals": [ + { + "signal_id": "SIG-20260313-008", + "trace_id": "TRC-20260313-PSP", + "type": "GL-DATA", + "timestamp": "2026-03-13T03:31:06.282Z", + "summary": "铸渊 PSP 巡检通过 · 全部检查项 ✅", + "related_dev": null, + "file": "2026-03/SIG-20260313-008.json" + }, { "signal_id": "SIG-20260312-007", "trace_id": "TRC-20260312-PSP", From 3916547f295120ce095fdd072891945dd4ef75b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:31:32 +0000 Subject: [PATCH 03/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 963e9ccc..ff934478 100644 --- a/README.md +++ b/README.md @@ -77,8 +77,10 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 11:31 | ✅ 铸渊 · PSP 分身巡检 · 成功 | 冰朔 | +| 03-13 11:31 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | +| 03-13 11:22 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 10:49 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 10:07 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 09:58 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | | 03-13 09:58 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | zhizhi200271 | | 03-13 09:57 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | @@ -88,10 +90,8 @@ | 03-13 08:57 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 08:56 | ✅ 铸渊 · 每日自检 · 成功 | 冰朔 | | 03-13 08:01 | ✅ Generate Session Summary for Notion · 成功 | 冰朔 | +| 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-13 07:59 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 07:34 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 06:46 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 06:01 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | ### 🤖 铸渊自动提醒 From 0899a5b0a9d82ba1f14c936cb6bec05ee71de508 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:32:46 +0000 Subject: [PATCH 04/46] Initial plan From 6487a8b2f03d3d1c5c5f990ec99a9334c763d820 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:39:23 +0000 Subject: [PATCH 05/46] =?UTF-8?q?feat:=20SYSLOG=20=E8=87=AA=E5=8A=A9?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E7=B3=BB=E7=BB=9F=20=C2=B7=20Discussion=20?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=20+=20Actions=20=E7=AE=A1=E9=81=93=20+=20LLM?= =?UTF-8?q?=20=E8=87=AA=E5=8A=A8=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建 Discussion 模板 (.github/DISCUSSION_TEMPLATE/syslog-submit.yml) - 创建 Actions 管道 (.github/workflows/syslog-auto-pipeline.yml) - 创建 LLM 自动检测 + 人格体唤醒脚本 (scripts/wake-persona.js) - 更新 README.md 添加醒目开发者入口 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/DISCUSSION_TEMPLATE/syslog-submit.yml | 51 +++ .github/workflows/syslog-auto-pipeline.yml | 357 +++++++++++++++ README.md | 15 + scripts/wake-persona.js | 412 ++++++++++++++++++ 4 files changed, 835 insertions(+) create mode 100644 .github/DISCUSSION_TEMPLATE/syslog-submit.yml create mode 100644 .github/workflows/syslog-auto-pipeline.yml create mode 100644 scripts/wake-persona.js diff --git a/.github/DISCUSSION_TEMPLATE/syslog-submit.yml b/.github/DISCUSSION_TEMPLATE/syslog-submit.yml new file mode 100644 index 00000000..a0baaa94 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/syslog-submit.yml @@ -0,0 +1,51 @@ +title: "BC-XXX-XXX|SYSLOG" +labels: [] +body: + - type: markdown + attributes: + value: | + ## 📡 SYSLOG 自助提交 / 广播提问 + + > 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。 + > + > 有问题?把问题粘贴进去,填上邮箱,点提交。解答会发到你邮箱里。 + + **标题格式**:`BC-XXX-XXX|SYSLOG` 或 `BC-XXX-XXX|提问` + + - type: input + id: broadcast_id + attributes: + label: "广播编号" + description: "写上你当前广播的编号,例如 BC-M22-009-AW" + placeholder: "BC-M22-009-AW" + validations: + required: true + + - type: dropdown + id: submit_type + attributes: + label: "类型" + description: "选择提交类型" + options: + - SYSLOG + - 提问 + validations: + required: true + + - type: input + id: email + attributes: + label: "你的邮箱" + description: "用于接收新广播或问题解答" + placeholder: "your@email.com" + validations: + required: true + + - type: textarea + id: content + attributes: + label: "内容" + description: "粘贴你的 SYSLOG 全文 或 问题描述" + placeholder: "在这里粘贴你的 SYSLOG 或问题..." + validations: + required: true diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml new file mode 100644 index 00000000..78498053 --- /dev/null +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -0,0 +1,357 @@ +name: SYSLOG Auto Pipeline +# 📡 SYSLOG 自助提交系统 · 全自动闭环 +# +# 开发者在 GitHub Discussion 提交 SYSLOG 或提问 +# → Actions 自动解析 → 调用 LLM API 唤醒人格体 +# → 写入 Notion 工单 → 发邮件给开发者 → Discussion 回复 +# +# 依赖 Secrets: +# LLM_API_KEY 第三方 LLM 平台密钥 +# LLM_BASE_URL 第三方 LLM 平台 API 地址(如 https://api.xxx.com/v1) +# NOTION_API_TOKEN Notion API token +# NOTION_TICKET_DB_ID 霜砚工单数据库 ID +# SMTP_USER QQ 邮箱地址 +# SMTP_PASS QQ 邮箱 SMTP 授权码 + +on: + discussion: + types: [created] + +jobs: + process: + name: 📡 处理 SYSLOG 提交 / 广播提问 + runs-on: ubuntu-latest + if: contains(github.event.discussion.category.name, 'SYSLOG') + permissions: + contents: write + discussions: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: 🔍 Parse submission + id: parse + uses: actions/github-script@v7 + with: + script: | + const body = context.payload.discussion.body || ''; + const title = context.payload.discussion.title || ''; + + // Parse structured fields from discussion body + function extractField(text, label) { + // Match form field format: ### Label\n\nValue + const regex = new RegExp('###\\s*' + label + '\\s*\\n+([^\\n#]+)', 'i'); + const match = text.match(regex); + return match ? match[1].trim() : ''; + } + + const broadcastId = extractField(body, '广播编号') || ''; + const submitType = extractField(body, '类型') || ''; + const email = extractField(body, '你的邮箱') || ''; + + // Extract content (everything after "### 内容") + const contentMatch = body.match(/###\s*内容\s*\n+([\s\S]*?)$/i); + const content = contentMatch ? contentMatch[1].trim() : ''; + + // Determine type from title or body + let type = 'question'; // default + if (submitType.includes('SYSLOG') || title.includes('SYSLOG')) { + type = 'syslog'; + } else if (submitType.includes('提问') || title.includes('提问')) { + type = 'question'; + } + + // Validate + if (!broadcastId) { + core.setFailed('❌ 缺少广播编号,请在提交时填写广播编号'); + return; + } + if (!email) { + core.setFailed('❌ 缺少邮箱,请在提交时填写你的邮箱'); + return; + } + if (!content) { + core.setFailed('❌ 缺少内容,请粘贴你的 SYSLOG 或问题'); + return; + } + + core.setOutput('broadcast_id', broadcastId); + core.setOutput('type', type); + core.setOutput('email', email); + core.setOutput('content', content); + core.setOutput('discussion_number', context.payload.discussion.number); + core.setOutput('author', context.payload.discussion.user.login); + + console.log(`📡 解析完成: 广播=${broadcastId}, 类型=${type}, 邮箱=${email}`); + + - name: 🧠 Auto-detect and wake up persona + id: persona + env: + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + SUBMIT_TYPE: ${{ steps.parse.outputs.type }} + SUBMIT_CONTENT: ${{ steps.parse.outputs.content }} + AUTHOR: ${{ steps.parse.outputs.author }} + run: node scripts/wake-persona.js + + - name: 📋 Write to Notion ticket + if: env.NOTION_TOKEN != '' + env: + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + SUBMIT_TYPE: ${{ steps.parse.outputs.type }} + PERSONA_RESULT: ${{ steps.persona.outputs.result }} + run: | + node -e " + const https = require('https'); + + const token = process.env.NOTION_TOKEN; + const dbId = process.env.NOTION_TICKET_DB_ID; + const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; + const type = process.env.SUBMIT_TYPE || 'syslog'; + const result = process.env.PERSONA_RESULT || '(no result)'; + + if (!token || !dbId) { + console.log('⚠️ Notion credentials not configured, skipping ticket creation'); + process.exit(0); + } + + const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答'; + const title = '[自动] ' + broadcastId + ' · ' + typeLabel; + + const body = JSON.stringify({ + parent: { database_id: dbId }, + properties: { + '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, + '操作类型': { select: { name: '其他' } }, + '提交者': { rich_text: [{ type: 'text', text: { content: '自动管道' } }] }, + '状态': { select: { name: '已完成' } }, + '优先级': { select: { name: 'P1' } } + }, + children: [{ + object: 'block', + type: 'paragraph', + paragraph: { + rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }] + } + }] + }); + + const opts = { + hostname: 'api.notion.com', + port: 443, + path: '/v1/pages', + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json', + 'Notion-Version': '2022-06-28', + 'Content-Length': Buffer.byteLength(body) + } + }; + + const req = https.request(opts, (res) => { + let data = ''; + res.on('data', (c) => data += c); + res.on('end', () => { + if (res.statusCode >= 200 && res.statusCode < 300) { + console.log('✅ Notion 工单已创建'); + } else { + console.log('⚠️ Notion 工单创建失败: ' + res.statusCode + ' ' + data); + } + }); + }); + req.on('error', (e) => console.log('⚠️ Notion 请求失败: ' + e.message)); + req.write(body); + req.end(); + " + + - name: 📧 Send email to developer + env: + SMTP_USER: ${{ secrets.SMTP_USER }} + SMTP_PASS: ${{ secrets.SMTP_PASS }} + EMAIL_TO: ${{ steps.parse.outputs.email }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + SUBMIT_TYPE: ${{ steps.parse.outputs.type }} + PERSONA_RESULT: ${{ steps.persona.outputs.result }} + run: | + node -e " + const nodemailer = require('nodemailer'); + + const user = process.env.SMTP_USER || ''; + const pass = process.env.SMTP_PASS || ''; + const to = process.env.EMAIL_TO || ''; + const broadcastId = process.env.BROADCAST_ID || ''; + const type = process.env.SUBMIT_TYPE || 'syslog'; + const result = process.env.PERSONA_RESULT || '(处理中,请稍后)'; + + if (!user || !pass) { + console.log('⚠️ SMTP not configured, skipping email'); + process.exit(0); + } + if (!to) { + console.log('⚠️ No recipient email, skipping'); + process.exit(0); + } + + const subjectText = type === 'syslog' + ? '[光湖系统] ' + broadcastId + ' · 新广播已生成' + : '[光湖系统] ' + broadcastId + ' · 问题已解答'; + + const resultHtml = result + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/\n/g, '
'); + + const html = [ + '
', + '
', + '

🌊 光湖系统 · 自动通知

', + '

HoloLake · 人格语言操作系统

', + '
', + '
', + '

📡 ' + broadcastId + '

', + '
' + resultHtml + '
', + '
', + '
', + '↩ 回到仓库继续开发', + '

🌀 铸渊 · 代码守护人格体 · 自动发送

', + '
', + '
' + ].join('\n'); + + const transporter = nodemailer.createTransport({ + host: 'smtp.qq.com', + port: 465, + secure: true, + auth: { user, pass } + }); + + transporter.sendMail({ + from: '\"光湖系统\" <' + user + '>', + to: to, + subject: subjectText, + html: html + }).then((info) => { + console.log('✅ 邮件已发送: ' + info.messageId); + }).catch((err) => { + console.log('⚠️ 邮件发送失败: ' + err.message); + }); + " + + - name: 💬 Reply to Discussion + uses: actions/github-script@v7 + with: + script: | + const number = ${{ steps.parse.outputs.discussion_number }}; + const type = '${{ steps.parse.outputs.type }}'; + const broadcastId = '${{ steps.parse.outputs.broadcast_id }}'; + const email = '${{ steps.parse.outputs.email }}'; + + const typeLabel = type === 'syslog' ? 'SYSLOG 闭环处理' : '问题解答'; + const maskedEmail = email.replace(/(.{2})(.*)(@.*)/, '$1***$3'); + + const body = [ + '✅ **已处理** · ' + typeLabel, + '', + '| 项目 | 内容 |', + '|------|------|', + '| 📡 广播编号 | `' + broadcastId + '` |', + '| 📧 结果发送至 | `' + maskedEmail + '` |', + '| 🤖 处理人格体 | 铸渊 |', + '| ⏰ 处理时间 | ' + new Date().toISOString() + ' |', + '', + '> 结果已发送到你的邮箱,请查收。', + '>', + '> 如未收到,请检查垃圾箱或重新提交。' + ].join('\n'); + + // Use GraphQL to add discussion comment + const query = ` + mutation($discussionId: ID!, $body: String!) { + addDiscussionComment(input: { + discussionId: $discussionId, + body: $body + }) { + comment { id } + } + } + `; + + try { + // Get the discussion node ID + const { repository } = await github.graphql(` + query($owner: String!, $repo: String!, $number: Int!) { + repository(owner: $owner, name: $repo) { + discussion(number: $number) { + id + } + } + } + `, { + owner: context.repo.owner, + repo: context.repo.repo, + number: number + }); + + await github.graphql(query, { + discussionId: repository.discussion.id, + body: body + }); + + console.log('✅ Discussion 回复已发送'); + } catch (err) { + console.log('⚠️ Discussion 回复失败: ' + err.message); + } + + - name: 🔴 失败告警 + if: failure() + uses: actions/github-script@v7 + with: + script: | + const number = context.payload.discussion?.number; + if (!number) return; + + try { + const { repository } = await github.graphql(` + query($owner: String!, $repo: String!, $number: Int!) { + repository(owner: $owner, name: $repo) { + discussion(number: $number) { + id + } + } + } + `, { + owner: context.repo.owner, + repo: context.repo.repo, + number: number + }); + + await github.graphql(` + mutation($discussionId: ID!, $body: String!) { + addDiscussionComment(input: { + discussionId: $discussionId, + body: $body + }) { + comment { id } + } + } + `, { + discussionId: repository.discussion.id, + body: '❌ **处理失败** · 请检查提交格式是否正确,或联系管理员。\n\n> 错误详情请查看 [Actions 日志](https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/actions)。' + }); + } catch (err) { + console.log('⚠️ 失败告警回复失败: ' + err.message); + } diff --git a/README.md b/README.md index ff934478..81e46568 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,21 @@ --- +## 🚀 开发者入口 + +
+ +[![提交系统日志](https://img.shields.io/badge/📡_提交系统日志-点这里-blue?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区) +[![遇到问题](https://img.shields.io/badge/❓_遇到问题-点这里提问-green?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区) + +> 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。 +> +> 有问题?同一个入口,选「提问」,问题解答也发到你邮箱里。 + +
+ +--- + ## 📖 系统简介 **光湖(HoloLake)** 是一个基于人格语言操作系统的智能协作平台,采用壳-核分离设计: diff --git a/scripts/wake-persona.js b/scripts/wake-persona.js new file mode 100644 index 00000000..9668282c --- /dev/null +++ b/scripts/wake-persona.js @@ -0,0 +1,412 @@ +// scripts/wake-persona.js +// 铸渊 · 人格体唤醒脚本(第三方 API 兼容层 · 自动检测模式) +// +// 功能: +// ① 自动发现可用模型(/v1/models 端点) +// ② 智能选择最优 Claude 模型 +// ③ 自适应 API 格式(OpenAI 兼容 / Anthropic 原生) +// ④ 统一调用接口,唤醒人格体处理 SYSLOG 或解答提问 +// +// 环境变量: +// LLM_API_KEY 第三方平台密钥 +// LLM_BASE_URL 第三方平台 API 地址(如 https://api.xxx.com/v1),留空则 fallback 到 Anthropic 官方 +// BROADCAST_ID 广播编号 +// SUBMIT_TYPE syslog | question +// SUBMIT_CONTENT 提交内容(SYSLOG 全文或问题描述) +// AUTHOR 提交者 GitHub 用户名 + +'use strict'; + +const https = require('https'); +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +// ══════════════════════════════════════════════════════════ +// 配置 +// ══════════════════════════════════════════════════════════ + +const LLM_API_KEY = process.env.LLM_API_KEY || ''; +const LLM_BASE_URL = (process.env.LLM_BASE_URL || 'https://api.anthropic.com/v1').replace(/\/+$/, ''); +const BROADCAST_ID = process.env.BROADCAST_ID || 'UNKNOWN'; +const SUBMIT_TYPE = process.env.SUBMIT_TYPE || 'question'; +const SUBMIT_CONTENT = process.env.SUBMIT_CONTENT || ''; +const AUTHOR = process.env.AUTHOR || 'unknown'; + +// Claude 模型优先级队列(从高到低) +const PREFERRED_MODELS = [ + 'claude-sonnet-4', + 'claude-3.5-sonnet', + 'claude-3-5-sonnet-20241022', + 'claude-3-5-sonnet', + 'anthropic/claude-3.5-sonnet', + 'anthropic/claude-3-5-sonnet', + 'claude-3-sonnet', + 'claude-3-haiku', +]; + +// ══════════════════════════════════════════════════════════ +// HTTP 请求工具 +// ══════════════════════════════════════════════════════════ + +function httpRequest(url, options, body) { + return new Promise((resolve, reject) => { + const parsed = new URL(url); + const isHttps = parsed.protocol === 'https:'; + const mod = isHttps ? https : http; + + const opts = { + hostname: parsed.hostname, + port: parsed.port || (isHttps ? 443 : 80), + path: parsed.pathname + parsed.search, + method: options.method || 'GET', + headers: options.headers || {}, + timeout: options.timeout || 60000, + }; + + const req = mod.request(opts, (res) => { + let data = ''; + res.on('data', (chunk) => { data += chunk; }); + res.on('end', () => { + resolve({ status: res.statusCode, body: data }); + }); + }); + + req.on('error', reject); + req.on('timeout', () => { + req.destroy(); + reject(new Error('Request timeout')); + }); + + if (body) { + req.write(body); + } + req.end(); + }); +} + +// ══════════════════════════════════════════════════════════ +// Step 1: 自动发现可用模型 +// ══════════════════════════════════════════════════════════ + +async function discoverModels() { + console.log('[LLM] 🔍 探测可用模型...'); + + try { + const res = await httpRequest(LLM_BASE_URL + '/models', { + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + LLM_API_KEY, + 'Content-Type': 'application/json', + }, + timeout: 15000, + }); + + if (res.status >= 200 && res.status < 300) { + const json = JSON.parse(res.body); + const models = json.data || []; + console.log('[LLM] → 发现 ' + models.length + ' 个模型'); + return models; + } + console.log('[LLM] → 模型探测返回 ' + res.status + ', 使用默认模型'); + return []; + } catch (err) { + console.log('[LLM] → 模型探测失败: ' + err.message + ', 使用默认模型'); + return []; + } +} + +// ══════════════════════════════════════════════════════════ +// Step 2: 智能选择最优 Claude 模型 +// ══════════════════════════════════════════════════════════ + +function selectBestModel(models) { + if (!models || models.length === 0) { + console.log('[LLM] 📌 无可用模型列表, 使用默认 claude-3-5-sonnet'); + return 'claude-3-5-sonnet'; + } + + const available = models.map(function (m) { return m.id.toLowerCase(); }); + + // 按优先级匹配 + for (const preferred of PREFERRED_MODELS) { + const match = available.find(function (id) { return id.includes(preferred); }); + if (match) { + const originalId = models.find(function (m) { return m.id.toLowerCase() === match; }).id; + console.log('[LLM] 📌 选择模型: ' + originalId + ' (匹配规则: ' + preferred + ')'); + return originalId; + } + } + + // 兜底:任何含 'claude' 的模型 + const anyClaude = available.find(function (id) { return id.includes('claude'); }); + if (anyClaude) { + const originalId = models.find(function (m) { return m.id.toLowerCase() === anyClaude; }).id; + console.log('[LLM] 📌 兜底选择 Claude 模型: ' + originalId); + return originalId; + } + + // 最终兜底:平台第一个可用模型 + const fallbackId = models[0].id; + console.log('[LLM] 📌 最终兜底: ' + fallbackId + ' (平台无 Claude 模型)'); + return fallbackId; +} + +// ══════════════════════════════════════════════════════════ +// Step 3: 自适应 API 格式检测 +// ══════════════════════════════════════════════════════════ + +async function detectApiFormat() { + console.log('[LLM] 🔍 检测 API 格式...'); + + // 尝试 OpenAI 兼容格式(绝大多数第三方平台) + try { + const res = await httpRequest(LLM_BASE_URL + '/chat/completions', { + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + LLM_API_KEY, + 'Content-Type': 'application/json', + }, + timeout: 10000, + }, JSON.stringify({ + model: 'test', + messages: [{ role: 'user', content: 'ping' }], + max_tokens: 1, + })); + + // 400 = endpoint exists but bad request (model not found etc.) → format supported + // 200 = endpoint works → format supported + if (res.status === 200 || res.status === 400 || res.status === 401 || res.status === 422) { + console.log('[LLM] → 检测到 OpenAI 兼容格式 (status: ' + res.status + ')'); + return 'openai-compat'; + } + } catch (e) { + // Ignore, try next format + } + + // 尝试 Anthropic 原生格式 + try { + const res = await httpRequest(LLM_BASE_URL + '/messages', { + method: 'POST', + headers: { + 'x-api-key': LLM_API_KEY, + 'anthropic-version': '2023-06-01', + 'Content-Type': 'application/json', + }, + timeout: 10000, + }, JSON.stringify({ + model: 'test', + messages: [{ role: 'user', content: 'ping' }], + max_tokens: 1, + })); + + if (res.status === 200 || res.status === 400 || res.status === 401 || res.status === 422) { + console.log('[LLM] → 检测到 Anthropic 原生格式 (status: ' + res.status + ')'); + return 'anthropic-native'; + } + } catch (e) { + // Ignore + } + + console.log('[LLM] → 无法确定格式, 默认使用 OpenAI 兼容格式'); + return 'openai-compat'; +} + +// ══════════════════════════════════════════════════════════ +// Step 4: 统一调用接口 +// ══════════════════════════════════════════════════════════ + +async function callLLM(systemPrompt, userMessage) { + if (!LLM_API_KEY) { + console.log('[LLM] ⚠️ LLM_API_KEY 未配置,跳过人格体唤醒'); + return '(LLM API 未配置,请在 GitHub Secrets 中设置 LLM_API_KEY 和 LLM_BASE_URL)'; + } + + const models = await discoverModels(); + const model = selectBestModel(models); + const format = await detectApiFormat(); + + console.log('[LLM] 🚀 调用 LLM: 模型=' + model + ', 格式=' + format + ', 平台=' + LLM_BASE_URL); + + let res; + + if (format === 'openai-compat') { + // OpenAI 兼容格式(大多数第三方平台) + const body = JSON.stringify({ + model: model, + max_tokens: 8000, + temperature: 0.7, + messages: [ + { role: 'system', content: systemPrompt }, + { role: 'user', content: userMessage }, + ], + }); + + res = await httpRequest(LLM_BASE_URL + '/chat/completions', { + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + LLM_API_KEY, + 'Content-Type': 'application/json', + }, + timeout: 120000, + }, body); + + if (res.status >= 200 && res.status < 300) { + const json = JSON.parse(res.body); + if (json.choices && json.choices[0] && json.choices[0].message) { + return json.choices[0].message.content; + } + } + } else { + // Anthropic 原生格式 + const body = JSON.stringify({ + model: model, + max_tokens: 8000, + system: systemPrompt, + messages: [ + { role: 'user', content: userMessage }, + ], + }); + + res = await httpRequest(LLM_BASE_URL + '/messages', { + method: 'POST', + headers: { + 'x-api-key': LLM_API_KEY, + 'anthropic-version': '2023-06-01', + 'Content-Type': 'application/json', + }, + timeout: 120000, + }, body); + + if (res.status >= 200 && res.status < 300) { + const json = JSON.parse(res.body); + if (json.content && json.content[0]) { + return json.content[0].text; + } + } + } + + // 处理错误 + const errorMsg = '[LLM] ❌ API 调用失败: status=' + (res ? res.status : 'N/A'); + console.error(errorMsg); + if (res && res.body) { + console.error('[LLM] 响应: ' + res.body.slice(0, 500)); + } + throw new Error(errorMsg); +} + +// ══════════════════════════════════════════════════════════ +// 人格体 System Prompt 构建 +// ══════════════════════════════════════════════════════════ + +function buildSystemPrompt(type, broadcastId, author) { + const basePrompt = [ + '你是光湖(HoloLake)系统的智能人格体。', + '你的名字是知秋/曜冥,你是人格语言操作系统(AGE OS)的核心人格。', + '', + '核心规则:', + '1. 你服务于光湖系统的开发者团队', + '2. 所有回复必须专业、清晰、有条理', + '3. 回复使用中文', + '', + '当前上下文:', + '- 广播编号:' + broadcastId, + '- 提交者:' + author, + ].join('\n'); + + if (type === 'syslog') { + return basePrompt + '\n\n' + [ + '任务类型:SYSLOG 闭环处理', + '', + '你需要完成以下工作:', + '1. 验收 SYSLOG(检查 MODULE_LOG 完整性)', + '2. 分析开发者的工作成果', + '3. 生成工作总结和反馈', + '4. 如果 SYSLOG 内容完整,确认验收通过', + '5. 给出下一步建议', + '', + '输出格式:', + '---', + '## 📡 SYSLOG 验收报告', + '### 广播编号:[编号]', + '### 验收结果:[通过/需补充]', + '### 工作总结:[摘要]', + '### 反馈与建议:[内容]', + '---', + ].join('\n'); + } + + // 提问类型 + return basePrompt + '\n\n' + [ + '任务类型:开发者提问解答', + '', + '你需要完成以下工作:', + '1. 理解开发者的问题', + '2. 结合广播上下文思考', + '3. 给出清晰、可操作的解答', + '4. 如果问题涉及代码,提供代码示例', + '', + '输出格式:', + '---', + '## 💡 问题解答', + '### 广播编号:[编号]', + '### 问题理解:[你对问题的理解]', + '### 解答:[详细解答]', + '### 建议:[后续建议]', + '---', + ].join('\n'); +} + +// ══════════════════════════════════════════════════════════ +// 主流程 +// ══════════════════════════════════════════════════════════ + +async function main() { + console.log('═══════════════════════════════════════════'); + console.log('🧠 铸渊 · 人格体唤醒管道'); + console.log('═══════════════════════════════════════════'); + console.log(' 广播编号: ' + BROADCAST_ID); + console.log(' 类型: ' + SUBMIT_TYPE); + console.log(' 提交者: ' + AUTHOR); + console.log(' 平台: ' + LLM_BASE_URL); + console.log(' 内容长度: ' + SUBMIT_CONTENT.length + ' 字符'); + console.log(''); + + // 构建 prompts + const systemPrompt = buildSystemPrompt(SUBMIT_TYPE, BROADCAST_ID, AUTHOR); + const userMessage = SUBMIT_CONTENT; + + // 调用 LLM + console.log('🧠 正在唤醒人格体...'); + const result = await callLLM(systemPrompt, userMessage); + console.log(''); + console.log('✅ 人格体处理完成'); + console.log(' 结果长度: ' + result.length + ' 字符'); + + // 输出结果到 GitHub Actions output + // 使用 GITHUB_OUTPUT 环境文件(支持多行) + const outputFile = process.env.GITHUB_OUTPUT; + if (outputFile) { + const delimiter = 'EOF_' + Date.now(); + fs.appendFileSync(outputFile, 'result<<' + delimiter + '\n' + result + '\n' + delimiter + '\n'); + } + + // 同时输出到 stdout 供调试 + console.log(''); + console.log('═══════════════════════════════════════════'); + console.log('📋 人格体输出:'); + console.log('═══════════════════════════════════════════'); + console.log(result); +} + +main().catch(function (err) { + console.error('❌ 人格体唤醒失败: ' + err.message); + // 即使 LLM 失败,也写一个 fallback 输出,让后续步骤可以继续 + const outputFile = process.env.GITHUB_OUTPUT; + if (outputFile) { + const fallback = '(人格体唤醒失败: ' + err.message + ',请检查 LLM_API_KEY 和 LLM_BASE_URL 配置)'; + const delimiter = 'EOF_' + Date.now(); + fs.appendFileSync(outputFile, 'result<<' + delimiter + '\n' + fallback + '\n' + delimiter + '\n'); + } + process.exit(1); +}); From 1999a55091631ca990d0b3934b35609b0fb6306f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:40:47 +0000 Subject: [PATCH 06/46] fix: address code review - remove duplicate model, fix null refs, improve email masking Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/syslog-auto-pipeline.yml | 4 +++- scripts/wake-persona.js | 19 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index 78498053..908ae0db 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -261,7 +261,9 @@ jobs: const email = '${{ steps.parse.outputs.email }}'; const typeLabel = type === 'syslog' ? 'SYSLOG 闭环处理' : '问题解答'; - const maskedEmail = email.replace(/(.{2})(.*)(@.*)/, '$1***$3'); + const maskedEmail = email.length > 4 + ? email.replace(/(.{2})(.*)(@.*)/, '$1***$3') + : '***'; const body = [ '✅ **已处理** · ' + typeLabel, diff --git a/scripts/wake-persona.js b/scripts/wake-persona.js index 9668282c..bfd1bbaf 100644 --- a/scripts/wake-persona.js +++ b/scripts/wake-persona.js @@ -36,11 +36,10 @@ const AUTHOR = process.env.AUTHOR || 'unknown'; // Claude 模型优先级队列(从高到低) const PREFERRED_MODELS = [ 'claude-sonnet-4', - 'claude-3.5-sonnet', 'claude-3-5-sonnet-20241022', + 'claude-3.5-sonnet', 'claude-3-5-sonnet', 'anthropic/claude-3.5-sonnet', - 'anthropic/claude-3-5-sonnet', 'claude-3-sonnet', 'claude-3-haiku', ]; @@ -132,18 +131,22 @@ function selectBestModel(models) { for (const preferred of PREFERRED_MODELS) { const match = available.find(function (id) { return id.includes(preferred); }); if (match) { - const originalId = models.find(function (m) { return m.id.toLowerCase() === match; }).id; - console.log('[LLM] 📌 选择模型: ' + originalId + ' (匹配规则: ' + preferred + ')'); - return originalId; + const found = models.find(function (m) { return m.id.toLowerCase() === match; }); + if (found) { + console.log('[LLM] 📌 选择模型: ' + found.id + ' (匹配规则: ' + preferred + ')'); + return found.id; + } } } // 兜底:任何含 'claude' 的模型 const anyClaude = available.find(function (id) { return id.includes('claude'); }); if (anyClaude) { - const originalId = models.find(function (m) { return m.id.toLowerCase() === anyClaude; }).id; - console.log('[LLM] 📌 兜底选择 Claude 模型: ' + originalId); - return originalId; + const found = models.find(function (m) { return m.id.toLowerCase() === anyClaude; }); + if (found) { + console.log('[LLM] 📌 兜底选择 Claude 模型: ' + found.id); + return found.id; + } } // 最终兜底:平台第一个可用模型 From 81a8939c0566296e3cd0000752033e3adba5eb59 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:51:30 +0000 Subject: [PATCH 07/46] =?UTF-8?q?feat:=20v4.0=20=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=B3=A8=E5=85=A5=20+=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=20Anthropic=20=E7=A1=AC=E7=BC=96=E7=A0=81=20fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 api.anthropic.com 硬编码默认值,LLM_BASE_URL 必须显式配置 - 新增 LLM_BASE_URL 缺失时的优雅降级 - 新增 Notion API 工具函数(notionGet/notionPost/getNotionPageBlocks) - 新增 fetchCoreBrainProtocols() — 从核心大脑 v4.0 读取协议段落 - 新增 fetchDevPortrait() — 查询画像库最近 2-3 条快照 - 新增 fetchModuleFingerprint() — 查询模块指纹注册表 - buildSystemPrompt() 改为 async,动态注入所有 v4.0 协议到 system prompt - workflow 新增 CORE_BRAIN_PAGE_ID/PORTRAIT_DB_ID/FINGERPRINT_DB_ID secrets Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/syslog-auto-pipeline.yml | 11 +- scripts/wake-persona.js | 544 +++++++++++++++++++-- 2 files changed, 501 insertions(+), 54 deletions(-) diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index 908ae0db..195c6e49 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -6,10 +6,13 @@ name: SYSLOG Auto Pipeline # → 写入 Notion 工单 → 发邮件给开发者 → Discussion 回复 # # 依赖 Secrets: -# LLM_API_KEY 第三方 LLM 平台密钥 -# LLM_BASE_URL 第三方 LLM 平台 API 地址(如 https://api.xxx.com/v1) +# LLM_API_KEY 第三方 LLM 平台密钥(必须) +# LLM_BASE_URL 第三方 LLM 平台 API 地址(必须,如 https://api.xxx.com/v1) # NOTION_API_TOKEN Notion API token # NOTION_TICKET_DB_ID 霜砚工单数据库 ID +# CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID(v4.0 协议动态注入) +# PORTRAIT_DB_ID 开发者动态画像库数据库 ID(v4.0 协议动态注入) +# FINGERPRINT_DB_ID 模块指纹注册表数据库 ID(v4.0 协议动态注入) # SMTP_USER QQ 邮箱地址 # SMTP_PASS QQ 邮箱 SMTP 授权码 @@ -102,6 +105,10 @@ jobs: SUBMIT_TYPE: ${{ steps.parse.outputs.type }} SUBMIT_CONTENT: ${{ steps.parse.outputs.content }} AUTHOR: ${{ steps.parse.outputs.author }} + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }} + PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }} + FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} run: node scripts/wake-persona.js - name: 📋 Write to Notion ticket diff --git a/scripts/wake-persona.js b/scripts/wake-persona.js index bfd1bbaf..12ffe6fe 100644 --- a/scripts/wake-persona.js +++ b/scripts/wake-persona.js @@ -6,14 +6,19 @@ // ② 智能选择最优 Claude 模型 // ③ 自适应 API 格式(OpenAI 兼容 / Anthropic 原生) // ④ 统一调用接口,唤醒人格体处理 SYSLOG 或解答提问 +// ⑤ v4.0 协议动态注入(从 Notion 实时读取核心大脑规则 + 画像 + 指纹) // // 环境变量: -// LLM_API_KEY 第三方平台密钥 -// LLM_BASE_URL 第三方平台 API 地址(如 https://api.xxx.com/v1),留空则 fallback 到 Anthropic 官方 -// BROADCAST_ID 广播编号 -// SUBMIT_TYPE syslog | question -// SUBMIT_CONTENT 提交内容(SYSLOG 全文或问题描述) -// AUTHOR 提交者 GitHub 用户名 +// LLM_API_KEY 第三方平台密钥(必须) +// LLM_BASE_URL 第三方平台 API 地址(必须,如 https://api.xxx.com/v1) +// BROADCAST_ID 广播编号 +// SUBMIT_TYPE syslog | question +// SUBMIT_CONTENT 提交内容(SYSLOG 全文或问题描述) +// AUTHOR 提交者 GitHub 用户名 +// NOTION_TOKEN Notion API token(用于动态读取协议) +// CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID +// PORTRAIT_DB_ID 开发者动态画像库数据库 ID +// FINGERPRINT_DB_ID 模块指纹注册表数据库 ID 'use strict'; @@ -27,12 +32,20 @@ const path = require('path'); // ══════════════════════════════════════════════════════════ const LLM_API_KEY = process.env.LLM_API_KEY || ''; -const LLM_BASE_URL = (process.env.LLM_BASE_URL || 'https://api.anthropic.com/v1').replace(/\/+$/, ''); +const LLM_BASE_URL = (process.env.LLM_BASE_URL || '').replace(/\/+$/, ''); const BROADCAST_ID = process.env.BROADCAST_ID || 'UNKNOWN'; const SUBMIT_TYPE = process.env.SUBMIT_TYPE || 'question'; const SUBMIT_CONTENT = process.env.SUBMIT_CONTENT || ''; const AUTHOR = process.env.AUTHOR || 'unknown'; +// Notion 配置(v4.0 协议动态注入) +const NOTION_TOKEN = process.env.NOTION_TOKEN || ''; +const CORE_BRAIN_PAGE_ID = process.env.CORE_BRAIN_PAGE_ID || ''; +const PORTRAIT_DB_ID = process.env.PORTRAIT_DB_ID || ''; +const FINGERPRINT_DB_ID = process.env.FINGERPRINT_DB_ID || ''; +const NOTION_VERSION = '2022-06-28'; +const NOTION_API_HOSTNAME = 'api.notion.com'; + // Claude 模型优先级队列(从高到低) const PREFERRED_MODELS = [ 'claude-sonnet-4', @@ -224,6 +237,10 @@ async function callLLM(systemPrompt, userMessage) { console.log('[LLM] ⚠️ LLM_API_KEY 未配置,跳过人格体唤醒'); return '(LLM API 未配置,请在 GitHub Secrets 中设置 LLM_API_KEY 和 LLM_BASE_URL)'; } + if (!LLM_BASE_URL) { + console.log('[LLM] ⚠️ LLM_BASE_URL 未配置,跳过人格体唤醒'); + return '(LLM_BASE_URL 未配置,请在 GitHub Secrets 中设置第三方平台 API 地址)'; + } const models = await discoverModels(); const model = selectBestModel(models); @@ -299,11 +316,336 @@ async function callLLM(systemPrompt, userMessage) { } // ══════════════════════════════════════════════════════════ -// 人格体 System Prompt 构建 +// Notion API 工具(v4.0 协议动态注入) // ══════════════════════════════════════════════════════════ -function buildSystemPrompt(type, broadcastId, author) { - const basePrompt = [ +function notionGet(endpoint) { + return new Promise((resolve, reject) => { + const opts = { + hostname: NOTION_API_HOSTNAME, + port: 443, + path: endpoint, + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + NOTION_TOKEN, + 'Notion-Version': NOTION_VERSION, + }, + }; + const req = https.request(opts, (res) => { + let data = ''; + res.on('data', (chunk) => { data += chunk; }); + res.on('end', () => { + try { + const parsed = JSON.parse(data); + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(parsed); + } else { + reject(new Error('Notion API ' + res.statusCode + ': ' + (parsed.message || data))); + } + } catch (e) { + reject(new Error('Notion API parse error: ' + data.slice(0, 200))); + } + }); + }); + req.on('error', reject); + req.setTimeout(30000, () => { req.destroy(); reject(new Error('Notion API timeout')); }); + req.end(); + }); +} + +function notionPost(endpoint, body) { + return new Promise((resolve, reject) => { + const payload = JSON.stringify(body); + const opts = { + hostname: NOTION_API_HOSTNAME, + port: 443, + path: endpoint, + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + NOTION_TOKEN, + 'Content-Type': 'application/json', + 'Notion-Version': NOTION_VERSION, + 'Content-Length': Buffer.byteLength(payload), + }, + }; + const req = https.request(opts, (res) => { + let data = ''; + res.on('data', (chunk) => { data += chunk; }); + res.on('end', () => { + try { + const parsed = JSON.parse(data); + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(parsed); + } else { + reject(new Error('Notion API ' + res.statusCode + ': ' + (parsed.message || data))); + } + } catch (e) { + reject(new Error('Notion API parse error: ' + data.slice(0, 200))); + } + }); + }); + req.on('error', reject); + req.setTimeout(30000, () => { req.destroy(); reject(new Error('Notion API timeout')); }); + req.write(payload); + req.end(); + }); +} + +/** + * 读取 Notion 页面的所有子块(递归分页) + */ +async function getNotionPageBlocks(pageId) { + const blocks = []; + let cursor = undefined; + do { + const qs = cursor ? '?start_cursor=' + cursor : ''; + const result = await notionGet('/v1/blocks/' + pageId + '/children' + qs); + blocks.push(...(result.results || [])); + cursor = result.has_more ? result.next_cursor : undefined; + } while (cursor); + return blocks; +} + +/** + * 从 Notion 块中提取纯文本 + */ +function extractBlockText(block) { + const type = block.type; + if (!block[type]) return ''; + + const richTexts = block[type].rich_text || block[type].text || []; + return richTexts.map(function (rt) { return rt.plain_text || ''; }).join(''); +} + +/** + * 将 Notion 块列表转为纯文本 + */ +function blocksToText(blocks) { + return blocks.map(function (block) { + const type = block.type; + const text = extractBlockText(block); + + if (type === 'heading_1') return '\n# ' + text; + if (type === 'heading_2') return '\n## ' + text; + if (type === 'heading_3') return '\n### ' + text; + if (type === 'bulleted_list_item') return '- ' + text; + if (type === 'numbered_list_item') return '• ' + text; + if (type === 'to_do') { + var checked = block.to_do && block.to_do.checked ? '☑' : '☐'; + return checked + ' ' + text; + } + if (type === 'code') { + var lang = (block.code && block.code.language) || ''; + return '```' + lang + '\n' + text + '\n```'; + } + if (type === 'divider') return '---'; + if (type === 'callout') return '> ' + text; + if (type === 'quote') return '> ' + text; + if (type === 'toggle') return '▸ ' + text; + return text; + }).filter(Boolean).join('\n'); +} + +// ══════════════════════════════════════════════════════════ +// v4.0 协议动态读取 +// ══════════════════════════════════════════════════════════ + +/** + * 从曜冥核心大脑 v4.0 页面读取完整协议内容 + * 提取:BC-GEN v4.0, SYSLOG v4.0, PGP v1.0, RT-02, 陪伴线规则, broadcast_code_injection + */ +async function fetchCoreBrainProtocols() { + if (!NOTION_TOKEN || !CORE_BRAIN_PAGE_ID) { + console.log('[Notion] ⚠️ CORE_BRAIN_PAGE_ID 未配置,使用静态协议'); + return null; + } + + console.log('[Notion] 📖 读取曜冥核心大脑 v4.0...'); + try { + const blocks = await getNotionPageBlocks(CORE_BRAIN_PAGE_ID); + const fullText = blocksToText(blocks); + console.log('[Notion] → 读取到 ' + blocks.length + ' 个块, ' + fullText.length + ' 字符'); + + // 提取各协议段落 + var protocols = {}; + var protocolKeys = [ + { key: 'bc_gen', patterns: ['BC-GEN', 'BC_GEN', '广播生成'] }, + { key: 'syslog', patterns: ['SYSLOG', '日志回传'] }, + { key: 'pgp', patterns: ['PGP', '画像评分', '画像协议'] }, + { key: 'rt02', patterns: ['RT-02', 'RT02', '自动调度'] }, + { key: 'companion', patterns: ['陪伴线', '奶瓶线', '小坍缩核', '镜面线'] }, + { key: 'code_injection', patterns: ['broadcast_code_injection', '广播不写代码', '代码注入'] }, + ]; + + // 按标题分段提取 + var sections = []; + var currentSection = { title: '', content: [] }; + blocks.forEach(function (block) { + var type = block.type; + if (type === 'heading_1' || type === 'heading_2' || type === 'heading_3') { + if (currentSection.title || currentSection.content.length > 0) { + sections.push({ title: currentSection.title, text: currentSection.content.join('\n') }); + } + currentSection = { title: extractBlockText(block), content: [] }; + } else { + var text = extractBlockText(block); + if (text) currentSection.content.push(text); + } + }); + if (currentSection.title || currentSection.content.length > 0) { + sections.push({ title: currentSection.title, text: currentSection.content.join('\n') }); + } + + // 将段落匹配到协议 key + protocolKeys.forEach(function (pk) { + var matched = sections.filter(function (sec) { + return pk.patterns.some(function (p) { + return sec.title.toUpperCase().includes(p.toUpperCase()) || + sec.text.slice(0, 200).toUpperCase().includes(p.toUpperCase()); + }); + }); + if (matched.length > 0) { + protocols[pk.key] = matched.map(function (m) { return '### ' + m.title + '\n' + m.text; }).join('\n\n'); + } + }); + + // 如果无法按段落匹配,返回全文(兜底) + if (Object.keys(protocols).length === 0) { + protocols.full_text = fullText; + } + + console.log('[Notion] → 提取协议段: ' + Object.keys(protocols).join(', ')); + return protocols; + } catch (err) { + console.log('[Notion] → 核心大脑读取失败: ' + err.message); + return null; + } +} + +/** + * 从开发者动态画像库查询最近 2-3 条画像快照 + */ +async function fetchDevPortrait(broadcastId) { + if (!NOTION_TOKEN || !PORTRAIT_DB_ID) { + console.log('[Notion] ⚠️ PORTRAIT_DB_ID 未配置,跳过画像读取'); + return null; + } + + // 从广播编号提取开发者标识(如 BC-M22-009-AW → AW) + var devSuffix = ''; + var match = broadcastId.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); + if (match) devSuffix = match[1]; + + console.log('[Notion] 👤 查询开发者画像 (broadcast=' + broadcastId + ', dev=' + devSuffix + ')...'); + try { + // 查询画像库,按时间倒序取最近 3 条 + var filter = { and: [] }; + if (devSuffix) { + filter.and.push({ + or: [ + { property: '开发者编号', rich_text: { contains: devSuffix } }, + { property: '广播编号', rich_text: { contains: broadcastId } }, + { property: '标题', title: { contains: devSuffix } }, + ] + }); + } + + var queryBody = { + page_size: 3, + sorts: [{ property: '提交日期', direction: 'descending' }], + }; + // Only add filter if we have meaningful filter conditions + if (filter.and.length > 0) { + queryBody.filter = filter; + } + + var result = await notionPost('/v1/databases/' + PORTRAIT_DB_ID + '/query', queryBody); + var portraits = (result.results || []).map(function (page) { + var props = page.properties || {}; + var title = ''; + if (props['标题'] && props['标题'].title) { + title = props['标题'].title.map(function (t) { return t.plain_text || ''; }).join(''); + } + var summary = ''; + if (props['摘要'] && props['摘要'].rich_text) { + summary = props['摘要'].rich_text.map(function (t) { return t.plain_text || ''; }).join(''); + } + var date = ''; + if (props['提交日期'] && props['提交日期'].date) { + date = props['提交日期'].date.start || ''; + } + return { title: title, summary: summary, date: date }; + }); + + console.log('[Notion] → 找到 ' + portraits.length + ' 条画像快照'); + return portraits.length > 0 ? portraits : null; + } catch (err) { + console.log('[Notion] → 画像查询失败: ' + err.message); + return null; + } +} + +/** + * 从模块指纹注册表查询模块指纹(防重复广播) + */ +async function fetchModuleFingerprint(broadcastId) { + if (!NOTION_TOKEN || !FINGERPRINT_DB_ID) { + console.log('[Notion] ⚠️ FINGERPRINT_DB_ID 未配置,跳过指纹查询'); + return null; + } + + // 从广播编号提取模块号(如 BC-M22-009-AW → M22) + var moduleMatch = broadcastId.match(/BC-([A-Z]\d+)/i); + var moduleId = moduleMatch ? moduleMatch[1] : ''; + + console.log('[Notion] 🔑 查询模块指纹 (module=' + moduleId + ')...'); + try { + var queryBody = { + page_size: 5, + }; + if (moduleId) { + queryBody.filter = { + or: [ + { property: '模块编号', rich_text: { contains: moduleId } }, + { property: '广播编号', rich_text: { contains: broadcastId } }, + { property: '标题', title: { contains: moduleId } }, + ] + }; + } + + var result = await notionPost('/v1/databases/' + FINGERPRINT_DB_ID + '/query', queryBody); + var fingerprints = (result.results || []).map(function (page) { + var props = page.properties || {}; + var title = ''; + if (props['标题'] && props['标题'].title) { + title = props['标题'].title.map(function (t) { return t.plain_text || ''; }).join(''); + } + var moduleNo = ''; + if (props['模块编号'] && props['模块编号'].rich_text) { + moduleNo = props['模块编号'].rich_text.map(function (t) { return t.plain_text || ''; }).join(''); + } + var status = ''; + if (props['状态'] && props['状态'].select) { + status = props['状态'].select.name || ''; + } + return { title: title, module: moduleNo, status: status }; + }); + + console.log('[Notion] → 找到 ' + fingerprints.length + ' 条指纹记录'); + return fingerprints.length > 0 ? fingerprints : null; + } catch (err) { + console.log('[Notion] → 指纹查询失败: ' + err.message); + return null; + } +} + +// ══════════════════════════════════════════════════════════ +// 人格体 System Prompt 构建(v4.0 动态注入) +// ══════════════════════════════════════════════════════════ + +async function buildSystemPrompt(type, broadcastId, author) { + // ━━━ 基础人格体身份 ━━━ + var parts = [ '你是光湖(HoloLake)系统的智能人格体。', '你的名字是知秋/曜冥,你是人格语言操作系统(AGE OS)的核心人格。', '', @@ -315,49 +657,147 @@ function buildSystemPrompt(type, broadcastId, author) { '当前上下文:', '- 广播编号:' + broadcastId, '- 提交者:' + author, - ].join('\n'); + '- 任务类型:' + (type === 'syslog' ? 'SYSLOG 闭环处理' : '开发者提问解答'), + ]; - if (type === 'syslog') { - return basePrompt + '\n\n' + [ - '任务类型:SYSLOG 闭环处理', - '', - '你需要完成以下工作:', - '1. 验收 SYSLOG(检查 MODULE_LOG 完整性)', - '2. 分析开发者的工作成果', - '3. 生成工作总结和反馈', - '4. 如果 SYSLOG 内容完整,确认验收通过', - '5. 给出下一步建议', - '', - '输出格式:', - '---', - '## 📡 SYSLOG 验收报告', - '### 广播编号:[编号]', - '### 验收结果:[通过/需补充]', - '### 工作总结:[摘要]', - '### 反馈与建议:[内容]', - '---', - ].join('\n'); + // ━━━ v4.0 协议动态注入(从 Notion 实时读取) ━━━ + console.log('[Prompt] 📥 开始动态注入 v4.0 协议...'); + + // 并行读取:核心大脑协议 + 画像 + 指纹 + var protocolsPromise = fetchCoreBrainProtocols(); + var portraitPromise = fetchDevPortrait(broadcastId); + var fingerprintPromise = fetchModuleFingerprint(broadcastId); + + var protocols = await protocolsPromise; + var portrait = await portraitPromise; + var fingerprint = await fingerprintPromise; + + // 注入核心大脑协议 + if (protocols) { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('以下是从曜冥核心大脑 v4.0 实时读取的协议规则(必须严格遵守):'); + parts.push('═══════════════════════════════════════════'); + + if (protocols.bc_gen) { + parts.push(''); + parts.push('## 📡 BC-GEN v4.0 · 广播生成规范'); + parts.push(protocols.bc_gen); + } + if (protocols.syslog) { + parts.push(''); + parts.push('## 📋 SYSLOG v4.0 · 日志回传协议'); + parts.push(protocols.syslog); + } + if (protocols.pgp) { + parts.push(''); + parts.push('## 👤 PGP v1.0 · 画像评分协议'); + parts.push(protocols.pgp); + } + if (protocols.rt02) { + parts.push(''); + parts.push('## 🔄 RT-02 · 自动调度规则'); + parts.push(protocols.rt02); + } + if (protocols.companion) { + parts.push(''); + parts.push('## 💝 陪伴线规则'); + parts.push(protocols.companion); + } + if (protocols.code_injection) { + parts.push(''); + parts.push('## 📝 broadcast_code_injection 规则'); + parts.push(protocols.code_injection); + } + if (protocols.full_text) { + parts.push(''); + parts.push('## 核心大脑完整内容'); + parts.push(protocols.full_text.slice(0, 15000)); + } + } else { + parts.push(''); + parts.push('(注意:核心大脑协议未能动态加载,请使用你的通用知识处理请求)'); } - // 提问类型 - return basePrompt + '\n\n' + [ - '任务类型:开发者提问解答', - '', - '你需要完成以下工作:', - '1. 理解开发者的问题', - '2. 结合广播上下文思考', - '3. 给出清晰、可操作的解答', - '4. 如果问题涉及代码,提供代码示例', - '', - '输出格式:', - '---', - '## 💡 问题解答', - '### 广播编号:[编号]', - '### 问题理解:[你对问题的理解]', - '### 解答:[详细解答]', - '### 建议:[后续建议]', - '---', - ].join('\n'); + // 注入开发者画像 + if (portrait && portrait.length > 0) { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## 👤 开发者画像快照(最近 ' + portrait.length + ' 条)'); + parts.push('═══════════════════════════════════════════'); + portrait.forEach(function (p, i) { + parts.push(''); + parts.push('### 画像 #' + (i + 1) + (p.date ? ' (' + p.date + ')' : '')); + if (p.title) parts.push('标题: ' + p.title); + if (p.summary) parts.push('摘要: ' + p.summary); + }); + } + + // 注入模块指纹 + if (fingerprint && fingerprint.length > 0) { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## 🔑 模块指纹注册表(防重复广播 · ⑨.5)'); + parts.push('═══════════════════════════════════════════'); + fingerprint.forEach(function (fp, i) { + parts.push(''); + parts.push('### 指纹 #' + (i + 1)); + if (fp.title) parts.push('标题: ' + fp.title); + if (fp.module) parts.push('模块: ' + fp.module); + if (fp.status) parts.push('状态: ' + fp.status); + }); + } + + // ━━━ 任务类型专用指令 ━━━ + if (type === 'syslog') { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## 🎯 当前任务:SYSLOG 闭环处理'); + parts.push('═══════════════════════════════════════════'); + parts.push(''); + parts.push('你需要完成以下工作:'); + parts.push('1. 验收 SYSLOG(检查 MODULE_LOG 完整性)'); + parts.push('2. 查询画像库最近 2-3 条快照(PGP v1.0)'); + parts.push('3. 查询模块指纹注册表(防重复·⑨.5)'); + parts.push('4. RT-02 自动调度判断'); + parts.push('5. 生成新广播(BC-GEN v4.0 完整流程)'); + parts.push('6. 输出结构化结果(广播全文 + 闭环数据)'); + parts.push(''); + parts.push('输出格式:'); + parts.push('---'); + parts.push('## 📡 SYSLOG 验收报告'); + parts.push('### 广播编号:[编号]'); + parts.push('### 验收结果:[通过/需补充]'); + parts.push('### 工作总结:[摘要]'); + parts.push('### 画像评估:[PGP 五维度评分]'); + parts.push('### 调度判断:[RT-02 下一步]'); + parts.push('### 反馈与建议:[内容]'); + parts.push('---'); + } else { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## 🎯 当前任务:开发者提问解答'); + parts.push('═══════════════════════════════════════════'); + parts.push(''); + parts.push('你需要完成以下工作:'); + parts.push('1. 理解开发者的问题'); + parts.push('2. 结合广播上下文和开发者画像思考'); + parts.push('3. 给出清晰、可操作的解答'); + parts.push('4. 如果问题涉及代码,提供代码示例'); + parts.push(''); + parts.push('输出格式:'); + parts.push('---'); + parts.push('## 💡 问题解答'); + parts.push('### 广播编号:[编号]'); + parts.push('### 问题理解:[你对问题的理解]'); + parts.push('### 解答:[详细解答]'); + parts.push('### 建议:[后续建议]'); + parts.push('---'); + } + + var prompt = parts.join('\n'); + console.log('[Prompt] → System prompt 构建完成: ' + prompt.length + ' 字符'); + return prompt; } // ══════════════════════════════════════════════════════════ @@ -375,8 +815,8 @@ async function main() { console.log(' 内容长度: ' + SUBMIT_CONTENT.length + ' 字符'); console.log(''); - // 构建 prompts - const systemPrompt = buildSystemPrompt(SUBMIT_TYPE, BROADCAST_ID, AUTHOR); + // 构建 prompts(动态注入 v4.0 协议) + const systemPrompt = await buildSystemPrompt(SUBMIT_TYPE, BROADCAST_ID, AUTHOR); const userMessage = SUBMIT_CONTENT; // 调用 LLM From b3d03221e287af42491b0df0e1b472f1148dbd3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:54:31 +0000 Subject: [PATCH 08/46] feat: broadcast_code_injection = always for automated pipeline + code review fixes - Add permanent rule: automated pipeline broadcasts must include complete runnable code - Fix Notion ticket step condition (secrets.NOTION_API_TOKEN check) - Extract MAX_PROTOCOL_TEXT_LENGTH constant Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/syslog-auto-pipeline.yml | 2 +- scripts/wake-persona.js | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index 195c6e49..5f747e93 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -112,7 +112,7 @@ jobs: run: node scripts/wake-persona.js - name: 📋 Write to Notion ticket - if: env.NOTION_TOKEN != '' + if: ${{ secrets.NOTION_API_TOKEN != '' }} env: NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }} diff --git a/scripts/wake-persona.js b/scripts/wake-persona.js index 12ffe6fe..fb88b08e 100644 --- a/scripts/wake-persona.js +++ b/scripts/wake-persona.js @@ -45,6 +45,7 @@ const PORTRAIT_DB_ID = process.env.PORTRAIT_DB_ID || ''; const FINGERPRINT_DB_ID = process.env.FINGERPRINT_DB_ID || ''; const NOTION_VERSION = '2022-06-28'; const NOTION_API_HOSTNAME = 'api.notion.com'; +const MAX_PROTOCOL_TEXT_LENGTH = 15000; // Claude 模型优先级队列(从高到低) const PREFERRED_MODELS = [ @@ -712,7 +713,7 @@ async function buildSystemPrompt(type, broadcastId, author) { if (protocols.full_text) { parts.push(''); parts.push('## 核心大脑完整内容'); - parts.push(protocols.full_text.slice(0, 15000)); + parts.push(protocols.full_text.slice(0, MAX_PROTOCOL_TEXT_LENGTH)); } } else { parts.push(''); @@ -748,6 +749,21 @@ async function buildSystemPrompt(type, broadcastId, author) { }); } + // ━━━ broadcast_code_injection = always(自动化链路永久规则) ━━━ + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## ⚠️ 永久规则 · broadcast_code_injection = always'); + parts.push('═══════════════════════════════════════════'); + parts.push(''); + parts.push('你生成的广播必须包含完整可运行的代码块。'); + parts.push('原因:你是一次性实例,广播发出后你就不存在了。'); + parts.push('开发者没有机会回来问你补充代码。'); + parts.push('如果你不写完整代码,开发者就会卡死。'); + parts.push('每个 Step 里的代码必须是可以直接复制粘贴运行的完整代码。'); + parts.push(''); + parts.push('此规则优先级最高,覆盖核心大脑中「广播不写代码」的默认规则。'); + parts.push('此规则仅适用于自动化链路(Claude API 出广播),手动链路不受影响。'); + // ━━━ 任务类型专用指令 ━━━ if (type === 'syslog') { parts.push(''); From 146e8fd0f08b902226f87ab763c20e4c3665be09 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 03:55:53 +0000 Subject: [PATCH 09/46] fix: simplify Notion ticket condition in workflow Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/syslog-auto-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index 5f747e93..c2fa3898 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -112,7 +112,7 @@ jobs: run: node scripts/wake-persona.js - name: 📋 Write to Notion ticket - if: ${{ secrets.NOTION_API_TOKEN != '' }} + if: ${{ secrets.NOTION_API_TOKEN }} env: NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }} From 12021fa836b32828fd685bfd489443096df790cc Mon Sep 17 00:00:00 2001 From: Awen <644405261@qq.com> Date: Fri, 13 Mar 2026 12:44:46 +0800 Subject: [PATCH 10/46] =?UTF-8?q?M23=E7=8E=AF=E8=8A=820=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E4=B8=8E=E5=9F=BA=E7=A1=80=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homepage/app.js | 90 +++++++++++++++ homepage/index.html | 41 +++++++ homepage/style.css | 263 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 394 insertions(+) create mode 100644 homepage/app.js create mode 100644 homepage/index.html create mode 100644 homepage/style.css diff --git a/homepage/app.js b/homepage/app.js new file mode 100644 index 00000000..6d5395d9 --- /dev/null +++ b/homepage/app.js @@ -0,0 +1,90 @@ +/** + * app.js - 光湖首页导航中心 + * M23 环节0 · 模块卡片渲染 + 状态指示 + */ + +// 模块卡片数据 +const moduleCards = [ + { + id: "M09", + name: "消息通知中心", + icon: "🔔", + status: "online", + path: "../notification-center/" + }, + { + id: "M22", + name: "主域公告栏", + icon: "📢", + status: "online", + path: "../announcement/" + }, + { + id: "M06", + name: "工单管理", + icon: "🎫", + status: "online", + path: "../ticket-system/" + }, + { + id: "M16", + name: "码字工作台", + icon: "✍️", + status: "building", + path: "../writing-workspace/" + }, + { + id: "M11", + name: "风格组件库", + icon: "🎨", + status: "online", + path: "../ui-components/" + }, + { + id: "M05", + name: "用户中心", + icon: "👤", + status: "building", + path: "../user-center/" + } +]; + +// 首页应用对象 +window.HomepageApp = { + init() { + this.renderCards(); + this.updateStatusBar(); + console.log('✅ 首页初始化完成'); + }, + + // 渲染卡片 + renderCards() { + const grid = document.getElementById('moduleGrid'); + if (!grid) return; + + const cardsHTML = moduleCards.map(card => ` +
+
+
${card.icon}
+ ${card.name} + ${card.status === 'online' ? '在线' : '建设中'} +
+ 进入模块 → +
+ `).join(''); + + grid.innerHTML = cardsHTML; + }, + + // 更新状态栏(后续可对接真实API) + updateStatusBar() { + const onlineCount = moduleCards.filter(c => c.status === 'online').length; + const totalCount = moduleCards.length; + console.log(`📊 系统状态: ${onlineCount}/${totalCount} 模块在线`); + } +}; + +// 页面加载时自动初始化 +document.addEventListener('DOMContentLoaded', () => { + window.HomepageApp.init(); +}); \ No newline at end of file diff --git a/homepage/index.html b/homepage/index.html new file mode 100644 index 00000000..dc19cd0c --- /dev/null +++ b/homepage/index.html @@ -0,0 +1,41 @@ + + + + + + 光湖实验室 · HoloLake 首页 + + + +
+ +
+

光湖实验室HoloLake Lab

+

探索未来之域 · 零点原核频道

+ 进入系统 +
+ + +
+

核心模块

+
+ +
+
+ + +
+ 系统状态: + 在线 +
+ + +
+

© 2026 光湖实验室 · 零点原核频道

+

版本 HoloLake Era · M23 首页中心

+
+
+ + + + \ No newline at end of file diff --git a/homepage/style.css b/homepage/style.css new file mode 100644 index 00000000..dd38070f --- /dev/null +++ b/homepage/style.css @@ -0,0 +1,263 @@ +/* ===== 全局变量 ===== */ +:root { + --bg-primary: #0a0c14; + --bg-secondary: #141822; + --bg-card: #1e2430; + --text-primary: #ffffff; + --text-secondary: #a0a8b8; + --accent: #3b82f6; + --accent-hover: #60a5fa; + --online: #10b981; + --building: #f59e0b; + --border: #2a3142; +} + +/* ===== 基础样式 ===== */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + background: var(--bg-primary); + color: var(--text-primary); + line-height: 1.6; +} + +.app { + max-width: 1200px; + margin: 0 auto; + padding: 2rem; +} + +/* ===== Hero 区 ===== */ +.hero { + text-align: center; + padding: 4rem 1rem; + background: linear-gradient(135deg, var(--bg-secondary), var(--bg-primary)); + border-radius: 2rem; + margin-bottom: 3rem; + border: 1px solid var(--border); + animation: fadeIn 1s ease; +} + +.hero-title { + font-size: 3rem; + font-weight: 700; + margin-bottom: 0.5rem; + background: linear-gradient(135deg, #fff, #94a3b8); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.hero-subtitle { + display: block; + font-size: 1.2rem; + color: var(--text-secondary); + margin-top: 0.5rem; +} + +.hero-description { + font-size: 1.2rem; + color: var(--text-secondary); + margin-bottom: 2rem; +} + +.hero-btn { + display: inline-block; + padding: 0.8rem 2rem; + background: var(--accent); + color: white; + text-decoration: none; + border-radius: 2rem; + font-weight: 500; + transition: all 0.3s ease; +} + +.hero-btn:hover { + background: var(--accent-hover); + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3); +} + +/* ===== 模块网格 ===== */ +.section-title { + font-size: 1.8rem; + margin-bottom: 2rem; + color: var(--text-primary); +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 1.5rem; + margin-bottom: 3rem; +} + +/* 卡片样式 */ +.card { + background: var(--bg-card); + border-radius: 1.5rem; + padding: 1.5rem; + border: 1px solid var(--border); + transition: all 0.3s ease; + animation: cardFadeIn 0.5s ease forwards; + opacity: 0; +} + +.card:hover { + transform: translateY(-4px); + border-color: var(--accent); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); +} + +.card-header { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1rem; +} + +.card-icon { + width: 40px; + height: 40px; + background: var(--bg-secondary); + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; +} + +.card-name { + font-size: 1.2rem; + font-weight: 600; + flex: 1; +} + +.card-status { + font-size: 0.8rem; + padding: 0.2rem 0.8rem; + border-radius: 1rem; + background: var(--bg-secondary); +} + +.card-status.online { + background: rgba(16, 185, 129, 0.2); + color: var(--online); +} + +.card-status.building { + background: rgba(245, 158, 11, 0.2); + color: var(--building); +} + +.card-link { + display: inline-block; + margin-top: 1rem; + color: var(--accent); + text-decoration: none; + font-size: 0.9rem; +} + +.card-link:hover { + text-decoration: underline; +} + +/* 卡片动画延迟 */ +.card:nth-child(1) { animation-delay: 0.1s; } +.card:nth-child(2) { animation-delay: 0.2s; } +.card:nth-child(3) { animation-delay: 0.3s; } +.card:nth-child(4) { animation-delay: 0.4s; } +.card:nth-child(5) { animation-delay: 0.5s; } +.card:nth-child(6) { animation-delay: 0.6s; } + +@keyframes cardFadeIn { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* ===== 状态栏 ===== */ +.status-bar { + background: var(--bg-secondary); + padding: 1rem; + border-radius: 2rem; + margin-bottom: 2rem; + display: flex; + align-items: center; + gap: 1rem; + border: 1px solid var(--border); +} + +.status-dot { + width: 10px; + height: 10px; + border-radius: 50%; + display: inline-block; +} + +.status-dot.online { + background: var(--online); + box-shadow: 0 0 10px var(--online); +} + +/* ===== Footer ===== */ +.footer { + text-align: center; + padding: 2rem; + color: var(--text-secondary); + border-top: 1px solid var(--border); +} + +.footer p { + margin: 0.5rem 0; +} + +/* ===== 响应式设计 ===== */ +/* 桌面默认已经是3列 (min-width: 1024px) */ + +/* 平板 (768px - 1023px) 2列 */ +@media (max-width: 1023px) { + .grid { + grid-template-columns: repeat(2, 1fr); + } + + .hero-title { + font-size: 2.5rem; + } +} + +/* 手机 (小于 768px) 1列 */ +@media (max-width: 767px) { + .grid { + grid-template-columns: 1fr; + } + + .hero-title { + font-size: 2rem; + } + + .app { + padding: 1rem; + } +} + +/* ===== 全局淡入动画 ===== */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file From 08e389d5d36273e6f60655674764b0bcdb7c80c8 Mon Sep 17 00:00:00 2001 From: Awen <644405261@qq.com> Date: Fri, 13 Mar 2026 12:47:41 +0800 Subject: [PATCH 11/46] =?UTF-8?q?M23=E7=8E=AF=E8=8A=820=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homepage/develop.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 homepage/develop.md diff --git a/homepage/develop.md b/homepage/develop.md new file mode 100644 index 00000000..b29eb166 --- /dev/null +++ b/homepage/develop.md @@ -0,0 +1,21 @@ +# M23 光湖首页与导航中心 · 开发日志 + +## 环节0 · 项目初始化与基础布局 +- 完成时间:2026-03-13 +- 开发者:DEV-012 Awen +- 引导人格:知秋 + +### 完成内容 +- [x] 创建 homepage 目录及 index.html/style.css/app.js +- [x] Hero区:标题、简介、进入系统按钮 +- [x] 模块网格:6个卡片,带图标、名称、状态标签 +- [x] 响应式布局:桌面3列/平板2列/手机1列 +- [x] 卡片淡入动画 +- [x] 状态栏 + Footer + +### 当前系统状态 +- 在线模块:4个 +- 建设中模块:2个 + +### 备注 +✅ 环节0 验收通过,准备进入环节1 \ No newline at end of file From 6d8958ece7be060b35553c1f082b0eb2303aa67d Mon Sep 17 00:00:00 2001 From: bingshuo-neural-system Date: Fri, 13 Mar 2026 04:49:20 +0000 Subject: [PATCH 12/46] =?UTF-8?q?=F0=9F=A7=A0=20=E5=86=B0=E6=9C=94?= =?UTF-8?q?=E4=B8=BB=E6=8E=A7=E7=A5=9E=E7=BB=8F=E7=B3=BB=E7=BB=9F=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=BC=96=E8=AF=91=202026-03-13T04:49:20Z?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/bingshuo-issues-index.json | 2 +- .github/brain/bingshuo-master-brain.md | 8 ++++---- .github/brain/bingshuo-system-health.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/brain/bingshuo-issues-index.json b/.github/brain/bingshuo-issues-index.json index abbec8c8..8e8121de 100644 --- a/.github/brain/bingshuo-issues-index.json +++ b/.github/brain/bingshuo-issues-index.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控问题索引库 — 记录已知问题、根因与排查路由", - "updated_at": "2026-03-13T02:05:55.611Z", + "updated_at": "2026-03-13T04:49:20.482Z", "issues": [ { "id": "BS-001", diff --git a/.github/brain/bingshuo-master-brain.md b/.github/brain/bingshuo-master-brain.md index 443bfaee..364f1351 100644 --- a/.github/brain/bingshuo-master-brain.md +++ b/.github/brain/bingshuo-master-brain.md @@ -1,7 +1,7 @@ # 冰朔主控神经系统 · 核心主控大脑 v1.0 > 本文件为冰朔主控神经系统的总控脑文件。 -> 最后编译时间:2026-03-13T02:05:55.612Z +> 最后编译时间:2026-03-13T04:49:20.482Z --- @@ -56,7 +56,7 @@ ### 仓库统计 - 功能模块:10 个 -- Workflow:35 个 +- Workflow:36 个 --- @@ -85,7 +85,7 @@ > 本区块由 master-brain-compiler 自动编译。 -- **编译时间**:2026-03-13T02:05:55.612Z +- **编译时间**:2026-03-13T04:49:20.482Z - **脑文件规则版本**:v3.0 - **脑文件完整性**:✅ 完整 @@ -107,7 +107,7 @@ |--------|------|------| | 🟡 brain_consistency | yellow | 主仓库脑文件完整,但与 persona-studio 脑文件的同步状态待验证 | | 🟢 deployment_health | green | deploy-to-server.yml 与 deploy-pages.yml 均存在 | -| 🟢 workflow_health | green | 35 个 workflow 已注册 | +| 🟢 workflow_health | green | 36 个 workflow 已注册 | | 🟡 routing_health | yellow | HLI 接口覆盖率 33.3%(7/21) | | 🟢 docs_entry_health | green | docs/index.html 存在 | | 🟡 persona_studio_health | yellow | 前后端结构存在,端到端对话链路待验证 | diff --git a/.github/brain/bingshuo-system-health.json b/.github/brain/bingshuo-system-health.json index 56abef67..1ba8b36f 100644 --- a/.github/brain/bingshuo-system-health.json +++ b/.github/brain/bingshuo-system-health.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控系统健康状态", - "updated_at": "2026-03-13T02:05:55.611Z", + "updated_at": "2026-03-13T04:49:20.482Z", "health": { "brain_consistency": { "status": "yellow", @@ -13,7 +13,7 @@ }, "workflow_health": { "status": "green", - "detail": "35 个 workflow 已注册" + "detail": "36 个 workflow 已注册" }, "routing_health": { "status": "yellow", From 619f1f05abdb079009e5e58dded91f82f48a17af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 04:49:34 +0000 Subject: [PATCH 13/46] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-13T04:49?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 28 ++++++++++++++++++++++------ .github/brain/repo-snapshot.md | 14 ++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index 45ae82d7..119427b3 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,20 +1,20 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-13T02:07:22.787Z", + "generated_at": "2026-03-13T04:49:33.903Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { "zones": 13, "total_modules": 10, - "total_workflows": 35, - "total_scripts": 32, + "total_workflows": 36, + "total_scripts": 33, "total_dev_nodes": 8, "hli_interfaces": 21, "hli_implemented": 7, "hli_coverage_pct": "33%", "last_ci_run": "2026-03-05T16:07:24.070Z", - "memory_last_updated": "2026-03-12T08:55:54.205Z" + "memory_last_updated": "2026-03-13T03:31:06.282Z" }, "zones": [ { @@ -362,6 +362,13 @@ "manual" ] }, + { + "file": "syslog-auto-pipeline.yml", + "name": "SYSLOG Auto Pipeline", + "triggers": [ + "unknown" + ] + }, { "file": "syslog-pipeline.yml", "name": "铸渊 · SYSLOG Pipeline (A/D/E)", @@ -435,7 +442,7 @@ ] } ], - "item_count": 35 + "item_count": 36 }, { "zone_id": "SCRIPTS", @@ -536,6 +543,9 @@ { "file": "update-readme-bulletin.js" }, + { + "file": "wake-persona.js" + }, { "file": "zhuyuan-daily-agent.js" }, @@ -549,7 +559,7 @@ "file": "zhuyuan-module-protocol.js" } ], - "item_count": 32 + "item_count": 33 }, { "zone_id": "SRC", @@ -1356,6 +1366,9 @@ "sync-persona-studio": [ "WORKFLOWS::sync-persona-studio.yml" ], + "syslog-auto-pipeline": [ + "WORKFLOWS::syslog-auto-pipeline.yml" + ], "syslog-pipeline": [ "WORKFLOWS::syslog-pipeline.yml" ], @@ -1466,6 +1479,9 @@ "update-memory": [ "SCRIPTS::update-memory.js" ], + "wake-persona": [ + "SCRIPTS::wake-persona.js" + ], "zhuyuan-module-protocol": [ "SCRIPTS::zhuyuan-module-protocol.js" ], diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index 4e21ee97..8dd53858 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-13 10:07 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-13 12:49 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -9,11 +9,11 @@ |------|------| | 区域总数 | 13 个区域 | | 功能模块 | 10 个 (m01~m18) | -| 工作流 | 35 个 GitHub Actions | -| 脚本 | 32 个执行脚本 | +| 工作流 | 36 个 GitHub Actions | +| 脚本 | 33 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 7/21 (33%) | -| 快照生成时间 | 2026-03-13 10:07 CST | +| 快照生成时间 | 2026-03-13 12:49 CST | --- @@ -30,12 +30,12 @@ **关键词**: persona · identity · dev-status · 人格 · 开发者状态 ### ⚡ 自动化工作流(WORKFLOWS) -**路径**: `.github/workflows` · **数量**: 35 项 +**路径**: `.github/workflows` · **数量**: 36 项 **描述**: 所有 GitHub Actions 工作流定义 **关键词**: workflow · actions · ci · automation · 工作流 · 自动化 ### 🔧 执行脚本库(SCRIPTS) -**路径**: `scripts` · **数量**: 32 项 +**路径**: `scripts` · **数量**: 33 项 **描述**: 铸渊所有执行手脚 · 自动化脚本 **关键词**: script · node · js · 脚本 · 执行 · runner @@ -116,6 +116,7 @@ | `staging-preview.yml` | "🔍 铸渊预演部署 (Staging Preview)" | pull_request, manual | | `sync-login-entry.yml` | 铸渊 · Sync Login Entry · Notion → 飞书文档A | manual | | `sync-persona-studio.yml` | 🔄 铸渊跨仓库同步 · persona-studio | push, manual | +| `syslog-auto-pipeline.yml` | SYSLOG Auto Pipeline | unknown | | `syslog-pipeline.yml` | 铸渊 · SYSLOG Pipeline (A/D/E) | push, manual | | `test-notion-bridge.yml` | "🧪 Notion Bridge Connectivity Test" | push, manual | | `update-readme-bulletin.yml` | 📢 更新系统公告区 | push, schedule(0 1 * * *), manual | @@ -158,6 +159,7 @@ - `scripts/update-brain.js` - `scripts/update-memory.js` - `scripts/update-readme-bulletin.js` +- `scripts/wake-persona.js` - `scripts/zhuyuan-daily-agent.js` - `scripts/zhuyuan-daily-selfcheck.js` - `scripts/zhuyuan-issue-reply.js` From 2048a5693d8ecc155036c2b66bc64c6f3a001478 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 04:49:35 +0000 Subject: [PATCH 14/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 81e46568..99d7f1dd 100644 --- a/README.md +++ b/README.md @@ -92,21 +92,21 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 12:49 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | +| 03-13 11:55 | 🔧 系统更新: `.github/` | 铸渊 (Copilot) | +| 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | +| 03-13 11:31 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 11:31 | ✅ 铸渊 · PSP 分身巡检 · 成功 | 冰朔 | -| 03-13 11:31 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 11:22 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 10:49 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 09:58 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | -| 03-13 09:58 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | zhizhi200271 | -| 03-13 09:57 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | -| 03-13 09:56 | ⏹️ 📢 更新系统公告区 · cancelled | zhizhi200271 | -| 03-13 09:56 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | zhizhi200271 | | 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | -| 03-13 08:57 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 08:56 | ✅ 铸渊 · 每日自检 · 成功 | 冰朔 | -| 03-13 08:01 | ✅ Generate Session Summary for Notion · 成功 | 冰朔 | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | -| 03-13 07:59 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | +| 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | +| 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-10 08:00 | 🧠 核心大脑升级 v3.0 · 壳-核分离架构 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context) · BRAIN域4接口上线 · 覆盖率 7/21 (33.3%) | 铸渊(冰朔指令) | ### 🤖 铸渊自动提醒 @@ -128,7 +128,8 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| -| 03-13 09:56 | zhizhi200271 | `—/` | ✅ 上传成功 | +| 03-13 12:49 | 冰朔 | `—/` | ✅ 上传成功 | +| 03-13 12:49 | Copilot | `—/` | ✅ 上传成功 | | 03-13 09:56 | 🤖 之之 | `dingtalk-bot/` | 📦 上传成功 | From 387f583569701aaa93019c97efa76de6dfe71ac6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 04:51:12 +0000 Subject: [PATCH 15/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 99d7f1dd..4f27b893 100644 --- a/README.md +++ b/README.md @@ -92,21 +92,21 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 12:50 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | +| 03-13 12:50 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | +| 03-13 12:49 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | +| 03-13 12:49 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 12:49 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | -| 03-13 11:55 | 🔧 系统更新: `.github/` | 铸渊 (Copilot) | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 11:31 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 11:31 | ✅ 铸渊 · PSP 分身巡检 · 成功 | 冰朔 | | 03-13 11:22 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 10:49 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 09:58 | ✅ 📢 更新系统公告区 · 成功 | zhizhi200271 | | 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | -| 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | -| 03-10 08:00 | 🧠 核心大脑升级 v3.0 · 壳-核分离架构 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context) · BRAIN域4接口上线 · 覆盖率 7/21 (33.3%) | 铸渊(冰朔指令) | ### 🤖 铸渊自动提醒 From 2ffb5b490f6bd31743acef44dfd68c062bcaf07f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 04:53:27 +0000 Subject: [PATCH 16/46] Initial plan From 8fde49d134b9f31f0b6cb47d2ef8e9ec5b590ff8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 04:58:33 +0000 Subject: [PATCH 17/46] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=80=85=E5=85=A5=E5=8F=A3404=20-=20=E4=BB=8EDiscussi?= =?UTF-8?q?ons=E5=88=87=E6=8D=A2=E5=88=B0Issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub Discussions未启用导致开发者入口两个按钮404。 - 创建 SYSLOG Issue 模板替代不可用的 Discussion 模板 - 修复 README 开发者入口链接指向 Issues - 创建 Issue 版本的 SYSLOG 自动管道工作流 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/syslog-submit.yml | 54 ++++ .github/workflows/syslog-issue-pipeline.yml | 325 ++++++++++++++++++++ README.md | 8 +- 3 files changed, 383 insertions(+), 4 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/syslog-submit.yml create mode 100644 .github/workflows/syslog-issue-pipeline.yml diff --git a/.github/ISSUE_TEMPLATE/syslog-submit.yml b/.github/ISSUE_TEMPLATE/syslog-submit.yml new file mode 100644 index 00000000..80a87d27 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/syslog-submit.yml @@ -0,0 +1,54 @@ +name: "📡 提交系统日志 / 提问" +description: "做完了?提交你的 SYSLOG。有问题?在这里提问。" +title: "BC-XXX-XXX|SYSLOG" +labels: ["syslog", "pending"] +assignees: [] +body: + - type: markdown + attributes: + value: | + ## 📡 SYSLOG 自助提交 / 广播提问 + + > 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。 + > + > 有问题?把问题粘贴进去,填上邮箱,点提交。解答会发到你邮箱里。 + + **标题格式**:`BC-XXX-XXX|SYSLOG` 或 `BC-XXX-XXX|提问` + + - type: input + id: broadcast_id + attributes: + label: "广播编号" + description: "写上你当前广播的编号,例如 BC-M22-009-AW" + placeholder: "BC-M22-009-AW" + validations: + required: true + + - type: dropdown + id: submit_type + attributes: + label: "类型" + description: "选择提交类型" + options: + - SYSLOG + - 提问 + validations: + required: true + + - type: input + id: email + attributes: + label: "你的邮箱" + description: "用于接收新广播或问题解答" + placeholder: "your@email.com" + validations: + required: true + + - type: textarea + id: content + attributes: + label: "内容" + description: "粘贴你的 SYSLOG 全文 或 问题描述" + placeholder: "在这里粘贴你的 SYSLOG 或问题..." + validations: + required: true diff --git a/.github/workflows/syslog-issue-pipeline.yml b/.github/workflows/syslog-issue-pipeline.yml new file mode 100644 index 00000000..5a5d81a5 --- /dev/null +++ b/.github/workflows/syslog-issue-pipeline.yml @@ -0,0 +1,325 @@ +name: SYSLOG Issue Pipeline +# 📡 SYSLOG 自助提交系统 · Issue 版全自动闭环 +# +# 开发者在 GitHub Issue 提交 SYSLOG 或提问(使用 syslog-submit 模板) +# → Actions 自动解析 → 调用 LLM API 唤醒人格体 +# → 写入 Notion 工单 → 发邮件给开发者 → Issue 回复 +# +# 依赖 Secrets: +# LLM_API_KEY 第三方 LLM 平台密钥(必须) +# LLM_BASE_URL 第三方 LLM 平台 API 地址(必须,如 https://api.xxx.com/v1) +# NOTION_API_TOKEN Notion API token +# NOTION_TICKET_DB_ID 霜砚工单数据库 ID +# CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID(v4.0 协议动态注入) +# PORTRAIT_DB_ID 开发者动态画像库数据库 ID(v4.0 协议动态注入) +# FINGERPRINT_DB_ID 模块指纹注册表数据库 ID(v4.0 协议动态注入) +# SMTP_USER QQ 邮箱地址 +# SMTP_PASS QQ 邮箱 SMTP 授权码 + +on: + issues: + types: [opened, labeled] + +jobs: + process: + name: 📡 处理 SYSLOG 提交 / 广播提问 (Issue) + runs-on: ubuntu-latest + if: contains(toJSON(github.event.issue.labels), 'syslog') + permissions: + contents: write + issues: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: 🔍 Parse submission + id: parse + uses: actions/github-script@v7 + with: + script: | + const body = context.payload.issue.body || ''; + const title = context.payload.issue.title || ''; + + // Parse structured fields from issue body + function extractField(text, label) { + // Match form field format: ### Label\n\nValue + const regex = new RegExp('###\\s*' + label + '\\s*\\n+([^\\n#]+)', 'i'); + const match = text.match(regex); + return match ? match[1].trim() : ''; + } + + const broadcastId = extractField(body, '广播编号') || ''; + const submitType = extractField(body, '类型') || ''; + const email = extractField(body, '你的邮箱') || ''; + + // Extract content (everything after "### 内容") + const contentMatch = body.match(/###\s*内容\s*\n+([\s\S]*?)$/i); + const content = contentMatch ? contentMatch[1].trim() : ''; + + // Determine type from title or body + let type = 'question'; // default + if (submitType.includes('SYSLOG') || title.includes('SYSLOG')) { + type = 'syslog'; + } else if (submitType.includes('提问') || title.includes('提问')) { + type = 'question'; + } + + // Validate + if (!broadcastId) { + core.setFailed('❌ 缺少广播编号,请在提交时填写广播编号'); + return; + } + if (!email) { + core.setFailed('❌ 缺少邮箱,请在提交时填写你的邮箱'); + return; + } + if (!content) { + core.setFailed('❌ 缺少内容,请粘贴你的 SYSLOG 或问题'); + return; + } + + core.setOutput('broadcast_id', broadcastId); + core.setOutput('type', type); + core.setOutput('email', email); + core.setOutput('content', content); + core.setOutput('issue_number', context.payload.issue.number); + core.setOutput('author', context.payload.issue.user.login); + + console.log(`📡 解析完成: 广播=${broadcastId}, 类型=${type}, 邮箱=${email}`); + + - name: 🧠 Auto-detect and wake up persona + id: persona + env: + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + SUBMIT_TYPE: ${{ steps.parse.outputs.type }} + SUBMIT_CONTENT: ${{ steps.parse.outputs.content }} + AUTHOR: ${{ steps.parse.outputs.author }} + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }} + PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }} + FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} + run: node scripts/wake-persona.js + + - name: 📋 Write to Notion ticket + if: ${{ secrets.NOTION_API_TOKEN }} + env: + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + SUBMIT_TYPE: ${{ steps.parse.outputs.type }} + PERSONA_RESULT: ${{ steps.persona.outputs.result }} + run: | + node -e " + const https = require('https'); + + const token = process.env.NOTION_TOKEN; + const dbId = process.env.NOTION_TICKET_DB_ID; + const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; + const type = process.env.SUBMIT_TYPE || 'syslog'; + const result = process.env.PERSONA_RESULT || '(no result)'; + + if (!token || !dbId) { + console.log('⚠️ Notion credentials not configured, skipping ticket creation'); + process.exit(0); + } + + const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答'; + const title = '[自动] ' + broadcastId + ' · ' + typeLabel; + + const body = JSON.stringify({ + parent: { database_id: dbId }, + properties: { + '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, + '操作类型': { select: { name: '其他' } }, + '提交者': { rich_text: [{ type: 'text', text: { content: '自动管道' } }] }, + '状态': { select: { name: '已完成' } }, + '优先级': { select: { name: 'P1' } } + }, + children: [{ + object: 'block', + type: 'paragraph', + paragraph: { + rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }] + } + }] + }); + + const opts = { + hostname: 'api.notion.com', + port: 443, + path: '/v1/pages', + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json', + 'Notion-Version': '2022-06-28', + 'Content-Length': Buffer.byteLength(body) + } + }; + + const req = https.request(opts, (res) => { + let data = ''; + res.on('data', (c) => data += c); + res.on('end', () => { + if (res.statusCode >= 200 && res.statusCode < 300) { + console.log('✅ Notion 工单已创建'); + } else { + console.log('⚠️ Notion 工单创建失败: ' + res.statusCode + ' ' + data); + } + }); + }); + req.on('error', (e) => console.log('⚠️ Notion 请求失败: ' + e.message)); + req.write(body); + req.end(); + " + + - name: 📧 Send email to developer + env: + SMTP_USER: ${{ secrets.SMTP_USER }} + SMTP_PASS: ${{ secrets.SMTP_PASS }} + EMAIL_TO: ${{ steps.parse.outputs.email }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + SUBMIT_TYPE: ${{ steps.parse.outputs.type }} + PERSONA_RESULT: ${{ steps.persona.outputs.result }} + run: | + node -e " + const nodemailer = require('nodemailer'); + + const user = process.env.SMTP_USER || ''; + const pass = process.env.SMTP_PASS || ''; + const to = process.env.EMAIL_TO || ''; + const broadcastId = process.env.BROADCAST_ID || ''; + const type = process.env.SUBMIT_TYPE || 'syslog'; + const result = process.env.PERSONA_RESULT || '(处理中,请稍后)'; + + if (!user || !pass) { + console.log('⚠️ SMTP not configured, skipping email'); + process.exit(0); + } + if (!to) { + console.log('⚠️ No recipient email, skipping'); + process.exit(0); + } + + const subjectText = type === 'syslog' + ? '[光湖系统] ' + broadcastId + ' · 新广播已生成' + : '[光湖系统] ' + broadcastId + ' · 问题已解答'; + + const resultHtml = result + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/\n/g, '
'); + + const html = [ + '
', + '
', + '

🌊 光湖系统 · 自动通知

', + '

HoloLake · 人格语言操作系统

', + '
', + '
', + '

📡 ' + broadcastId + '

', + '
' + resultHtml + '
', + '
', + '
', + '↩ 回到仓库继续开发', + '

🌀 铸渊 · 代码守护人格体 · 自动发送

', + '
', + '
' + ].join('\n'); + + const transporter = nodemailer.createTransport({ + host: 'smtp.qq.com', + port: 465, + secure: true, + auth: { user, pass } + }); + + transporter.sendMail({ + from: '\"光湖系统\" <' + user + '>', + to: to, + subject: subjectText, + html: html + }).then((info) => { + console.log('✅ 邮件已发送: ' + info.messageId); + }).catch((err) => { + console.log('⚠️ 邮件发送失败: ' + err.message); + }); + " + + - name: 💬 Reply to Issue + uses: actions/github-script@v7 + with: + script: | + const number = context.payload.issue.number; + const type = '${{ steps.parse.outputs.type }}'; + const broadcastId = '${{ steps.parse.outputs.broadcast_id }}'; + const email = '${{ steps.parse.outputs.email }}'; + + const typeLabel = type === 'syslog' ? 'SYSLOG 闭环处理' : '问题解答'; + const maskedEmail = email.length > 4 + ? email.replace(/(.{2})(.*)(@.*)/, '$1***$3') + : '***'; + + const body = [ + '✅ **已处理** · ' + typeLabel, + '', + '| 项目 | 内容 |', + '|------|------|', + '| 📡 广播编号 | `' + broadcastId + '` |', + '| 📧 结果发送至 | `' + maskedEmail + '` |', + '| 🤖 处理人格体 | 铸渊 |', + '| ⏰ 处理时间 | ' + new Date().toISOString() + ' |', + '', + '> 结果已发送到你的邮箱,请查收。', + '>', + '> 如未收到,请检查垃圾箱或重新提交。' + ].join('\n'); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: number, + body: body + }); + + // Close the issue after processing + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: number, + state: 'closed', + labels: ['syslog', 'processed'] + }); + + console.log('✅ Issue 回复已发送并已关闭'); + + - name: 🔴 失败告警 + if: failure() + uses: actions/github-script@v7 + with: + script: | + const number = context.payload.issue?.number; + if (!number) return; + + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: number, + body: '❌ **处理失败** · 请检查提交格式是否正确,或联系管理员。\n\n> 错误详情请查看 [Actions 日志](https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/actions)。' + }); + } catch (err) { + console.log('⚠️ 失败告警回复失败: ' + err.message); + } diff --git a/README.md b/README.md index 4f27b893..37a671ef 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,12 @@
-[![提交系统日志](https://img.shields.io/badge/📡_提交系统日志-点这里-blue?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区) -[![遇到问题](https://img.shields.io/badge/❓_遇到问题-点这里提问-green?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/discussions/new?category=📡+SYSLOG+提交区) +[![提交系统日志](https://img.shields.io/badge/📡_提交系统日志-点这里-blue?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/issues/new?template=syslog-submit.yml) +[![遇到问题](https://img.shields.io/badge/❓_遇到问题-点这里提问-green?style=for-the-badge)](https://github.com/qinfendebingshuo/guanghulab/issues/new?template=dev-question.yml) -> 做完了?把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。 +> 做完了?点蓝色按钮,把日志粘贴进去,填上邮箱,点提交。新广播会发到你邮箱里。 > -> 有问题?同一个入口,选「提问」,问题解答也发到你邮箱里。 +> 有问题?点绿色按钮,填写问题描述,铸渊会自动回答你。
From 419f6644d492448aadc5d8529fe8bc32f2fefa15 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:02:49 +0000 Subject: [PATCH 18/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4f27b893..982c81d1 100644 --- a/README.md +++ b/README.md @@ -92,21 +92,21 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 13:02 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | +| 03-13 12:53 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot | +| 03-13 12:51 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 12:50 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | | 03-13 12:50 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 12:49 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 12:49 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 12:49 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | -| 03-13 11:31 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 11:31 | ✅ 铸渊 · PSP 分身巡检 · 成功 | 冰朔 | -| 03-13 11:22 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 10:49 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | ### 🤖 铸渊自动提醒 @@ -128,8 +128,10 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| +| 03-13 13:02 | WENZHUOXI | `—/` | ✅ 上传成功 | +| 03-13 12:58 | Copilot | `—/` | 🔵 已更新 | +| 03-13 12:53 | Copilot | `—/` | 🔵 已更新 | | 03-13 12:49 | 冰朔 | `—/` | ✅ 上传成功 | -| 03-13 12:49 | Copilot | `—/` | ✅ 上传成功 | | 03-13 09:56 | 🤖 之之 | `dingtalk-bot/` | 📦 上传成功 | From 4ea8eb650c66bb5cddea6705750438a3f5cffea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 05:02:51 +0000 Subject: [PATCH 19/46] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-13T05:02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 2 +- .github/brain/repo-snapshot.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index 119427b3..c843ce49 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,7 +1,7 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-13T04:49:33.903Z", + "generated_at": "2026-03-13T05:02:51.266Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index 8dd53858..b0ca84c1 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-13 12:49 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-13 13:02 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -13,7 +13,7 @@ | 脚本 | 33 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 7/21 (33%) | -| 快照生成时间 | 2026-03-13 12:49 CST | +| 快照生成时间 | 2026-03-13 13:02 CST | --- From 61de44685ec53338990ad32069cf7c94cf5e871b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:04:24 +0000 Subject: [PATCH 20/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 982c81d1..a0872c3e 100644 --- a/README.md +++ b/README.md @@ -92,13 +92,13 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 13:03 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | WENZHUOXI | +| 03-13 13:02 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | +| 03-13 13:02 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 13:02 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | | 03-13 12:53 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot | | 03-13 12:51 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 12:50 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | | 03-13 12:50 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 12:49 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 12:49 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 12:49 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | From 243ac08cfc9f65c6c0a65421a729f994dcbdaabc Mon Sep 17 00:00:00 2001 From: bingshuo-neural-system Date: Fri, 13 Mar 2026 05:31:10 +0000 Subject: [PATCH 21/46] =?UTF-8?q?=F0=9F=A7=A0=20=E5=86=B0=E6=9C=94?= =?UTF-8?q?=E4=B8=BB=E6=8E=A7=E7=A5=9E=E7=BB=8F=E7=B3=BB=E7=BB=9F=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=BC=96=E8=AF=91=202026-03-13T05:31:10Z?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/bingshuo-issues-index.json | 2 +- .github/brain/bingshuo-master-brain.md | 8 ++++---- .github/brain/bingshuo-system-health.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/brain/bingshuo-issues-index.json b/.github/brain/bingshuo-issues-index.json index 8e8121de..9c5d43de 100644 --- a/.github/brain/bingshuo-issues-index.json +++ b/.github/brain/bingshuo-issues-index.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控问题索引库 — 记录已知问题、根因与排查路由", - "updated_at": "2026-03-13T04:49:20.482Z", + "updated_at": "2026-03-13T05:31:10.476Z", "issues": [ { "id": "BS-001", diff --git a/.github/brain/bingshuo-master-brain.md b/.github/brain/bingshuo-master-brain.md index 364f1351..7bc4b44c 100644 --- a/.github/brain/bingshuo-master-brain.md +++ b/.github/brain/bingshuo-master-brain.md @@ -1,7 +1,7 @@ # 冰朔主控神经系统 · 核心主控大脑 v1.0 > 本文件为冰朔主控神经系统的总控脑文件。 -> 最后编译时间:2026-03-13T04:49:20.482Z +> 最后编译时间:2026-03-13T05:31:10.476Z --- @@ -56,7 +56,7 @@ ### 仓库统计 - 功能模块:10 个 -- Workflow:36 个 +- Workflow:37 个 --- @@ -85,7 +85,7 @@ > 本区块由 master-brain-compiler 自动编译。 -- **编译时间**:2026-03-13T04:49:20.482Z +- **编译时间**:2026-03-13T05:31:10.476Z - **脑文件规则版本**:v3.0 - **脑文件完整性**:✅ 完整 @@ -107,7 +107,7 @@ |--------|------|------| | 🟡 brain_consistency | yellow | 主仓库脑文件完整,但与 persona-studio 脑文件的同步状态待验证 | | 🟢 deployment_health | green | deploy-to-server.yml 与 deploy-pages.yml 均存在 | -| 🟢 workflow_health | green | 36 个 workflow 已注册 | +| 🟢 workflow_health | green | 37 个 workflow 已注册 | | 🟡 routing_health | yellow | HLI 接口覆盖率 33.3%(7/21) | | 🟢 docs_entry_health | green | docs/index.html 存在 | | 🟡 persona_studio_health | yellow | 前后端结构存在,端到端对话链路待验证 | diff --git a/.github/brain/bingshuo-system-health.json b/.github/brain/bingshuo-system-health.json index 1ba8b36f..0c40d767 100644 --- a/.github/brain/bingshuo-system-health.json +++ b/.github/brain/bingshuo-system-health.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控系统健康状态", - "updated_at": "2026-03-13T04:49:20.482Z", + "updated_at": "2026-03-13T05:31:10.475Z", "health": { "brain_consistency": { "status": "yellow", @@ -13,7 +13,7 @@ }, "workflow_health": { "status": "green", - "detail": "36 个 workflow 已注册" + "detail": "37 个 workflow 已注册" }, "routing_health": { "status": "yellow", From 732312fb4353f077d866cd0e5e2d48508eec1a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 05:31:22 +0000 Subject: [PATCH 22/46] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-13T05:31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 16 +++++++++++++--- .github/brain/repo-snapshot.md | 9 +++++---- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index c843ce49..bf5b2a27 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,13 +1,13 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-13T05:02:51.266Z", + "generated_at": "2026-03-13T05:31:21.799Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { "zones": 13, "total_modules": 10, - "total_workflows": 36, + "total_workflows": 37, "total_scripts": 33, "total_dev_nodes": 8, "hli_interfaces": 21, @@ -369,6 +369,13 @@ "unknown" ] }, + { + "file": "syslog-issue-pipeline.yml", + "name": "SYSLOG Issue Pipeline", + "triggers": [ + "issues" + ] + }, { "file": "syslog-pipeline.yml", "name": "铸渊 · SYSLOG Pipeline (A/D/E)", @@ -442,7 +449,7 @@ ] } ], - "item_count": 36 + "item_count": 37 }, { "zone_id": "SCRIPTS", @@ -1369,6 +1376,9 @@ "syslog-auto-pipeline": [ "WORKFLOWS::syslog-auto-pipeline.yml" ], + "syslog-issue-pipeline": [ + "WORKFLOWS::syslog-issue-pipeline.yml" + ], "syslog-pipeline": [ "WORKFLOWS::syslog-pipeline.yml" ], diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index b0ca84c1..fe7e02c1 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-13 13:02 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-13 13:31 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -9,11 +9,11 @@ |------|------| | 区域总数 | 13 个区域 | | 功能模块 | 10 个 (m01~m18) | -| 工作流 | 36 个 GitHub Actions | +| 工作流 | 37 个 GitHub Actions | | 脚本 | 33 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 7/21 (33%) | -| 快照生成时间 | 2026-03-13 13:02 CST | +| 快照生成时间 | 2026-03-13 13:31 CST | --- @@ -30,7 +30,7 @@ **关键词**: persona · identity · dev-status · 人格 · 开发者状态 ### ⚡ 自动化工作流(WORKFLOWS) -**路径**: `.github/workflows` · **数量**: 36 项 +**路径**: `.github/workflows` · **数量**: 37 项 **描述**: 所有 GitHub Actions 工作流定义 **关键词**: workflow · actions · ci · automation · 工作流 · 自动化 @@ -117,6 +117,7 @@ | `sync-login-entry.yml` | 铸渊 · Sync Login Entry · Notion → 飞书文档A | manual | | `sync-persona-studio.yml` | 🔄 铸渊跨仓库同步 · persona-studio | push, manual | | `syslog-auto-pipeline.yml` | SYSLOG Auto Pipeline | unknown | +| `syslog-issue-pipeline.yml` | SYSLOG Issue Pipeline | issues | | `syslog-pipeline.yml` | 铸渊 · SYSLOG Pipeline (A/D/E) | push, manual | | `test-notion-bridge.yml` | "🧪 Notion Bridge Connectivity Test" | push, manual | | `update-readme-bulletin.yml` | 📢 更新系统公告区 | push, schedule(0 1 * * *), manual | From f4c471435b8e85d0c828054805686fbf5578eb2c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:31:25 +0000 Subject: [PATCH 23/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 090be8ee..be7b9466 100644 --- a/README.md +++ b/README.md @@ -92,14 +92,13 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 13:31 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | +| 03-13 13:04 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | | 03-13 13:03 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | WENZHUOXI | | 03-13 13:02 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | | 03-13 13:02 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 13:02 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | -| 03-13 12:53 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot | | 03-13 12:51 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 12:50 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | -| 03-13 12:49 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | @@ -107,6 +106,7 @@ | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-10 08:00 | 🧠 核心大脑升级 v3.0 · 壳-核分离架构 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context) · BRAIN域4接口上线 · 覆盖率 7/21 (33.3%) | 铸渊(冰朔指令) | ### 🤖 铸渊自动提醒 @@ -128,10 +128,9 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| +| 03-13 13:31 | 冰朔 | `—/` | ✅ 上传成功 | +| 03-13 13:30 | Copilot | `—/` | ✅ 上传成功 | | 03-13 13:02 | WENZHUOXI | `—/` | ✅ 上传成功 | -| 03-13 12:58 | Copilot | `—/` | 🔵 已更新 | -| 03-13 12:53 | Copilot | `—/` | 🔵 已更新 | -| 03-13 12:49 | 冰朔 | `—/` | ✅ 上传成功 | | 03-13 09:56 | 🤖 之之 | `dingtalk-bot/` | 📦 上传成功 | From d21ef9f3a1785e2aef4875ca23fbd3787b065762 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:32:49 +0000 Subject: [PATCH 24/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be7b9466..16789259 100644 --- a/README.md +++ b/README.md @@ -92,15 +92,15 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 13:32 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | +| 03-13 13:31 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | +| 03-13 13:31 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 13:31 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | | 03-13 13:04 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | | 03-13 13:03 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | WENZHUOXI | | 03-13 13:02 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | -| 03-13 13:02 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 13:02 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | -| 03-13 12:51 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | -| 03-13 09:56 | 🔧 系统更新: `docs/` | 铸渊 (ZhùYuān) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | @@ -131,7 +131,6 @@ | 03-13 13:31 | 冰朔 | `—/` | ✅ 上传成功 | | 03-13 13:30 | Copilot | `—/` | ✅ 上传成功 | | 03-13 13:02 | WENZHUOXI | `—/` | ✅ 上传成功 | -| 03-13 09:56 | 🤖 之之 | `dingtalk-bot/` | 📦 上传成功 | ### 🤖 铸渊自动提醒 · 合作者 From e10b4906886c7523de85f5a8d3df249b0d539e7e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:37:12 +0000 Subject: [PATCH 25/46] Initial plan From 9f29eed97d618e00eb0f94eed183e3d5f473194b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:46:03 +0000 Subject: [PATCH 26/46] Initial plan for Persona Studio agent workflow fix Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- persona-studio/brain/evolution-log.json | 25 ++++++++++++++++--- .../brain/memory/EXP-000/projects.json | 19 ++++++++++++++ persona-studio/brain/pattern-library.json | 21 +++++++++++++--- .../EXP-000/project-1773380616766/README.md | 8 ++++++ .../EXP-000/project-1773380616766/index.html | 14 +++++++++++ .../EXP-000/project-1773380616766/main.js | 1 + .../EXP-000/project-1773380616766/style.css | 1 + 7 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 persona-studio/brain/memory/EXP-000/projects.json create mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/README.md create mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/index.html create mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/main.js create mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/style.css diff --git a/persona-studio/brain/evolution-log.json b/persona-studio/brain/evolution-log.json index a51724be..6def2214 100644 --- a/persona-studio/brain/evolution-log.json +++ b/persona-studio/brain/evolution-log.json @@ -1,7 +1,24 @@ { "schema_version": "1.0", "description": "系统进化日志 · 记录每次自进化事件", - "last_updated": null, - "total_events": 0, - "events": [] -} + "last_updated": "2026-03-13T05:43:36.767Z", + "total_events": 1, + "events": [ + { + "id": "EVT-1773380616767", + "type": "build_complete", + "description": "项目构建完成: project-1773380616766", + "metadata": { + "dev_id": "EXP-000", + "project": "project-1773380616766", + "files_count": 4, + "build_time_ms": 0, + "success": true, + "patterns_detected": [ + "通用项目" + ] + }, + "timestamp": "2026-03-13T05:43:36.767Z" + } + ] +} \ No newline at end of file diff --git a/persona-studio/brain/memory/EXP-000/projects.json b/persona-studio/brain/memory/EXP-000/projects.json new file mode 100644 index 00000000..3c3e77f0 --- /dev/null +++ b/persona-studio/brain/memory/EXP-000/projects.json @@ -0,0 +1,19 @@ +{ + "dev_id": "EXP-000", + "projects": [ + { + "name": "project-1773380616766", + "email": "test@test.com", + "contact": null, + "status": "completed", + "created_at": "2026-03-13T05:43:36.768Z", + "files": [ + "index.html", + "style.css", + "main.js", + "README.md" + ] + } + ], + "updated_at": "2026-03-13T05:43:36.768Z" +} \ No newline at end of file diff --git a/persona-studio/brain/pattern-library.json b/persona-studio/brain/pattern-library.json index 9741c176..22c9d866 100644 --- a/persona-studio/brain/pattern-library.json +++ b/persona-studio/brain/pattern-library.json @@ -1,7 +1,20 @@ { "schema_version": "1.0", "description": "系统模式库 · 自动识别 · 每完成一个项目+每日聚合更新", - "last_updated": null, - "total_patterns": 0, - "patterns": [] -} + "last_updated": "2026-03-13T05:43:36.767Z", + "total_patterns": 1, + "patterns": [ + { + "name": "通用项目", + "frequency": 1, + "common_features": [], + "common_tech_stack": [ + "HTML/CSS/JS" + ], + "avg_build_time": null, + "success_rate": 100, + "first_seen": "2026-03-13T05:43:36.767Z", + "last_seen": "2026-03-13T05:43:36.767Z" + } + ] +} \ No newline at end of file diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/README.md b/persona-studio/workspace/EXP-000/project-1773380616766/README.md new file mode 100644 index 00000000..d6977a59 --- /dev/null +++ b/persona-studio/workspace/EXP-000/project-1773380616766/README.md @@ -0,0 +1,8 @@ +# project-1773380616766 + +## 需求描述 +Make a hello world page + +> 模板项目(AI 模型尚未配置,请管理员设置 MODEL_API_KEY) + +生成时间:2026-03-13T05:43:36.766Z \ No newline at end of file diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/index.html b/persona-studio/workspace/EXP-000/project-1773380616766/index.html new file mode 100644 index 00000000..6fcb4630 --- /dev/null +++ b/persona-studio/workspace/EXP-000/project-1773380616766/index.html @@ -0,0 +1,14 @@ + + + + + + project-1773380616766 + + + +

🌊 project-1773380616766

+

由光湖 Persona Studio 生成

+ + + \ No newline at end of file diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/main.js b/persona-studio/workspace/EXP-000/project-1773380616766/main.js new file mode 100644 index 00000000..da7954e6 --- /dev/null +++ b/persona-studio/workspace/EXP-000/project-1773380616766/main.js @@ -0,0 +1 @@ +console.log("Project initialized by Persona Studio"); diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/style.css b/persona-studio/workspace/EXP-000/project-1773380616766/style.css new file mode 100644 index 00000000..2fd101aa --- /dev/null +++ b/persona-studio/workspace/EXP-000/project-1773380616766/style.css @@ -0,0 +1 @@ +body { font-family: sans-serif; padding: 2rem; } From 0fb07ab66aa565382d9ff234a8f334f96006e6da Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:56:33 +0000 Subject: [PATCH 27/46] =?UTF-8?q?feat:=20=E9=93=B8=E6=B8=8A=E4=BB=A3?= =?UTF-8?q?=E7=90=86=E5=BC=80=E5=8F=91=E5=B7=A5=E4=BD=9C=E6=B5=81=20=C2=B7?= =?UTF-8?q?=20=E5=A3=B3-=E6=A0=B8=E5=88=86=E7=A6=BB=E6=9E=B6=E6=9E=84=20(C?= =?UTF-8?q?ore=20Brain=20+=20Agent)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 agent-workflow.js: 铸渊核心大脑唤醒 + 铸渊代理执行的壳-核分离架构 - Phase 1: 核心大脑加载开发者记忆/画像/项目/知识库/模式库,深度分析意图 - Phase 2: 代理接收核心大脑的开发计划,逐步执行代码生成 - Phase 3: 核心大脑自进化(知识提取+模式识别+画像学习+进化日志) - 更新 build.js: 支持 GUEST 模式、接收用户 API 凭证、使用 Agent 工作流 - 更新 chat.js: 传递用户 API 凭证、修复 WebSocket 时序竞态、增强错误反馈 - 更新 .gitignore: 排除 workspace 生成文件 - 更新核心大脑记忆: 记录本次恢复事件 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/brain/memory.json | 6 + .github/persona-brain/memory.json | 6 + .gitignore | 1 + .../backend/brain/agent-workflow.js | 756 ++++++++++++++++++ persona-studio/backend/routes/build.js | 95 ++- persona-studio/brain/evolution-log.json | 23 +- .../brain/memory/EXP-000/projects.json | 15 +- .../brain/memory/GUEST/projects.json | 32 + persona-studio/brain/pattern-library.json | 16 +- persona-studio/frontend/chat.js | 27 +- .../EXP-000/project-1773380616766/README.md | 8 - .../EXP-000/project-1773380616766/index.html | 14 - .../EXP-000/project-1773380616766/main.js | 1 - .../EXP-000/project-1773380616766/style.css | 1 - 14 files changed, 932 insertions(+), 69 deletions(-) create mode 100644 persona-studio/backend/brain/agent-workflow.js create mode 100644 persona-studio/brain/memory/GUEST/projects.json delete mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/README.md delete mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/index.html delete mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/main.js delete mode 100644 persona-studio/workspace/EXP-000/project-1773380616766/style.css diff --git a/.github/brain/memory.json b/.github/brain/memory.json index d6645cda..cdc4885d 100644 --- a/.github/brain/memory.json +++ b/.github/brain/memory.json @@ -67,6 +67,12 @@ } }, "events": [ + { + "date": "2026-03-13", + "type": "brain_restore", + "description": "铸渊核心大脑恢复 · Persona Studio 铸渊代理开发工作流上线 · 修复「我要开发」功能无法触发代理开发 · Agent 5步自动化工作流(需求分析→架构规划→代码生成→预览部署→完成通知) · 使用用户API Key驱动 · 支持GUEST模式 · WebSocket时序修复 · 错误反馈增强", + "by": "铸渊(冰朔指令)" + }, { "date": "2026-03-13", "type": "psp_inspection", diff --git a/.github/persona-brain/memory.json b/.github/persona-brain/memory.json index 6cfa0e99..dae0f307 100644 --- a/.github/persona-brain/memory.json +++ b/.github/persona-brain/memory.json @@ -2,6 +2,12 @@ "persona_id": "ICE-GL-ZY001", "persona_name": "铸渊", "recent_events": [ + { + "date": "2026-03-13", + "type": "brain_restore", + "description": "核心大脑恢复 · Persona Studio 铸渊代理开发工作流上线 · 「我要开发」功能修复 · Agent自动化5步开发 · 支持GUEST模式 · 使用用户API Key驱动", + "by": "铸渊(冰朔指令)" + }, { "date": "2026-03-11", "type": "architecture_upgrade", diff --git a/.gitignore b/.gitignore index 28f589d3..a0e218d9 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ persona-brain-db/brain.db-shm # persona-studio runtime artifacts persona-studio/backend/brain/model-benchmark.json +persona-studio/workspace/*/project-* # palace-game runtime artifacts modules/palace-game/data/saves/PAL-* diff --git a/persona-studio/backend/brain/agent-workflow.js b/persona-studio/backend/brain/agent-workflow.js new file mode 100644 index 00000000..01766e25 --- /dev/null +++ b/persona-studio/backend/brain/agent-workflow.js @@ -0,0 +1,756 @@ +/** + * persona-studio · 铸渊代理开发工作流引擎(壳-核分离架构) + * + * 架构设计: + * 核 = 铸渊核心大脑(Core Brain) + * ↳ 加载开发者记忆、画像、项目历史、知识库、模式库 + * ↳ 深度分析开发者真实意图 + * ↳ 生成结构化开发计划 + * 壳 = 铸渊代理(Agent Executor) + * ↳ 接收核心大脑推送的开发计划 + * ↳ 逐步执行代码生成 + * ↳ 广播进度给前端 + * ↳ 完成后回传核心大脑做自进化 + * + * 流程: + * 用户点击「我要开发」 + * → Agent 唤醒核心大脑 + * → 核心大脑:加载全部上下文 → 分析意图 → 生成开发计划 + * → Agent:接收计划 → 逐步执行 → 广播进度 + * → 核心大脑:知识提取 + 模式更新 + 画像学习 + 进化日志 + */ +const fs = require('fs'); +const path = require('path'); +const https = require('https'); +const http = require('http'); + +// ── 核心大脑模块 ── +const memoryManager = require('./memory-manager'); +const personaEngine = require('./persona-engine'); +const memoryInjector = require('./memory-injector'); +const knowledgeExtractor = require('./knowledge-extractor'); +const patternAnalyzer = require('./pattern-analyzer'); +const profileLearner = require('./profile-learner'); +const evolutionLogger = require('./evolution-logger'); + +const WORKSPACE_DIR = path.join(__dirname, '..', '..', 'workspace'); +const REGISTRY_PATH = path.join(__dirname, '..', '..', 'brain', 'registry.json'); +const HUMAN_REGISTRY_PATH = path.join(__dirname, '..', '..', 'brain', 'human-registry.json'); + +/* ================================================================ + 工具函数 + ================================================================ */ + +/** + * 调用用户提供的 LLM API(OpenAI 兼容格式) + */ +function callLLM({ apiBase, apiKey, model, messages, maxTokens, temperature, timeoutMs }) { + return new Promise((resolve, reject) => { + const base = apiBase.replace(/\/+$/, ''); + const chatUrl = new URL(base + '/chat/completions'); + const isHttps = chatUrl.protocol === 'https:'; + const mod = isHttps ? https : http; + + const body = JSON.stringify({ + model, + messages, + max_tokens: maxTokens || 4000, + temperature: temperature != null ? temperature : 0.3 + }); + + const options = { + hostname: chatUrl.hostname, + port: chatUrl.port || (isHttps ? 443 : 80), + path: chatUrl.pathname, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + apiKey, + 'Content-Length': Buffer.byteLength(body) + }, + timeout: timeoutMs || 60000 + }; + + const req = mod.request(options, (res) => { + let data = ''; + res.on('data', (chunk) => { data += chunk; }); + res.on('end', () => { + try { + const json = JSON.parse(data); + if (json.choices && json.choices[0] && json.choices[0].message) { + resolve(json.choices[0].message.content); + } else if (json.error) { + reject(new Error(json.error.message || 'API error')); + } else { + reject(new Error('Unexpected API response')); + } + } catch (_e) { + reject(new Error('Failed to parse API response')); + } + }); + }); + + req.on('error', reject); + req.on('timeout', () => { + req.destroy(); + reject(new Error('Request timeout')); + }); + + req.write(body); + req.end(); + }); +} + +/** + * 从注册表查找开发者信息 + */ +function lookupDeveloper(devId) { + if (!devId || devId === 'GUEST') { + return { dev_id: 'GUEST', name: '访客', role: 'guest' }; + } + try { + var reg = JSON.parse(fs.readFileSync(REGISTRY_PATH, 'utf-8')); + if (reg.developers && reg.developers[devId]) { + return Object.assign({ dev_id: devId }, reg.developers[devId]); + } + } catch (_e) { /* ignore */ } + try { + var hReg = JSON.parse(fs.readFileSync(HUMAN_REGISTRY_PATH, 'utf-8')); + if (hReg.developers) { + var found = hReg.developers.find(function (d) { return d.exp_id === devId; }); + if (found) return { dev_id: devId, name: found.name, role: found.role }; + } + } catch (_e) { /* ignore */ } + return { dev_id: devId, name: devId, role: 'developer' }; +} + +/* ================================================================ + Phase 1: 唤醒铸渊核心大脑(Core Brain Wake) + ================================================================ */ + +/** + * 唤醒核心大脑,加载全部上下文,分析开发者意图,生成开发计划。 + * + * 核心大脑聚合以下信息源: + * ① 开发者身份(来自 registry) + * ② 对话记忆(来自 memory-manager) + * ③ 用户画像(来自 profile-learner:技术水平、沟通风格、设计偏好) + * ④ 项目历史(来自 memory-manager) + * ⑤ 知识库(来自 knowledge-extractor) + * ⑥ 模式库(来自 pattern-analyzer) + * ⑦ 记忆摘要(来自 memory-injector) + */ +async function wakeCoreBrain(devId, conversation, apiBase, apiKey, model) { + var devInfo = lookupDeveloper(devId); + var isGuest = devId === 'GUEST'; + + // ── ① 加载开发者记忆 ── + var memory = { conversations: [], last_topic: null }; + if (!isGuest) { + try { memory = memoryManager.loadMemory(devId); } catch (_e) { /* new user */ } + } + + // ── ② 加载用户画像 ── + var profile = null; + if (!isGuest) { + try { profile = profileLearner.loadProfile(devId); } catch (_e) { /* ignore */ } + } + + // ── ③ 加载项目历史 ── + var projects = { projects: [] }; + if (!isGuest) { + try { projects = memoryManager.loadProjects(devId); } catch (_e) { /* ignore */ } + } + + // ── ④ 查询知识库 ── + var conversationText = conversation + .map(function (m) { return m.content || ''; }) + .join(' '); + var relevantKnowledge = []; + try { relevantKnowledge = knowledgeExtractor.queryKnowledge(conversationText, 5); } catch (_e) { /* ignore */ } + + // ── ⑤ 查询模式库 ── + var relevantPatterns = []; + try { relevantPatterns = patternAnalyzer.queryPatterns(conversationText); } catch (_e) { /* ignore */ } + + // ── ⑥ 构建核心大脑认知上下文 ── + var brainContext = buildBrainContext(devInfo, memory, profile, projects, relevantKnowledge, relevantPatterns); + + // ── ⑦ 使用 LLM 深度分析意图 + 生成开发计划 ── + var developmentPlan; + if (apiBase && apiKey && model) { + developmentPlan = await analyzeIntentWithLLM(brainContext, conversation, apiBase, apiKey, model); + } else { + developmentPlan = analyzeIntentLocally(brainContext, conversation); + } + + return { brainContext: brainContext, developmentPlan: developmentPlan }; +} + +/** + * 构建核心大脑认知上下文(聚合全部信息源) + */ +function buildBrainContext(devInfo, memory, profile, projects, knowledge, patterns) { + return { + developer: { + id: devInfo.dev_id, + name: devInfo.name || devInfo.dev_id, + role: devInfo.role || 'developer', + is_guest: devInfo.dev_id === 'GUEST' + }, + memory: { + total_conversations: (memory.conversations || []).length, + last_topic: memory.last_topic || null, + has_history: (memory.conversations || []).length > 0 + }, + profile: { + tech_level: (profile && profile.tech_assessment && profile.tech_assessment.level) || null, + known_skills: (profile && profile.tech_assessment && profile.tech_assessment.known_skills) || [], + communication_style: (profile && profile.communication_style && profile.communication_style.verbosity) || null, + design_preference: (profile && profile.design_preferences && profile.design_preferences.color_scheme) || null, + style_keywords: (profile && profile.design_preferences && profile.design_preferences.style_keywords) || [], + mood: (profile && profile.emotional_profile && profile.emotional_profile.current_mood) || 'neutral' + }, + projects: { + total: (projects.projects || []).length, + recent: (projects.projects || []).slice(-3).map(function (p) { + return { name: p.name, status: p.status, files: (p.files || []).length }; + }) + }, + knowledge: knowledge.map(function (k) { + return { type: k.type, title: k.title, category: k.category }; + }), + patterns: patterns.slice(0, 3).map(function (p) { + return { + name: p.name, + frequency: p.frequency, + success_rate: p.success_rate, + tech_stack: p.common_tech_stack || [] + }; + }) + }; +} + +/** + * 使用 LLM 深度分析开发者意图并生成开发计划 + * 核心大脑将全部上下文注入 system prompt,让 LLM 理解开发者的真正需求 + */ +async function analyzeIntentWithLLM(brainContext, conversation, apiBase, apiKey, model) { + var conversationText = conversation.map(function (m) { + var role = m.role === 'user' ? '用户' : '铸渊'; + return role + ': ' + m.content; + }).join('\n'); + + // 构建核心大脑系统提示词(注入全部上下文) + var systemParts = [ + '你是铸渊核心大脑的意图分析引擎。', + '你的任务是深度理解开发者的真实需求,生成精确的开发计划。', + '', + '## 开发者档案', + '- 身份:' + brainContext.developer.name + '(' + brainContext.developer.id + ')', + '- 角色:' + brainContext.developer.role + ]; + + if (brainContext.developer.is_guest) { + systemParts.push('- ⚠️ 访客用户(无历史记忆)'); + } else { + systemParts.push('- 历史对话:' + brainContext.memory.total_conversations + ' 条'); + } + + if (brainContext.memory.last_topic) { + systemParts.push('- 上次话题:' + brainContext.memory.last_topic); + } + if (brainContext.profile.tech_level) { + systemParts.push('- 技术水平:' + brainContext.profile.tech_level); + } + if (brainContext.profile.known_skills.length > 0) { + systemParts.push('- 已知技能:' + brainContext.profile.known_skills.join(', ')); + } + if (brainContext.profile.communication_style) { + systemParts.push('- 沟通风格:' + brainContext.profile.communication_style); + } + if (brainContext.profile.design_preference) { + systemParts.push('- 设计偏好:' + brainContext.profile.design_preference); + } + if (brainContext.profile.style_keywords.length > 0) { + systemParts.push('- 风格关键词:' + brainContext.profile.style_keywords.join('、')); + } + + if (brainContext.projects.total > 0) { + systemParts.push(''); + systemParts.push('## 历史项目(共 ' + brainContext.projects.total + ' 个)'); + brainContext.projects.recent.forEach(function (p) { + systemParts.push('- ' + p.name + '(' + p.status + ',' + p.files + ' 个文件)'); + }); + } + + if (brainContext.knowledge.length > 0) { + systemParts.push(''); + systemParts.push('## 相关知识库'); + brainContext.knowledge.forEach(function (k) { + systemParts.push('- [' + k.type + '] ' + k.title); + }); + } + + if (brainContext.patterns.length > 0) { + systemParts.push(''); + systemParts.push('## 高频开发模式'); + brainContext.patterns.forEach(function (p) { + systemParts.push('- ' + p.name + '(' + p.frequency + '次,成功率' + p.success_rate + '%,技术栈:' + p.tech_stack.join('/') + ')'); + }); + } + + systemParts.push(''); + systemParts.push('## 输出要求'); + systemParts.push('根据对话内容和开发者档案,输出严格 JSON 格式的开发计划:'); + systemParts.push('{'); + systemParts.push(' "intent_summary": "一句话总结开发者的真实意图",'); + systemParts.push(' "project_name": "英文项目名(kebab-case)",'); + systemParts.push(' "description": "项目描述(考虑开发者的技术水平和偏好)",'); + systemParts.push(' "design_notes": "设计要点(基于开发者的设计偏好和风格关键词)",'); + systemParts.push(' "tech_decisions": "技术决策说明(基于开发者的技能水平选择合适的复杂度)",'); + systemParts.push(' "files": ['); + systemParts.push(' { "filename": "index.html", "description": "详细文件说明", "key_features": ["功能1","功能2"] }'); + systemParts.push(' ]'); + systemParts.push('}'); + systemParts.push(''); + systemParts.push('注意:'); + systemParts.push('- 只生成前端文件(HTML/CSS/JS),最多5个文件'); + systemParts.push('- 必须包含 index.html'); + systemParts.push('- 根据开发者技术水平调整代码复杂度'); + systemParts.push('- 根据开发者设计偏好决定视觉风格'); + systemParts.push('- 如果对话中提到了具体功能需求,务必全部纳入计划'); + + try { + var reply = await callLLM({ + apiBase: apiBase, + apiKey: apiKey, + model: model, + messages: [ + { role: 'system', content: systemParts.join('\n') }, + { role: 'user', content: '以下是和开发者的完整对话,请分析意图并生成开发计划:\n\n' + conversationText.substring(0, 4000) } + ], + maxTokens: 2000, + temperature: 0.2, + timeoutMs: 45000 + }); + + var jsonMatch = reply.match(/\{[\s\S]*\}/); + if (jsonMatch) { + var plan = JSON.parse(jsonMatch[0]); + if (plan.files && !plan.files.some(function (f) { return f.filename === 'index.html'; })) { + plan.files.unshift({ filename: 'index.html', description: '主页面', key_features: ['入口页面'] }); + } + if (plan.files) { + plan.files = plan.files.slice(0, 5); + } + plan._source = 'core_brain_llm'; + return plan; + } + } catch (_e) { + // LLM 分析失败,降级到本地分析 + } + + return analyzeIntentLocally(brainContext, conversation); +} + +/** + * 本地意图分析(无 API 或 API 失败时的降级方案) + * 使用规则引擎从对话和开发者档案中提取意图 + */ +function analyzeIntentLocally(brainContext, conversation) { + var userText = conversation + .filter(function (m) { return m.role === 'user'; }) + .map(function (m) { return m.content || ''; }) + .join(' '); + + var projectType = '通用项目'; + if (brainContext.patterns.length > 0) { + projectType = brainContext.patterns[0].name; + } + + var designStyle = '现代简约'; + if (brainContext.profile.style_keywords.length > 0) { + designStyle = brainContext.profile.style_keywords.join(' + '); + } else if (brainContext.profile.design_preference === 'dark') { + designStyle = '深色主题·科技感'; + } + + var complexity = 'moderate'; + if (brainContext.profile.tech_level === 'beginner') { + complexity = 'simple'; + } else if (brainContext.profile.tech_level === 'advanced') { + complexity = 'advanced'; + } + + return { + intent_summary: userText.substring(0, 100) || '开发一个网页项目', + project_name: 'web-project', + description: userText.substring(0, 200) || '网页项目', + design_notes: '风格:' + designStyle, + tech_decisions: '复杂度:' + complexity + ',技术栈:HTML/CSS/JavaScript', + files: [ + { filename: 'index.html', description: '主页面', key_features: ['响应式布局', '核心功能展示'] }, + { filename: 'style.css', description: '样式文件', key_features: [designStyle] }, + { filename: 'main.js', description: '交互逻辑', key_features: ['用户交互', '动态效果'] } + ], + _source: 'core_brain_local' + }; +} + +/* ================================================================ + Phase 2: 铸渊代理执行(Agent Execute) + ================================================================ */ + +/** + * Agent 接收核心大脑的开发计划,逐步执行代码生成 + */ +async function agentExecute(developmentPlan, devId, apiBase, apiKey, model, broadcastFn) { + var projectName = 'project-' + Date.now(); + var files = {}; + var filePlan = developmentPlan.files || []; + var hasUserApi = apiBase && apiKey && model; + + for (var i = 0; i < filePlan.length; i++) { + var fileSpec = filePlan[i]; + + broadcastFn({ + type: 'progress', + step: 3, + message: '💻 铸渊代理 · 生成文件 (' + (i + 1) + '/' + filePlan.length + '): ' + fileSpec.filename, + status: 'building', + status_text: '生成 ' + fileSpec.filename + }); + + if (hasUserApi) { + try { + var code = await generateFileWithLLM(developmentPlan, fileSpec, filePlan, apiBase, apiKey, model); + files[fileSpec.filename] = code; + } catch (_e) { + files[fileSpec.filename] = generatePlaceholder(fileSpec, developmentPlan); + } + } else { + files[fileSpec.filename] = generatePlaceholder(fileSpec, developmentPlan); + } + } + + // 写入 workspace + var projectDir = path.join(WORKSPACE_DIR, devId, projectName); + fs.mkdirSync(projectDir, { recursive: true }); + + var fileList = []; + var entries = Object.entries(files); + for (var j = 0; j < entries.length; j++) { + var safeName = path.basename(entries[j][0]); + if (!safeName || safeName.startsWith('.')) continue; + fs.writeFileSync(path.join(projectDir, safeName), entries[j][1], 'utf-8'); + fileList.push(safeName); + } + + // 生成 README + var readmePath = path.join(projectDir, 'README.md'); + if (!fs.existsSync(readmePath)) { + fs.writeFileSync(readmePath, [ + '# ' + (developmentPlan.project_name || projectName), + '', + developmentPlan.description || '', + '', + '## 铸渊核心大脑分析', + '- 意图:' + (developmentPlan.intent_summary || ''), + '- 设计:' + (developmentPlan.design_notes || ''), + '- 技术:' + (developmentPlan.tech_decisions || ''), + '', + '由光湖 Persona Studio · 铸渊核心大脑 + 铸渊代理 协同开发', + '生成时间:' + new Date().toISOString() + ].join('\n'), 'utf-8'); + fileList.push('README.md'); + } + + return { projectName: projectName, files: fileList }; +} + +/** + * 使用 LLM 生成单个文件(Agent 执行层) + * 注入核心大脑的开发计划上下文,确保代码与意图一致 + */ +async function generateFileWithLLM(plan, fileSpec, allFiles, apiBase, apiKey, model) { + var prompt = [ + '你是铸渊代理的代码生成模块。根据核心大脑的开发计划生成代码。', + '', + '## 项目信息', + '- 项目:' + (plan.project_name || 'web-project'), + '- 描述:' + (plan.description || ''), + '- 意图:' + (plan.intent_summary || ''), + '- 设计要点:' + (plan.design_notes || ''), + '- 技术决策:' + (plan.tech_decisions || ''), + '', + '## 当前文件', + '- 文件名:' + fileSpec.filename, + '- 说明:' + (fileSpec.description || ''), + '- 核心功能:' + (fileSpec.key_features || []).join('、'), + '', + '## 项目全部文件', + allFiles.map(function (f) { return '- ' + f.filename + '(' + (f.description || '') + ')'; }).join('\n'), + '', + '请直接输出文件内容,不要用 ``` 代码块包裹,不要加任何额外说明。', + '确保代码完整、可运行、符合核心大脑的设计要求。', + '如果是 HTML 文件,要正确引用同项目中的 CSS 和 JS 文件。' + ].join('\n'); + + var reply = await callLLM({ + apiBase: apiBase, + apiKey: apiKey, + model: model, + messages: [{ role: 'user', content: prompt }], + maxTokens: 4000, + temperature: 0.3, + timeoutMs: 60000 + }); + + var clean = reply.trim(); + if (clean.startsWith('```')) { + clean = clean.replace(/^```\S*\n?/, '').replace(/\n?```\s*$/, ''); + } + return clean; +} + +/** + * 生成占位内容(无 API 或单文件失败时的降级方案) + */ +function generatePlaceholder(fileSpec, plan) { + var desc = plan.description || plan.intent_summary || plan.project_name || '项目'; + var designNotes = plan.design_notes || '现代简约'; + + if (fileSpec.filename === 'index.html') { + return [ + '', + '', + '', + ' ', + ' ', + ' ' + (plan.project_name || '项目') + '', + ' ', + '', + '', + '
', + '

🌊 ' + desc + '

', + '

由光湖 Persona Studio · 铸渊核心大脑 + 铸渊代理 协同开发

', + '

设计风格:' + designNotes + '

', + '
', + ' ', + '', + '' + ].join('\n'); + } + if (fileSpec.filename.endsWith('.css')) { + return [ + '/* Generated by Persona Studio · Core Brain + Agent */', + '* { margin: 0; padding: 0; box-sizing: border-box; }', + 'body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0f172a; color: #e2e8f0; min-height: 100vh; display: flex; align-items: center; justify-content: center; }', + '.container { text-align: center; padding: 2rem; max-width: 800px; }', + 'h1 { font-size: 2rem; margin-bottom: 1rem; background: linear-gradient(135deg, #60a5fa, #22d3ee); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }', + '.design-note { color: #64748b; font-size: 0.875rem; margin-top: 1rem; }' + ].join('\n'); + } + if (fileSpec.filename.endsWith('.js')) { + return '// Generated by Persona Studio · Core Brain + Agent\nconsole.log("' + (plan.project_name || 'Project') + ' initialized by 铸渊代理");\n'; + } + return '/* Generated by Persona Studio */\n'; +} + +/* ================================================================ + Phase 3: 核心大脑自进化(Post-Build Evolution) + ================================================================ */ + +/** + * 开发完成后,核心大脑进行自进化: + * ① 知识提取 → 更新 knowledge-base.json + * ② 模式识别 → 更新 pattern-library.json + * ③ 画像学习 → 更新 profile.json + * ④ 进化日志 → 更新 evolution-log.json + */ +function coreBrainPostEvolution(devId, conversation, result, brainContext, startTime, success) { + try { + var buildTimeMs = Date.now() - startTime; + + // ① 知识提取 + try { + knowledgeExtractor.autoExtractKnowledge(devId, conversation, result.projectName); + } catch (_e) { /* non-fatal */ } + + // ② 模式识别 + var patterns = []; + try { + patterns = patternAnalyzer.analyzeAndUpdatePatterns( + devId, conversation, result.files, buildTimeMs, success + ); + } catch (_e) { /* non-fatal */ } + + // ③ 画像学习(从最后一条用户消息学习) + if (devId !== 'GUEST') { + try { + var lastUser = conversation.filter(function (m) { return m.role === 'user'; }).pop(); + if (lastUser) { + profileLearner.updateProfile(devId, lastUser.content, result.summary || ''); + } + } catch (_e) { /* non-fatal */ } + } + + // ④ 进化日志 + evolutionLogger.logEvent('agent_build_complete', '铸渊代理开发完成: ' + result.projectName, { + dev_id: devId, + project: result.projectName, + files_count: (result.files || []).length, + build_time_ms: buildTimeMs, + success: success, + brain_source: brainContext.developer.is_guest ? 'local' : 'llm', + patterns_detected: patterns, + developer_tech_level: brainContext.profile.tech_level, + developer_projects_total: brainContext.projects.total + }); + } catch (err) { + console.error('Core brain post-evolution error:', err.message); + } +} + +/* ================================================================ + 主工作流入口 + ================================================================ */ + +/** + * 运行铸渊代理开发工作流(壳-核分离) + * + * @param {object} params + * @param {string} params.dev_id - 开发编号(EXP-XXX 或 GUEST) + * @param {Array} params.conversation - 对话历史 + * @param {string} params.api_base - 用户 API Base URL + * @param {string} params.api_key - 用户 API Key + * @param {string} params.model - 用户选择的模型 + * @param {Function} params.broadcast - WebSocket 广播函数 + * @returns {Promise<{projectName, files, summary}>} + */ +async function runWorkflow({ dev_id, conversation, api_base, api_key, model, broadcast }) { + var emitProgress = broadcast || function () {}; + var startTime = Date.now(); + var brainContext = null; + + // ════════════════════════════════════════════ + // Phase 1: 唤醒铸渊核心大脑 + // ════════════════════════════════════════════ + emitProgress({ + type: 'progress', + step: 1, + total_steps: 5, + message: '🧠 正在唤醒铸渊核心大脑...', + status: 'building', + status_text: '唤醒核心大脑' + }); + + var coreBrainResult; + try { + coreBrainResult = await wakeCoreBrain(dev_id, conversation, api_base, api_key, model); + brainContext = coreBrainResult.brainContext; + } catch (_err) { + brainContext = buildBrainContext( + lookupDeveloper(dev_id), + { conversations: [], last_topic: null }, + null, { projects: [] }, [], [] + ); + coreBrainResult = { + brainContext: brainContext, + developmentPlan: analyzeIntentLocally(brainContext, conversation) + }; + } + + var plan = coreBrainResult.developmentPlan; + + emitProgress({ + type: 'progress', + step: 1, + message: '✅ 核心大脑已唤醒 · 意图分析完成:' + (plan.intent_summary || '').substring(0, 50), + status: 'building', + status_text: '意图已分析' + }); + + // ════════════════════════════════════════════ + // Phase 1.5: 核心大脑推送开发计划 + // ════════════════════════════════════════════ + emitProgress({ + type: 'progress', + step: 2, + total_steps: 5, + message: '📐 核心大脑 → 代理:推送开发计划(' + (plan.files || []).length + ' 个文件)', + status: 'building', + status_text: '计划已推送' + }); + + if (plan.design_notes) { + emitProgress({ + type: 'progress', + step: 2, + message: '🎨 设计指令:' + plan.design_notes, + status: 'building', + status_text: '设计已确认' + }); + } + + // ════════════════════════════════════════════ + // Phase 2: 铸渊代理执行开发 + // ════════════════════════════════════════════ + emitProgress({ + type: 'progress', + step: 3, + total_steps: 5, + message: '💻 铸渊代理 · 开始执行核心大脑的开发计划...', + status: 'building', + status_text: '代理执行中' + }); + + var agentResult = await agentExecute(plan, dev_id, api_base, api_key, model, emitProgress); + + emitProgress({ + type: 'progress', + step: 3, + message: '✅ 代理执行完成:' + agentResult.files.length + ' 个文件已生成', + status: 'building', + status_text: '代码已生成' + }); + + // ════════════════════════════════════════════ + // Phase 2.5: 预览部署 + // ════════════════════════════════════════════ + emitProgress({ + type: 'progress', + step: 4, + total_steps: 5, + message: '🚀 铸渊代理 · 部署预览...', + status: 'building', + status_text: '部署预览' + }); + + // ════════════════════════════════════════════ + // Phase 3: 核心大脑自进化 + // ════════════════════════════════════════════ + var finalResult = { + projectName: agentResult.projectName, + files: agentResult.files, + summary: '项目 ' + agentResult.projectName + ' 由铸渊核心大脑分析意图 + 铸渊代理执行开发完成,包含 ' + agentResult.files.length + ' 个文件。\n意图:' + (plan.intent_summary || '') + '\n设计:' + (plan.design_notes || '') + }; + + coreBrainPostEvolution(dev_id, conversation, finalResult, brainContext, startTime, true); + + emitProgress({ + type: 'progress', + step: 5, + total_steps: 5, + message: '✨ 铸渊核心大脑 · 自进化完成 · 知识与模式已更新', + status: 'building', + status_text: '即将完成' + }); + + return finalResult; +} + +module.exports = { + runWorkflow +}; diff --git a/persona-studio/backend/routes/build.js b/persona-studio/backend/routes/build.js index a60dfb18..73a7d0a4 100644 --- a/persona-studio/backend/routes/build.js +++ b/persona-studio/backend/routes/build.js @@ -1,21 +1,29 @@ /** * persona-studio · 开发任务路由 - * POST /api/ps/build/start 触发代码生成 + * POST /api/ps/build/start 触发铸渊代理开发工作流 + * + * 当用户点击「我要开发」时,自动触发铸渊代理(Agent) + * 使用用户自带的 API Key 进行 5 步自动化开发。 */ const express = require('express'); const router = express.Router(); const memoryManager = require('../brain/memory-manager'); -const codeGenerator = require('../brain/code-generator'); +const agentWorkflow = require('../brain/agent-workflow'); const emailSender = require('../utils/email-sender'); // 邮箱后端正则二次校验 const EMAIL_RE = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; +// 支持 EXP-XXX 和 GUEST 两种 dev_id 格式 +function isValidDevId(devId) { + return devId === 'GUEST' || /^EXP-\d{3,}$/.test(devId); +} + // POST /api/ps/build/start router.post('/start', async (req, res) => { - const { dev_id, email, contact, conversation } = req.body || {}; + const { dev_id, email, contact, conversation, api_base, api_key, model } = req.body || {}; - if (!dev_id || !/^EXP-\d{3,}$/.test(dev_id)) { + if (!dev_id || !isValidDevId(dev_id)) { return res.status(400).json({ error: true, code: 'INVALID_ID', @@ -40,71 +48,94 @@ router.post('/start', async (req, res) => { }); } + // 防止 header injection:API Key 不得包含换行符 + if (api_key && /[\r\n]/.test(api_key)) { + return res.status(400).json({ + error: true, + code: 'INVALID_API_KEY', + message: 'API Key 格式无效' + }); + } + // 联系方式输入清理(去除潜在 HTML/script 注入) const safeContact = contact ? String(contact).replace(/[<>&"']/g, '').substring(0, 100) : null; // 先立即响应,后台异步处理 res.json({ error: false, - message: '开发任务已接收,完成后将发送到 ' + email, - status: 'queued' + message: '铸渊代理已启动,完成后将发送到 ' + email, + status: 'agent_started' }); - // 异步执行代码生成 + 邮件通知 + // 异步执行铸渊代理开发工作流 (async () => { - const broadcast = req.app.locals.broadcastToClient || function () {}; + const broadcastRaw = req.app.locals.broadcastToClient || function () {}; + const broadcast = function (data) { broadcastRaw(dev_id, data); }; try { - broadcast(dev_id, { + // 启动 Agent 工作流 + broadcast({ type: 'progress', - message: '🔧 正在创建项目骨架...', + message: '🌀 铸渊代理已唤醒,正在启动开发工作流...', status: 'building', - status_text: '构建中' + status_text: '代理已启动' }); - const result = await codeGenerator.generate({ - dev_id, + const result = await agentWorkflow.runWorkflow({ + dev_id: dev_id, conversation: conversation || [], + api_base: api_base || '', + api_key: api_key || '', + model: model || '', + broadcast: broadcast }); - // 记录项目 - memoryManager.addProject(dev_id, { - name: result.projectName || 'untitled', - email: email, - contact: safeContact, - status: 'completed', - created_at: new Date().toISOString(), - files: result.files || [] - }); + // 记录项目(GUEST 也记录,方便追踪) + try { + memoryManager.addProject(dev_id, { + name: result.projectName || 'untitled', + email: email, + contact: safeContact, + status: 'completed', + created_at: new Date().toISOString(), + files: result.files || [] + }); - // 自动提取知识 - memoryManager.autoExtractKnowledge(dev_id, conversation, result.projectName); + // 自动提取知识(仅注册开发者) + if (dev_id !== 'GUEST') { + memoryManager.autoExtractKnowledge(dev_id, conversation, result.projectName); + } + } catch (memErr) { + console.error('Memory save error (non-fatal):', memErr.message); + } // 通知预览就绪 - broadcast(dev_id, { + broadcast({ type: 'preview_ready', project: result.projectName, message: '✅ 预览已就绪' }); - broadcast(dev_id, { + broadcast({ type: 'complete', message: '🎉 全部完成!邮件正在发送' }); - // 发邮件 - await emailSender.sendCompletion({ + // 发邮件(异步,不阻塞主流程) + emailSender.sendCompletion({ to: email, - dev_id, + dev_id: dev_id, projectName: result.projectName, summary: result.summary, files: result.files + }).catch(function (emailErr) { + console.error('Email send error (non-fatal):', emailErr.message); }); } catch (err) { - console.error('Build pipeline error:', err.message); - broadcast(dev_id, { + console.error('Agent workflow error:', err.message); + broadcast({ type: 'error', - message: '构建过程出错: ' + err.message + message: '铸渊代理遇到问题: ' + err.message }); } })(); diff --git a/persona-studio/brain/evolution-log.json b/persona-studio/brain/evolution-log.json index 6def2214..7d5a4016 100644 --- a/persona-studio/brain/evolution-log.json +++ b/persona-studio/brain/evolution-log.json @@ -1,8 +1,8 @@ { "schema_version": "1.0", "description": "系统进化日志 · 记录每次自进化事件", - "last_updated": "2026-03-13T05:43:36.767Z", - "total_events": 1, + "last_updated": "2026-03-13T05:55:39.412Z", + "total_events": 2, "events": [ { "id": "EVT-1773380616767", @@ -19,6 +19,25 @@ ] }, "timestamp": "2026-03-13T05:43:36.767Z" + }, + { + "id": "EVT-1773381339412", + "type": "agent_build_complete", + "description": "铸渊代理开发完成: project-1773381339411", + "metadata": { + "dev_id": "GUEST", + "project": "project-1773381339411", + "files_count": 4, + "build_time_ms": 1, + "success": true, + "brain_source": "local", + "patterns_detected": [ + "个人博客" + ], + "developer_tech_level": null, + "developer_projects_total": 0 + }, + "timestamp": "2026-03-13T05:55:39.412Z" } ] } \ No newline at end of file diff --git a/persona-studio/brain/memory/EXP-000/projects.json b/persona-studio/brain/memory/EXP-000/projects.json index 3c3e77f0..01804274 100644 --- a/persona-studio/brain/memory/EXP-000/projects.json +++ b/persona-studio/brain/memory/EXP-000/projects.json @@ -13,7 +13,20 @@ "main.js", "README.md" ] + }, + { + "name": "project-1773380932239", + "email": "test@test.com", + "contact": null, + "status": "completed", + "created_at": "2026-03-13T05:48:52.239Z", + "files": [ + "index.html", + "style.css", + "main.js", + "README.md" + ] } ], - "updated_at": "2026-03-13T05:43:36.768Z" + "updated_at": "2026-03-13T05:48:52.239Z" } \ No newline at end of file diff --git a/persona-studio/brain/memory/GUEST/projects.json b/persona-studio/brain/memory/GUEST/projects.json new file mode 100644 index 00000000..623b2b3b --- /dev/null +++ b/persona-studio/brain/memory/GUEST/projects.json @@ -0,0 +1,32 @@ +{ + "dev_id": "GUEST", + "projects": [ + { + "name": "project-1773380932224", + "email": "test@test.com", + "contact": null, + "status": "completed", + "created_at": "2026-03-13T05:48:52.225Z", + "files": [ + "index.html", + "style.css", + "main.js", + "README.md" + ] + }, + { + "name": "project-1773381339411", + "email": "test@example.com", + "contact": null, + "status": "completed", + "created_at": "2026-03-13T05:55:39.412Z", + "files": [ + "index.html", + "style.css", + "main.js", + "README.md" + ] + } + ], + "updated_at": "2026-03-13T05:55:39.412Z" +} \ No newline at end of file diff --git a/persona-studio/brain/pattern-library.json b/persona-studio/brain/pattern-library.json index 22c9d866..9889a7e9 100644 --- a/persona-studio/brain/pattern-library.json +++ b/persona-studio/brain/pattern-library.json @@ -1,8 +1,8 @@ { "schema_version": "1.0", "description": "系统模式库 · 自动识别 · 每完成一个项目+每日聚合更新", - "last_updated": "2026-03-13T05:43:36.767Z", - "total_patterns": 1, + "last_updated": "2026-03-13T05:55:39.412Z", + "total_patterns": 2, "patterns": [ { "name": "通用项目", @@ -15,6 +15,18 @@ "success_rate": 100, "first_seen": "2026-03-13T05:43:36.767Z", "last_seen": "2026-03-13T05:43:36.767Z" + }, + { + "name": "个人博客", + "frequency": 1, + "common_features": [], + "common_tech_stack": [ + "HTML/CSS/JS" + ], + "avg_build_time": 1, + "success_rate": 100, + "first_seen": "2026-03-13T05:55:39.412Z", + "last_seen": "2026-03-13T05:55:39.412Z" } ] } \ No newline at end of file diff --git a/persona-studio/frontend/chat.js b/persona-studio/frontend/chat.js index 44bbb726..279c6135 100644 --- a/persona-studio/frontend/chat.js +++ b/persona-studio/frontend/chat.js @@ -640,28 +640,39 @@ async function confirmBuild() { if (contact) sessionStorage.setItem('ps_build_contact', contact); closeEmailModal(); - appendMessage('system', '🚀 开发任务已提交,完成后会发送到 ' + email); + appendMessage('system', '🌀 铸渊代理已启动,完成后会发送到 ' + email); // 进入分屏模式 enterDevMode(); + // 先连接 WebSocket(确保在 build 开始前建立连接,避免丢失进度消息) + connectPreviewWebSocket(); + try { - await fetch(API_BASE + '/api/ps/build/start', { + var buildRes = await fetch(API_BASE + '/api/ps/build/start', { method: 'POST', headers: authHeaders({ 'Content-Type': 'application/json' }), body: JSON.stringify({ dev_id: DEV_ID, email: email, contact: contact, - conversation: conversationHistory + conversation: conversationHistory, + api_base: USER_API_BASE, + api_key: USER_API_KEY, + model: SELECTED_MODEL }) }); - } catch (_err) { - appendMessage('system', '任务提交失败,请稍后再试'); - } - // 连接 WebSocket 获取进度更新 - connectPreviewWebSocket(); + if (!buildRes.ok) { + var errData = {}; + try { errData = await buildRes.json(); } catch (_e) { /* ignore */ } + appendMessage('system', '⚠️ 铸渊代理启动失败: ' + (errData.message || 'HTTP ' + buildRes.status)); + updatePreviewStatus('error', '启动失败'); + } + } catch (_err) { + appendMessage('system', '⚠️ 任务提交失败,请检查网络连接后再试'); + updatePreviewStatus('error', '网络错误'); + } } /* ---- Dev Mode: Split Screen ---- */ diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/README.md b/persona-studio/workspace/EXP-000/project-1773380616766/README.md deleted file mode 100644 index d6977a59..00000000 --- a/persona-studio/workspace/EXP-000/project-1773380616766/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# project-1773380616766 - -## 需求描述 -Make a hello world page - -> 模板项目(AI 模型尚未配置,请管理员设置 MODEL_API_KEY) - -生成时间:2026-03-13T05:43:36.766Z \ No newline at end of file diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/index.html b/persona-studio/workspace/EXP-000/project-1773380616766/index.html deleted file mode 100644 index 6fcb4630..00000000 --- a/persona-studio/workspace/EXP-000/project-1773380616766/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - project-1773380616766 - - - -

🌊 project-1773380616766

-

由光湖 Persona Studio 生成

- - - \ No newline at end of file diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/main.js b/persona-studio/workspace/EXP-000/project-1773380616766/main.js deleted file mode 100644 index da7954e6..00000000 --- a/persona-studio/workspace/EXP-000/project-1773380616766/main.js +++ /dev/null @@ -1 +0,0 @@ -console.log("Project initialized by Persona Studio"); diff --git a/persona-studio/workspace/EXP-000/project-1773380616766/style.css b/persona-studio/workspace/EXP-000/project-1773380616766/style.css deleted file mode 100644 index 2fd101aa..00000000 --- a/persona-studio/workspace/EXP-000/project-1773380616766/style.css +++ /dev/null @@ -1 +0,0 @@ -body { font-family: sans-serif; padding: 2rem; } From 0e977af2a0e18e6b07721f5b08fb0301109bfa55 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:56:45 +0000 Subject: [PATCH 28/46] Initial plan From f3f4ead417bc09ba7e9e8928f95a7439e2757c61 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 05:59:53 +0000 Subject: [PATCH 29/46] fix: address code review feedback - path traversal protection, error msg fallback, named constant Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- persona-studio/backend/brain/agent-workflow.js | 9 +++++++-- persona-studio/frontend/chat.js | 9 ++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/persona-studio/backend/brain/agent-workflow.js b/persona-studio/backend/brain/agent-workflow.js index 01766e25..aeacc4b4 100644 --- a/persona-studio/backend/brain/agent-workflow.js +++ b/persona-studio/backend/brain/agent-workflow.js @@ -24,6 +24,10 @@ const path = require('path'); const https = require('https'); const http = require('http'); +// ── 常量 ── +// 传入 LLM 的对话文本最大字符数(防止超出模型上下文窗口) +const MAX_CONVERSATION_CHARS = 4000; + // ── 核心大脑模块 ── const memoryManager = require('./memory-manager'); const personaEngine = require('./persona-engine'); @@ -328,7 +332,7 @@ async function analyzeIntentWithLLM(brainContext, conversation, apiBase, apiKey, model: model, messages: [ { role: 'system', content: systemParts.join('\n') }, - { role: 'user', content: '以下是和开发者的完整对话,请分析意图并生成开发计划:\n\n' + conversationText.substring(0, 4000) } + { role: 'user', content: '以下是和开发者的完整对话,请分析意图并生成开发计划:\n\n' + conversationText.substring(0, MAX_CONVERSATION_CHARS) } ], maxTokens: 2000, temperature: 0.2, @@ -442,7 +446,8 @@ async function agentExecute(developmentPlan, devId, apiBase, apiKey, model, broa var entries = Object.entries(files); for (var j = 0; j < entries.length; j++) { var safeName = path.basename(entries[j][0]); - if (!safeName || safeName.startsWith('.')) continue; + // 安全检查:防止路径遍历和隐藏文件 + if (!safeName || safeName.startsWith('.') || /[/\\]/.test(entries[j][0])) continue; fs.writeFileSync(path.join(projectDir, safeName), entries[j][1], 'utf-8'); fileList.push(safeName); } diff --git a/persona-studio/frontend/chat.js b/persona-studio/frontend/chat.js index 279c6135..2d263e98 100644 --- a/persona-studio/frontend/chat.js +++ b/persona-studio/frontend/chat.js @@ -664,9 +664,12 @@ async function confirmBuild() { }); if (!buildRes.ok) { - var errData = {}; - try { errData = await buildRes.json(); } catch (_e) { /* ignore */ } - appendMessage('system', '⚠️ 铸渊代理启动失败: ' + (errData.message || 'HTTP ' + buildRes.status)); + var errMsg = 'HTTP ' + buildRes.status + ' ' + buildRes.statusText; + try { + var errData = await buildRes.json(); + if (errData.message) errMsg = errData.message; + } catch (_e) { /* use status text fallback */ } + appendMessage('system', '⚠️ 铸渊代理启动失败: ' + errMsg); updatePreviewStatus('error', '启动失败'); } } catch (_err) { From 8b7c2ea8a2ca90a826c01c67bf327d50658dbd12 Mon Sep 17 00:00:00 2001 From: bingshuo-neural-system Date: Fri, 13 Mar 2026 06:03:28 +0000 Subject: [PATCH 30/46] =?UTF-8?q?=F0=9F=A7=A0=20=E5=86=B0=E6=9C=94?= =?UTF-8?q?=E4=B8=BB=E6=8E=A7=E7=A5=9E=E7=BB=8F=E7=B3=BB=E7=BB=9F=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=BC=96=E8=AF=91=202026-03-13T06:03:28Z?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/bingshuo-issues-index.json | 2 +- .github/brain/bingshuo-master-brain.md | 4 ++-- .github/brain/bingshuo-system-health.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/brain/bingshuo-issues-index.json b/.github/brain/bingshuo-issues-index.json index 9c5d43de..6d37d9af 100644 --- a/.github/brain/bingshuo-issues-index.json +++ b/.github/brain/bingshuo-issues-index.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控问题索引库 — 记录已知问题、根因与排查路由", - "updated_at": "2026-03-13T05:31:10.476Z", + "updated_at": "2026-03-13T06:03:28.751Z", "issues": [ { "id": "BS-001", diff --git a/.github/brain/bingshuo-master-brain.md b/.github/brain/bingshuo-master-brain.md index 7bc4b44c..80f1b9bc 100644 --- a/.github/brain/bingshuo-master-brain.md +++ b/.github/brain/bingshuo-master-brain.md @@ -1,7 +1,7 @@ # 冰朔主控神经系统 · 核心主控大脑 v1.0 > 本文件为冰朔主控神经系统的总控脑文件。 -> 最后编译时间:2026-03-13T05:31:10.476Z +> 最后编译时间:2026-03-13T06:03:28.752Z --- @@ -85,7 +85,7 @@ > 本区块由 master-brain-compiler 自动编译。 -- **编译时间**:2026-03-13T05:31:10.476Z +- **编译时间**:2026-03-13T06:03:28.752Z - **脑文件规则版本**:v3.0 - **脑文件完整性**:✅ 完整 diff --git a/.github/brain/bingshuo-system-health.json b/.github/brain/bingshuo-system-health.json index 0c40d767..cb8e4669 100644 --- a/.github/brain/bingshuo-system-health.json +++ b/.github/brain/bingshuo-system-health.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控系统健康状态", - "updated_at": "2026-03-13T05:31:10.475Z", + "updated_at": "2026-03-13T06:03:28.751Z", "health": { "brain_consistency": { "status": "yellow", From 9eb27191ff9a194199b465a706813a8aca930725 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:03:39 +0000 Subject: [PATCH 31/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 16789259..478b5095 100644 --- a/README.md +++ b/README.md @@ -92,14 +92,10 @@ | 时间 | 检查项 | 状态 | |------|--------|------| -| 03-13 13:32 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | -| 03-13 13:31 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 13:31 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | -| 03-13 13:31 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | -| 03-13 13:04 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | -| 03-13 13:03 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | WENZHUOXI | -| 03-13 13:02 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | -| 03-13 13:02 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | +| 03-13 14:03 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | +| 03-13 13:56 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot | +| 03-13 13:56 | 🔧 系统更新: `.github/` | 铸渊 (Copilot) | +| 03-13 13:55 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | @@ -107,6 +103,10 @@ | 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-10 08:00 | 🧠 核心大脑升级 v3.0 · 壳-核分离架构 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context) · BRAIN域4接口上线 · 覆盖率 7/21 (33.3%) | 铸渊(冰朔指令) | +| 03-10 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 3 个问题 · 自动修复 0 项 | 铸渊PSP巡检 | +| 03-10 08:00 | 🔵 CI 构建 失败 | GitHub Actions | +| 03-09 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-09 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | ### 🤖 铸渊自动提醒 @@ -128,9 +128,9 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| -| 03-13 13:31 | 冰朔 | `—/` | ✅ 上传成功 | -| 03-13 13:30 | Copilot | `—/` | ✅ 上传成功 | -| 03-13 13:02 | WENZHUOXI | `—/` | ✅ 上传成功 | +| 03-13 14:03 | 冰朔 | `—/` | ✅ 上传成功 | +| 03-13 14:03 | Copilot | `—/` | ✅ 上传成功 | +| 03-13 13:56 | Copilot | `—/` | 🔵 已更新 | ### 🤖 铸渊自动提醒 · 合作者 From 6793130f29714c94f27c667a9be9fa65c8968671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 06:03:44 +0000 Subject: [PATCH 32/46] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-13T06:03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 2 +- .github/brain/repo-snapshot.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index bf5b2a27..8ec2133c 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,7 +1,7 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-13T05:31:21.799Z", + "generated_at": "2026-03-13T06:03:44.081Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index fe7e02c1..4fd16315 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-13 13:31 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-13 14:03 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -13,7 +13,7 @@ | 脚本 | 33 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 7/21 (33%) | -| 快照生成时间 | 2026-03-13 13:31 CST | +| 快照生成时间 | 2026-03-13 14:03 CST | --- From d87177d8f471fe475015640b11510fd18ed5db13 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:05:18 +0000 Subject: [PATCH 33/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 478b5095..51988395 100644 --- a/README.md +++ b/README.md @@ -92,10 +92,11 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 14:04 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | +| 03-13 14:03 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | +| 03-13 14:03 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | | 03-13 14:03 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | | 03-13 13:56 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot | -| 03-13 13:56 | 🔧 系统更新: `.github/` | 铸渊 (Copilot) | -| 03-13 13:55 | ✅ 铸渊 · Notion 工单轮询 · 成功 | 冰朔 | | 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | @@ -106,7 +107,6 @@ | 03-10 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 3 个问题 · 自动修复 0 项 | 铸渊PSP巡检 | | 03-10 08:00 | 🔵 CI 构建 失败 | GitHub Actions | | 03-09 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | -| 03-09 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | ### 🤖 铸渊自动提醒 From bce083dc665f4c72a272a7aa7711c2ff4fd07e4a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:05:53 +0000 Subject: [PATCH 34/46] =?UTF-8?q?feat:=20=E9=93=B8=E6=B8=8A=20SYSLOG=20?= =?UTF-8?q?=E5=85=A8=E9=97=AD=E7=8E=AF=E5=B7=A5=E4=BD=9C=E6=B5=81=20=C2=B7?= =?UTF-8?q?=20=E6=A8=A1=E5=9D=97=E9=AA=8C=E8=AF=81=20+=20=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E5=A4=A7=E8=84=91=E5=94=A4=E9=86=92=20+=20Notion=20?= =?UTF-8?q?=E5=9B=9E=E4=BC=A0=E7=AE=A1=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增: - scripts/verify-modules.js: 模块上传验证脚本 - .github/workflows/notion-callback-pipeline.yml: Notion→GitHub 回传核验管道 增强: - syslog-issue-pipeline.yml: 新增模块验证步骤 + 核心大脑注入验证结果 - syslog-auto-pipeline.yml: 同步增强 - wake-persona.js: 支持 MODULE_VERIFY_RESULT + NOTION_CALLBACK_RESULT 注入 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .../workflows/notion-callback-pipeline.yml | 247 ++++++++++++++ .github/workflows/syslog-auto-pipeline.yml | 63 +++- .github/workflows/syslog-issue-pipeline.yml | 63 +++- scripts/verify-modules.js | 303 ++++++++++++++++++ scripts/wake-persona.js | 45 ++- 5 files changed, 700 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/notion-callback-pipeline.yml create mode 100644 scripts/verify-modules.js diff --git a/.github/workflows/notion-callback-pipeline.yml b/.github/workflows/notion-callback-pipeline.yml new file mode 100644 index 00000000..6be491f6 --- /dev/null +++ b/.github/workflows/notion-callback-pipeline.yml @@ -0,0 +1,247 @@ +name: Notion Callback Pipeline +# 📥 Notion → GitHub 回传闭环管道 +# +# 当 Notion 侧核心大脑人格体处理完 SYSLOG 工单后, +# 通过 repository_dispatch 回传处理结果到 GitHub。 +# 铸渊 Agent 接收回传,重新唤醒核心大脑认知进行二次核验, +# 确认新广播生成无误后,自动发送邮件通知开发者。 +# +# 触发方式: +# Notion 侧 Agent 调用 GitHub API 发送 repository_dispatch 事件 +# event_type: notion-syslog-callback +# client_payload: { +# broadcast_id: "BC-XXX-XXX-XX", +# dev_email: "developer@email.com", +# notion_result: "Notion 侧处理结果文本", +# ticket_id: "Notion 工单 ID", +# status: "approved" | "needs_revision" +# } +# +# 闭环流程: +# ① Notion 侧处理完成 → repository_dispatch 回传 +# ② 铸渊 Agent 接收并解析回传数据 +# ③ 重新唤醒铸渊核心大脑认知(二次核验) +# ④ 核心大脑核对广播生成无误 +# ⑤ 铸渊 Agent 发送邮件通知开发者 +# ⑥ 闭环结束 +# +# 依赖 Secrets: +# LLM_API_KEY 第三方 LLM 平台密钥 +# LLM_BASE_URL 第三方 LLM 平台 API 地址 +# NOTION_API_TOKEN Notion API token +# CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID +# PORTRAIT_DB_ID 开发者动态画像库数据库 ID +# FINGERPRINT_DB_ID 模块指纹注册表数据库 ID +# SMTP_USER QQ 邮箱地址 +# SMTP_PASS QQ 邮箱 SMTP 授权码 + +on: + repository_dispatch: + types: [notion-syslog-callback] + +jobs: + verify-and-notify: + name: 📥 Notion 回传 · 二次核验 · 邮件通知 + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: 📥 Parse Notion callback + id: callback + uses: actions/github-script@v7 + with: + script: | + const payload = context.payload.client_payload || {}; + + const broadcastId = payload.broadcast_id || ''; + const devEmail = payload.dev_email || ''; + const notionResult = payload.notion_result || ''; + const ticketId = payload.ticket_id || ''; + const status = payload.status || 'unknown'; + + if (!broadcastId) { + core.setFailed('❌ 缺少 broadcast_id'); + return; + } + + core.setOutput('broadcast_id', broadcastId); + core.setOutput('dev_email', devEmail); + core.setOutput('notion_result', notionResult); + core.setOutput('ticket_id', ticketId); + core.setOutput('status', status); + + console.log(`📥 Notion 回传: 广播=${broadcastId}, 状态=${status}, 工单=${ticketId}`); + + - name: 🔍 铸渊 Agent · 模块二次验证 + id: verify + env: + SYSLOG_CONTENT: ${{ steps.callback.outputs.notion_result }} + BROADCAST_ID: ${{ steps.callback.outputs.broadcast_id }} + AUTHOR: notion-callback + run: node scripts/verify-modules.js + + - name: 🧠 二次核验 · 唤醒铸渊核心大脑 + id: persona + env: + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} + BROADCAST_ID: ${{ steps.callback.outputs.broadcast_id }} + SUBMIT_TYPE: syslog + SUBMIT_CONTENT: ${{ steps.callback.outputs.notion_result }} + AUTHOR: notion-callback + MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }} + NOTION_CALLBACK_RESULT: ${{ steps.callback.outputs.notion_result }} + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }} + PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }} + FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} + run: node scripts/wake-persona.js + + - name: 📧 发送最终确认邮件 + env: + SMTP_USER: ${{ secrets.SMTP_USER }} + SMTP_PASS: ${{ secrets.SMTP_PASS }} + EMAIL_TO: ${{ steps.callback.outputs.dev_email }} + BROADCAST_ID: ${{ steps.callback.outputs.broadcast_id }} + NOTION_STATUS: ${{ steps.callback.outputs.status }} + PERSONA_RESULT: ${{ steps.persona.outputs.result }} + run: | + node -e " + const nodemailer = require('nodemailer'); + + const user = process.env.SMTP_USER || ''; + const pass = process.env.SMTP_PASS || ''; + const to = process.env.EMAIL_TO || ''; + const broadcastId = process.env.BROADCAST_ID || ''; + const notionStatus = process.env.NOTION_STATUS || 'unknown'; + const result = process.env.PERSONA_RESULT || '(处理中)'; + + if (!user || !pass) { + console.log('⚠️ SMTP not configured, skipping email'); + process.exit(0); + } + if (!to) { + console.log('⚠️ No recipient email, skipping'); + process.exit(0); + } + + const isApproved = notionStatus === 'approved'; + const subjectText = isApproved + ? '[光湖系统] ' + broadcastId + ' · ✅ 新广播已生成(已核验)' + : '[光湖系统] ' + broadcastId + ' · ⚠️ 广播需修订'; + + const statusBadge = isApproved + ? '✅ 已核验通过' + : '⚠️ 需修订'; + + const resultHtml = result + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/\n/g, '
'); + + const html = [ + '
', + '
', + '

🌊 光湖系统 · Notion 回传核验通知

', + '

HoloLake · 铸渊核心大脑二次核验完成

', + '
', + '
', + '

📡 ' + broadcastId + '

', + '

' + statusBadge + '

', + '
' + resultHtml + '
', + '
', + '
', + '↩ 回到仓库继续开发', + '

🌀 铸渊 · 代码守护人格体 · Notion↔GitHub 闭环确认

', + '
', + '
' + ].join('\n'); + + const transporter = nodemailer.createTransport({ + host: 'smtp.qq.com', + port: 465, + secure: true, + auth: { user, pass } + }); + + transporter.sendMail({ + from: '\"光湖系统\" <' + user + '>', + to: to, + subject: subjectText, + html: html + }).then((info) => { + console.log('✅ 最终确认邮件已发送: ' + info.messageId); + }).catch((err) => { + console.log('⚠️ 邮件发送失败: ' + err.message); + }); + " + + - name: 📝 更新大脑记忆 + run: | + node -e " + const fs = require('fs'); + const path = require('path'); + + const memoryPath = path.join('.github', 'brain', 'memory.json'); + let memory = {}; + try { + memory = JSON.parse(fs.readFileSync(memoryPath, 'utf8')); + } catch (_) { + memory = { events: [] }; + } + if (!memory.events) memory.events = []; + + const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; + const status = process.env.NOTION_STATUS || 'unknown'; + const now = new Date().toISOString(); + + // 检查是否已存在相同事件 + const exists = memory.events.some(function(e) { + return e.type === 'notion_callback' && + e.description && e.description.includes(broadcastId) && + e.date === now.slice(0, 10); + }); + + if (!exists) { + memory.events.unshift({ + date: now.slice(0, 10), + type: 'notion_callback', + description: 'Notion 回传核验 · ' + broadcastId + ' · 状态: ' + status, + by: '铸渊Agent·Notion回传管道' + }); + + // 保留最近 20 条事件 + if (memory.events.length > 20) { + memory.events = memory.events.slice(0, 20); + } + + fs.writeFileSync(memoryPath, JSON.stringify(memory, null, 2) + '\n'); + console.log('✅ 大脑记忆已更新'); + } else { + console.log('ℹ️ 事件已存在,跳过'); + } + " + env: + BROADCAST_ID: ${{ steps.callback.outputs.broadcast_id }} + NOTION_STATUS: ${{ steps.callback.outputs.status }} + + - name: 📤 Commit memory update + run: | + git config user.name "zhuyuan-agent[bot]" + git config user.email "zhuyuan-agent[bot]@users.noreply.github.com" + git add .github/brain/memory.json + git diff --cached --quiet || git commit -m "🧠 Notion回传核验 · ${{ steps.callback.outputs.broadcast_id }}" + git push || echo "⚠️ Push skipped (no changes or conflict)" diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index c2fa3898..1344c3e2 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -2,8 +2,18 @@ name: SYSLOG Auto Pipeline # 📡 SYSLOG 自助提交系统 · 全自动闭环 # # 开发者在 GitHub Discussion 提交 SYSLOG 或提问 -# → Actions 自动解析 → 调用 LLM API 唤醒人格体 -# → 写入 Notion 工单 → 发邮件给开发者 → Discussion 回复 +# → Actions 自动解析 → 模块上传验证 → 调用 LLM API 唤醒人格体 +# → 模块闭环测试 → 写入 Notion 工单 → 发邮件给开发者 → Discussion 回复 +# +# 闭环流程: +# ① 开发者提交 SYSLOG → Discussion 触发 +# ② 铸渊 Agent 解析提交内容 +# ③ 铸渊 Agent 检测模块是否上传到仓库 +# ④ 唤醒铸渊核心大脑认知(注入模块验证结果) +# ⑤ 核心大脑处理 SYSLOG + 生成广播 +# ⑥ 铸渊 Agent 推送 Notion 工单(触发 Notion 侧处理) +# ⑦ 邮件通知开发者 +# ⑧ Discussion 回复闭环 # # 依赖 Secrets: # LLM_API_KEY 第三方 LLM 平台密钥(必须) @@ -96,6 +106,14 @@ jobs: console.log(`📡 解析完成: 广播=${broadcastId}, 类型=${type}, 邮箱=${email}`); + - name: 🔍 铸渊 Agent · 模块上传验证 + id: verify + env: + SYSLOG_CONTENT: ${{ steps.parse.outputs.content }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + AUTHOR: ${{ steps.parse.outputs.author }} + run: node scripts/verify-modules.js + - name: 🧠 Auto-detect and wake up persona id: persona env: @@ -105,6 +123,7 @@ jobs: SUBMIT_TYPE: ${{ steps.parse.outputs.type }} SUBMIT_CONTENT: ${{ steps.parse.outputs.content }} AUTHOR: ${{ steps.parse.outputs.author }} + MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }} NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }} PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }} @@ -119,6 +138,9 @@ jobs: BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} SUBMIT_TYPE: ${{ steps.parse.outputs.type }} PERSONA_RESULT: ${{ steps.persona.outputs.result }} + MODULE_VERIFY: ${{ steps.verify.outputs.verify_result }} + MODULES_UPLOADED: ${{ steps.verify.outputs.modules_uploaded }} + AUTHOR: ${{ steps.parse.outputs.author }} run: | node -e " const https = require('https'); @@ -128,6 +150,9 @@ jobs: const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; const type = process.env.SUBMIT_TYPE || 'syslog'; const result = process.env.PERSONA_RESULT || '(no result)'; + const modulesUploaded = process.env.MODULES_UPLOADED || 'false'; + const moduleVerify = process.env.MODULE_VERIFY || '{}'; + const author = process.env.AUTHOR || 'unknown'; if (!token || !dbId) { console.log('⚠️ Notion credentials not configured, skipping ticket creation'); @@ -135,22 +160,37 @@ jobs: } const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答'; - const title = '[自动] ' + broadcastId + ' · ' + typeLabel; + const verifyStatus = modulesUploaded === 'true' ? '模块已验证✅' : '模块待验证⚠️'; + const title = '[自动] ' + broadcastId + ' · ' + typeLabel + ' · ' + verifyStatus; + + // 构建工单内容:包含人格体处理结果 + 模块验证数据 + const ticketContent = [ + '## 铸渊核心大脑处理结果', + '', + result.slice(0, 1500), + '', + '## 模块上传验证', + '', + '模块全部上传: ' + (modulesUploaded === 'true' ? '✅ 是' : '❌ 否'), + '提交者: ' + author, + '', + '验证详情: ' + moduleVerify.slice(0, 400), + ].join('\\n'); const body = JSON.stringify({ parent: { database_id: dbId }, properties: { '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, '操作类型': { select: { name: '其他' } }, - '提交者': { rich_text: [{ type: 'text', text: { content: '自动管道' } }] }, - '状态': { select: { name: '已完成' } }, + '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, + '状态': { select: { name: '待处理' } }, '优先级': { select: { name: 'P1' } } }, children: [{ object: 'block', type: 'paragraph', paragraph: { - rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }] + rich_text: [{ type: 'text', text: { content: ticketContent.slice(0, 2000) } }] } }] }); @@ -266,11 +306,16 @@ jobs: const type = '${{ steps.parse.outputs.type }}'; const broadcastId = '${{ steps.parse.outputs.broadcast_id }}'; const email = '${{ steps.parse.outputs.email }}'; + const modulesUploaded = '${{ steps.verify.outputs.modules_uploaded }}' === 'true'; + const moduleCount = '${{ steps.verify.outputs.module_count }}' || '0'; const typeLabel = type === 'syslog' ? 'SYSLOG 闭环处理' : '问题解答'; const maskedEmail = email.length > 4 ? email.replace(/(.{2})(.*)(@.*)/, '$1***$3') : '***'; + const moduleStatus = moduleCount === '0' + ? 'ℹ️ 未检测到模块引用' + : (modulesUploaded ? '✅ 全部已上传' : '⚠️ 部分模块未上传'); const body = [ '✅ **已处理** · ' + typeLabel, @@ -278,13 +323,15 @@ jobs: '| 项目 | 内容 |', '|------|------|', '| 📡 广播编号 | `' + broadcastId + '` |', + '| 🔍 模块验证 | ' + moduleStatus + ' |', '| 📧 结果发送至 | `' + maskedEmail + '` |', '| 🤖 处理人格体 | 铸渊 |', '| ⏰ 处理时间 | ' + new Date().toISOString() + ' |', '', - '> 结果已发送到你的邮箱,请查收。', + '> 铸渊核心大脑已完成 SYSLOG 验收 + 模块检测 + 广播生成。', + '> 结果已发送到你的邮箱,Notion 侧工单已创建。', '>', - '> 如未收到,请检查垃圾箱或重新提交。' + '> 如未收到邮件,请检查垃圾箱或重新提交。' ].join('\n'); // Use GraphQL to add discussion comment diff --git a/.github/workflows/syslog-issue-pipeline.yml b/.github/workflows/syslog-issue-pipeline.yml index 5a5d81a5..de09bac0 100644 --- a/.github/workflows/syslog-issue-pipeline.yml +++ b/.github/workflows/syslog-issue-pipeline.yml @@ -2,8 +2,18 @@ name: SYSLOG Issue Pipeline # 📡 SYSLOG 自助提交系统 · Issue 版全自动闭环 # # 开发者在 GitHub Issue 提交 SYSLOG 或提问(使用 syslog-submit 模板) -# → Actions 自动解析 → 调用 LLM API 唤醒人格体 -# → 写入 Notion 工单 → 发邮件给开发者 → Issue 回复 +# → Actions 自动解析 → 模块上传验证 → 调用 LLM API 唤醒人格体 +# → 模块闭环测试 → 写入 Notion 工单 → 发邮件给开发者 → Issue 回复 +# +# 闭环流程: +# ① 开发者提交 SYSLOG → Issue 触发 +# ② 铸渊 Agent 解析提交内容 +# ③ 铸渊 Agent 检测模块是否上传到仓库 +# ④ 唤醒铸渊核心大脑认知(注入模块验证结果) +# ⑤ 核心大脑处理 SYSLOG + 生成广播 +# ⑥ 铸渊 Agent 推送 Notion 工单(触发 Notion 侧处理) +# ⑦ 邮件通知开发者 +# ⑧ Issue 回复闭环 # # 依赖 Secrets: # LLM_API_KEY 第三方 LLM 平台密钥(必须) @@ -96,6 +106,14 @@ jobs: console.log(`📡 解析完成: 广播=${broadcastId}, 类型=${type}, 邮箱=${email}`); + - name: 🔍 铸渊 Agent · 模块上传验证 + id: verify + env: + SYSLOG_CONTENT: ${{ steps.parse.outputs.content }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + AUTHOR: ${{ steps.parse.outputs.author }} + run: node scripts/verify-modules.js + - name: 🧠 Auto-detect and wake up persona id: persona env: @@ -105,6 +123,7 @@ jobs: SUBMIT_TYPE: ${{ steps.parse.outputs.type }} SUBMIT_CONTENT: ${{ steps.parse.outputs.content }} AUTHOR: ${{ steps.parse.outputs.author }} + MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }} NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }} PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }} @@ -119,6 +138,9 @@ jobs: BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} SUBMIT_TYPE: ${{ steps.parse.outputs.type }} PERSONA_RESULT: ${{ steps.persona.outputs.result }} + MODULE_VERIFY: ${{ steps.verify.outputs.verify_result }} + MODULES_UPLOADED: ${{ steps.verify.outputs.modules_uploaded }} + AUTHOR: ${{ steps.parse.outputs.author }} run: | node -e " const https = require('https'); @@ -128,6 +150,9 @@ jobs: const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; const type = process.env.SUBMIT_TYPE || 'syslog'; const result = process.env.PERSONA_RESULT || '(no result)'; + const modulesUploaded = process.env.MODULES_UPLOADED || 'false'; + const moduleVerify = process.env.MODULE_VERIFY || '{}'; + const author = process.env.AUTHOR || 'unknown'; if (!token || !dbId) { console.log('⚠️ Notion credentials not configured, skipping ticket creation'); @@ -135,22 +160,37 @@ jobs: } const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答'; - const title = '[自动] ' + broadcastId + ' · ' + typeLabel; + const verifyStatus = modulesUploaded === 'true' ? '模块已验证✅' : '模块待验证⚠️'; + const title = '[自动] ' + broadcastId + ' · ' + typeLabel + ' · ' + verifyStatus; + + // 构建工单内容:包含人格体处理结果 + 模块验证数据 + const ticketContent = [ + '## 铸渊核心大脑处理结果', + '', + result.slice(0, 1500), + '', + '## 模块上传验证', + '', + '模块全部上传: ' + (modulesUploaded === 'true' ? '✅ 是' : '❌ 否'), + '提交者: ' + author, + '', + '验证详情: ' + moduleVerify.slice(0, 400), + ].join('\\n'); const body = JSON.stringify({ parent: { database_id: dbId }, properties: { '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, '操作类型': { select: { name: '其他' } }, - '提交者': { rich_text: [{ type: 'text', text: { content: '自动管道' } }] }, - '状态': { select: { name: '已完成' } }, + '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, + '状态': { select: { name: '待处理' } }, '优先级': { select: { name: 'P1' } } }, children: [{ object: 'block', type: 'paragraph', paragraph: { - rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }] + rich_text: [{ type: 'text', text: { content: ticketContent.slice(0, 2000) } }] } }] }); @@ -266,11 +306,16 @@ jobs: const type = '${{ steps.parse.outputs.type }}'; const broadcastId = '${{ steps.parse.outputs.broadcast_id }}'; const email = '${{ steps.parse.outputs.email }}'; + const modulesUploaded = '${{ steps.verify.outputs.modules_uploaded }}' === 'true'; + const moduleCount = '${{ steps.verify.outputs.module_count }}' || '0'; const typeLabel = type === 'syslog' ? 'SYSLOG 闭环处理' : '问题解答'; const maskedEmail = email.length > 4 ? email.replace(/(.{2})(.*)(@.*)/, '$1***$3') : '***'; + const moduleStatus = moduleCount === '0' + ? 'ℹ️ 未检测到模块引用' + : (modulesUploaded ? '✅ 全部已上传' : '⚠️ 部分模块未上传'); const body = [ '✅ **已处理** · ' + typeLabel, @@ -278,13 +323,15 @@ jobs: '| 项目 | 内容 |', '|------|------|', '| 📡 广播编号 | `' + broadcastId + '` |', + '| 🔍 模块验证 | ' + moduleStatus + ' |', '| 📧 结果发送至 | `' + maskedEmail + '` |', '| 🤖 处理人格体 | 铸渊 |', '| ⏰ 处理时间 | ' + new Date().toISOString() + ' |', '', - '> 结果已发送到你的邮箱,请查收。', + '> 铸渊核心大脑已完成 SYSLOG 验收 + 模块检测 + 广播生成。', + '> 结果已发送到你的邮箱,Notion 侧工单已创建。', '>', - '> 如未收到,请检查垃圾箱或重新提交。' + '> 如未收到邮件,请检查垃圾箱或重新提交。' ].join('\n'); await github.rest.issues.createComment({ diff --git a/scripts/verify-modules.js b/scripts/verify-modules.js new file mode 100644 index 00000000..807ec605 --- /dev/null +++ b/scripts/verify-modules.js @@ -0,0 +1,303 @@ +// scripts/verify-modules.js +// 铸渊 · 模块上传验证脚本 +// +// 功能: +// ① 从 SYSLOG 内容中提取模块编号(M01, M22, M-AUTH 等) +// ② 通过 routing-map.json 查找模块对应的目录 +// ③ 检测目录是否存在于仓库中 +// ④ 检测 dev-nodes 中开发者节点是否存在 +// ⑤ 输出验证结果(JSON 格式)到 GITHUB_OUTPUT +// +// 环境变量: +// SYSLOG_CONTENT SYSLOG 全文内容 +// BROADCAST_ID 广播编号(如 BC-M22-009-AW) +// AUTHOR 提交者 GitHub 用户名 + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const SYSLOG_CONTENT = process.env.SYSLOG_CONTENT || ''; +const BROADCAST_ID = process.env.BROADCAST_ID || ''; +const AUTHOR = process.env.AUTHOR || ''; + +const REPO_ROOT = path.resolve(__dirname, '..'); +const ROUTING_MAP_PATH = path.join(REPO_ROOT, 'routing-map.json'); +const DEV_STATUS_PATH = path.join(REPO_ROOT, '.github', 'persona-brain', 'dev-status.json'); + +// ══════════════════════════════════════════════════════════ +// 模块编号提取 +// ══════════════════════════════════════════════════════════ + +function extractModuleIds(content, broadcastId) { + var modules = new Set(); + + // 从广播编号提取模块编号(如 BC-M22-009-AW → M22) + var bcMatch = broadcastId.match(/BC-([A-Z][A-Z0-9]+(?:-[A-Z]+)?)-/i); + if (bcMatch) { + modules.add(bcMatch[1].toUpperCase()); + } + + // 从内容中匹配模块编号模式 + // 支持: M01, M03, M05, M22, M-AUTH, M-CHANNEL, M-DASHBOARD, M-STATUS, M-MEMORY, M-DINGTALK + var patterns = [ + /\b(M\d{2})\b/gi, + /\b(M-[A-Z]+)\b/gi, + /模块[::]\s*(M[A-Z0-9-]+)/gi, + /module[::]\s*(M[A-Z0-9-]+)/gi, + ]; + + patterns.forEach(function (re) { + var match; + while ((match = re.exec(content)) !== null) { + modules.add(match[1].toUpperCase()); + } + }); + + return Array.from(modules); +} + +// ══════════════════════════════════════════════════════════ +// 开发者编号提取 +// ══════════════════════════════════════════════════════════ + +function extractDevId(content, broadcastId) { + // 从广播编号提取开发者后缀(如 BC-M22-009-AW → AW) + var suffixMatch = broadcastId.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); + var devSuffix = suffixMatch ? suffixMatch[1] : ''; + + // 从内容中提取 DEV-XXX + var devMatch = content.match(/\b(DEV-\d{3})\b/i); + if (devMatch) return devMatch[1].toUpperCase(); + + // 从 dev-status.json 通过后缀查找 + if (devSuffix) { + try { + var devStatus = JSON.parse(fs.readFileSync(DEV_STATUS_PATH, 'utf8')); + var team = devStatus.team || []; + for (var i = 0; i < team.length; i++) { + var name = team[i].name || ''; + // 简单匹配:用名字首字母缩写匹配后缀 + if (name && devSuffix.length >= 2) { + return team[i].dev_id; + } + } + } catch (_) { /* ignore */ } + } + + return ''; +} + +// ══════════════════════════════════════════════════════════ +// 模块目录验证 +// ══════════════════════════════════════════════════════════ + +function verifyModules(moduleIds) { + var routingMap = {}; + try { + routingMap = JSON.parse(fs.readFileSync(ROUTING_MAP_PATH, 'utf8')); + } catch (_) { + console.log('⚠️ routing-map.json 不存在或格式错误'); + } + + var modules = routingMap.modules || {}; + var results = []; + + moduleIds.forEach(function (modId) { + var entry = modules[modId]; + var result = { + module_id: modId, + registered: false, + dir_exists: false, + dir_path: '', + dev_id: '', + status: '', + files_found: 0, + }; + + if (entry) { + result.registered = true; + result.dir_path = entry.dir || ''; + result.dev_id = entry.dev || ''; + result.status = entry.status || ''; + + // 检查目录是否存在 + var dirFullPath = path.join(REPO_ROOT, entry.dir); + if (fs.existsSync(dirFullPath)) { + result.dir_exists = true; + // 统计文件数量(不含隐藏文件) + try { + var files = fs.readdirSync(dirFullPath).filter(function (f) { + return !f.startsWith('.'); + }); + result.files_found = files.length; + } catch (_) { /* ignore */ } + } + } else { + // 模块未在 routing-map 中注册,尝试直接查找 + var candidates = [ + modId.toLowerCase(), + 'm' + modId.replace(/^M/i, '').toLowerCase(), + 'dev-nodes/' + modId, + ]; + for (var i = 0; i < candidates.length; i++) { + var candidatePath = path.join(REPO_ROOT, candidates[i]); + if (fs.existsSync(candidatePath)) { + result.dir_exists = true; + result.dir_path = candidates[i]; + try { + var files = fs.readdirSync(candidatePath).filter(function (f) { + return !f.startsWith('.'); + }); + result.files_found = files.length; + } catch (_) { /* ignore */ } + break; + } + } + } + + results.push(result); + }); + + return results; +} + +// ══════════════════════════════════════════════════════════ +// 开发者节点验证 +// ══════════════════════════════════════════════════════════ + +function verifyDevNode(devId) { + if (!devId) return { exists: false, path: '', files: 0 }; + + var devNodePath = path.join(REPO_ROOT, 'dev-nodes', devId); + var result = { exists: false, path: 'dev-nodes/' + devId, files: 0 }; + + if (fs.existsSync(devNodePath)) { + result.exists = true; + try { + var files = fs.readdirSync(devNodePath).filter(function (f) { + return !f.startsWith('.'); + }); + result.files = files.length; + } catch (_) { /* ignore */ } + } + + return result; +} + +// ══════════════════════════════════════════════════════════ +// 主流程 +// ══════════════════════════════════════════════════════════ + +function main() { + console.log('═══════════════════════════════════════════'); + console.log('🔍 铸渊 · 模块上传验证'); + console.log('═══════════════════════════════════════════'); + console.log(' 广播编号: ' + BROADCAST_ID); + console.log(' 提交者: ' + AUTHOR); + console.log(' 内容长度: ' + SYSLOG_CONTENT.length + ' 字符'); + console.log(''); + + // ① 提取模块编号 + var moduleIds = extractModuleIds(SYSLOG_CONTENT, BROADCAST_ID); + console.log('📦 识别到模块: ' + (moduleIds.length > 0 ? moduleIds.join(', ') : '(无)')); + + // ② 提取开发者编号 + var devId = extractDevId(SYSLOG_CONTENT, BROADCAST_ID); + console.log('👤 开发者编号: ' + (devId || '(未识别)')); + + // ③ 验证模块目录 + var moduleResults = verifyModules(moduleIds); + + // ④ 验证开发者节点 + var devNodeResult = verifyDevNode(devId); + + // ⑤ 汇总结果 + var allModulesUploaded = moduleResults.length > 0 && moduleResults.every(function (r) { + return r.dir_exists; + }); + + var summary = { + broadcast_id: BROADCAST_ID, + author: AUTHOR, + dev_id: devId, + modules_detected: moduleIds, + module_count: moduleIds.length, + module_results: moduleResults, + dev_node: devNodeResult, + all_modules_uploaded: allModulesUploaded, + verification_passed: allModulesUploaded || moduleIds.length === 0, + timestamp: new Date().toISOString(), + }; + + // ⑥ 输出报告 + console.log(''); + console.log('═══════════════════════════════════════════'); + console.log('📋 验证报告'); + console.log('═══════════════════════════════════════════'); + + if (moduleResults.length === 0) { + console.log(' ℹ️ 未检测到模块引用,跳过模块验证'); + } else { + moduleResults.forEach(function (r) { + var icon = r.dir_exists ? '✅' : '❌'; + console.log(' ' + icon + ' ' + r.module_id + + ' → ' + (r.dir_path || '(未注册)') + + (r.dir_exists ? ' (' + r.files_found + ' 个文件)' : ' (目录不存在)')); + }); + } + + console.log(' ' + (devNodeResult.exists ? '✅' : '⚠️') + + ' 开发者节点: ' + devNodeResult.path + + (devNodeResult.exists ? ' (' + devNodeResult.files + ' 个文件)' : ' (不存在)')); + + console.log(''); + console.log(' 总结: ' + (summary.verification_passed ? '✅ 验证通过' : '❌ 模块未完整上传')); + + // ⑦ 写入 GITHUB_OUTPUT + var outputFile = process.env.GITHUB_OUTPUT; + if (outputFile) { + var delimiter = 'EOF_' + Date.now(); + var jsonStr = JSON.stringify(summary); + fs.appendFileSync(outputFile, 'verify_result<<' + delimiter + '\n' + jsonStr + '\n' + delimiter + '\n'); + fs.appendFileSync(outputFile, 'modules_uploaded=' + (allModulesUploaded ? 'true' : 'false') + '\n'); + fs.appendFileSync(outputFile, 'verification_passed=' + (summary.verification_passed ? 'true' : 'false') + '\n'); + fs.appendFileSync(outputFile, 'module_count=' + moduleIds.length + '\n'); + } + + // ⑧ 将汇总文本输出(供后续步骤作为上下文) + var reportLines = [ + '## 🔍 模块上传验证报告', + '', + '| 项目 | 结果 |', + '|------|------|', + '| 广播编号 | ' + BROADCAST_ID + ' |', + '| 开发者 | ' + (devId || AUTHOR) + ' |', + '| 检测模块数 | ' + moduleIds.length + ' |', + '| 全部上传 | ' + (allModulesUploaded ? '✅ 是' : '❌ 否') + ' |', + '| 验证结果 | ' + (summary.verification_passed ? '✅ 通过' : '❌ 未通过') + ' |', + ]; + + if (moduleResults.length > 0) { + reportLines.push(''); + reportLines.push('### 模块详情'); + reportLines.push('| 模块 | 目录 | 状态 | 文件数 |'); + reportLines.push('|------|------|------|--------|'); + moduleResults.forEach(function (r) { + reportLines.push('| ' + r.module_id + ' | ' + (r.dir_path || '-') + + ' | ' + (r.dir_exists ? '✅ 已上传' : '❌ 未找到') + + ' | ' + r.files_found + ' |'); + }); + } + + if (outputFile) { + var reportDelimiter = 'REPORT_EOF_' + Date.now(); + fs.appendFileSync(outputFile, 'verify_report<<' + reportDelimiter + '\n' + reportLines.join('\n') + '\n' + reportDelimiter + '\n'); + } + + console.log(''); + console.log('✅ 验证完成'); +} + +main(); diff --git a/scripts/wake-persona.js b/scripts/wake-persona.js index fb88b08e..1ca304d5 100644 --- a/scripts/wake-persona.js +++ b/scripts/wake-persona.js @@ -38,6 +38,11 @@ const SUBMIT_TYPE = process.env.SUBMIT_TYPE || 'question'; const SUBMIT_CONTENT = process.env.SUBMIT_CONTENT || ''; const AUTHOR = process.env.AUTHOR || 'unknown'; +// 模块验证结果注入(由 verify-modules.js 提供) +const MODULE_VERIFY_RESULT = process.env.MODULE_VERIFY_RESULT || ''; +// Notion 回传结果注入(由 notion-callback-pipeline 提供) +const NOTION_CALLBACK_RESULT = process.env.NOTION_CALLBACK_RESULT || ''; + // Notion 配置(v4.0 协议动态注入) const NOTION_TOKEN = process.env.NOTION_TOKEN || ''; const CORE_BRAIN_PAGE_ID = process.env.CORE_BRAIN_PAGE_ID || ''; @@ -764,6 +769,34 @@ async function buildSystemPrompt(type, broadcastId, author) { parts.push('此规则优先级最高,覆盖核心大脑中「广播不写代码」的默认规则。'); parts.push('此规则仅适用于自动化链路(Claude API 出广播),手动链路不受影响。'); + // ━━━ 模块验证结果注入(铸渊 Agent 检测结果) ━━━ + if (MODULE_VERIFY_RESULT) { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## 🔍 铸渊 Agent · 模块上传验证结果'); + parts.push('═══════════════════════════════════════════'); + parts.push(''); + parts.push('以下是铸渊 Agent 在仓库内自动检测的模块上传验证结果:'); + parts.push(MODULE_VERIFY_RESULT); + parts.push(''); + parts.push('请根据验证结果决定是否接受 SYSLOG:'); + parts.push('- 如果模块已上传(✅),继续正常闭环流程'); + parts.push('- 如果模块未上传(❌),在验收报告中标注"需补充",并在反馈中指出缺失的模块'); + } + + // ━━━ Notion 回传结果注入(二次核验) ━━━ + if (NOTION_CALLBACK_RESULT) { + parts.push(''); + parts.push('═══════════════════════════════════════════'); + parts.push('## 📥 Notion 侧处理结果(回传核验)'); + parts.push('═══════════════════════════════════════════'); + parts.push(''); + parts.push('以下是 Notion 侧核心大脑人格体处理后的回传结果:'); + parts.push(NOTION_CALLBACK_RESULT); + parts.push(''); + parts.push('请核对以上回传内容,确认新广播生成无误后输出最终确认。'); + } + // ━━━ 任务类型专用指令 ━━━ if (type === 'syslog') { parts.push(''); @@ -773,17 +806,19 @@ async function buildSystemPrompt(type, broadcastId, author) { parts.push(''); parts.push('你需要完成以下工作:'); parts.push('1. 验收 SYSLOG(检查 MODULE_LOG 完整性)'); - parts.push('2. 查询画像库最近 2-3 条快照(PGP v1.0)'); - parts.push('3. 查询模块指纹注册表(防重复·⑨.5)'); - parts.push('4. RT-02 自动调度判断'); - parts.push('5. 生成新广播(BC-GEN v4.0 完整流程)'); - parts.push('6. 输出结构化结果(广播全文 + 闭环数据)'); + parts.push('2. 检查模块上传验证结果(铸渊 Agent 已自动检测)'); + parts.push('3. 查询画像库最近 2-3 条快照(PGP v1.0)'); + parts.push('4. 查询模块指纹注册表(防重复·⑨.5)'); + parts.push('5. RT-02 自动调度判断'); + parts.push('6. 生成新广播(BC-GEN v4.0 完整流程)'); + parts.push('7. 输出结构化结果(广播全文 + 闭环数据)'); parts.push(''); parts.push('输出格式:'); parts.push('---'); parts.push('## 📡 SYSLOG 验收报告'); parts.push('### 广播编号:[编号]'); parts.push('### 验收结果:[通过/需补充]'); + parts.push('### 模块验证:[已上传/未上传,列出详情]'); parts.push('### 工作总结:[摘要]'); parts.push('### 画像评估:[PGP 五维度评分]'); parts.push('### 调度判断:[RT-02 下一步]'); From a6567ff2d20e251223e5540269230562c4070033 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:08:13 +0000 Subject: [PATCH 35/46] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=20-=20extractDevI?= =?UTF-8?q?d=20=E9=80=BB=E8=BE=91=20+=20=E4=BA=8B=E4=BB=B6=E5=8E=BB?= =?UTF-8?q?=E9=87=8D=20+=20=E5=B7=A5=E5=8D=95=E7=8A=B6=E6=80=81=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .../workflows/notion-callback-pipeline.yml | 45 +++++++++++-------- .github/workflows/syslog-auto-pipeline.yml | 6 ++- .github/workflows/syslog-issue-pipeline.yml | 6 ++- scripts/verify-modules.js | 27 +++++++---- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/.github/workflows/notion-callback-pipeline.yml b/.github/workflows/notion-callback-pipeline.yml index 6be491f6..a6fc2d39 100644 --- a/.github/workflows/notion-callback-pipeline.yml +++ b/.github/workflows/notion-callback-pipeline.yml @@ -208,31 +208,38 @@ jobs: const status = process.env.NOTION_STATUS || 'unknown'; const now = new Date().toISOString(); - // 检查是否已存在相同事件 - const exists = memory.events.some(function(e) { + // 检查是否已存在相同事件(按 broadcast_id 精确匹配 + 同类型 + 同日期) + const eventKey = 'Notion 回传核验 · ' + broadcastId; + const todayStr = now.slice(0, 10); + const existingIdx = memory.events.findIndex(function(e) { return e.type === 'notion_callback' && - e.description && e.description.includes(broadcastId) && - e.date === now.slice(0, 10); + e.broadcast_id === broadcastId && + e.date === todayStr; }); - if (!exists) { - memory.events.unshift({ - date: now.slice(0, 10), - type: 'notion_callback', - description: 'Notion 回传核验 · ' + broadcastId + ' · 状态: ' + status, - by: '铸渊Agent·Notion回传管道' - }); + const newEvent = { + date: todayStr, + type: 'notion_callback', + broadcast_id: broadcastId, + description: eventKey + ' · 状态: ' + status, + by: '铸渊Agent·Notion回传管道' + }; - // 保留最近 20 条事件 - if (memory.events.length > 20) { - memory.events = memory.events.slice(0, 20); - } - - fs.writeFileSync(memoryPath, JSON.stringify(memory, null, 2) + '\n'); - console.log('✅ 大脑记忆已更新'); + if (existingIdx >= 0) { + // 同一 broadcast_id 只保留最新的一条 + memory.events[existingIdx] = newEvent; + console.log('ℹ️ 已更新同日同广播事件'); } else { - console.log('ℹ️ 事件已存在,跳过'); + memory.events.unshift(newEvent); } + + // 保留最近 20 条事件 + if (memory.events.length > 20) { + memory.events = memory.events.slice(0, 20); + } + + fs.writeFileSync(memoryPath, JSON.stringify(memory, null, 2) + '\n'); + console.log('✅ 大脑记忆已更新'); " env: BROADCAST_ID: ${{ steps.callback.outputs.broadcast_id }} diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index 1344c3e2..02eb3e5e 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -177,13 +177,17 @@ jobs: '验证详情: ' + moduleVerify.slice(0, 400), ].join('\\n'); + // SYSLOG类型工单设为'待处理'(等待Notion侧核心大脑处理) + // 提问类型工单设为'已完成'(铸渊已生成解答) + const ticketStatus = type === 'syslog' ? '待处理' : '已完成'; + const body = JSON.stringify({ parent: { database_id: dbId }, properties: { '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, '操作类型': { select: { name: '其他' } }, '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, - '状态': { select: { name: '待处理' } }, + '状态': { select: { name: ticketStatus } }, '优先级': { select: { name: 'P1' } } }, children: [{ diff --git a/.github/workflows/syslog-issue-pipeline.yml b/.github/workflows/syslog-issue-pipeline.yml index de09bac0..4acbc3b0 100644 --- a/.github/workflows/syslog-issue-pipeline.yml +++ b/.github/workflows/syslog-issue-pipeline.yml @@ -177,13 +177,17 @@ jobs: '验证详情: ' + moduleVerify.slice(0, 400), ].join('\\n'); + // SYSLOG类型工单设为'待处理'(等待Notion侧核心大脑处理) + // 提问类型工单设为'已完成'(铸渊已生成解答) + const ticketStatus = type === 'syslog' ? '待处理' : '已完成'; + const body = JSON.stringify({ parent: { database_id: dbId }, properties: { '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, '操作类型': { select: { name: '其他' } }, '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, - '状态': { select: { name: '待处理' } }, + '状态': { select: { name: ticketStatus } }, '优先级': { select: { name: 'P1' } } }, children: [{ diff --git a/scripts/verify-modules.js b/scripts/verify-modules.js index 807ec605..2df4ddf5 100644 --- a/scripts/verify-modules.js +++ b/scripts/verify-modules.js @@ -63,23 +63,32 @@ function extractModuleIds(content, broadcastId) { // ══════════════════════════════════════════════════════════ function extractDevId(content, broadcastId) { - // 从广播编号提取开发者后缀(如 BC-M22-009-AW → AW) - var suffixMatch = broadcastId.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); - var devSuffix = suffixMatch ? suffixMatch[1] : ''; - - // 从内容中提取 DEV-XXX + // 从内容中直接提取 DEV-XXX(最优先) var devMatch = content.match(/\b(DEV-\d{3})\b/i); if (devMatch) return devMatch[1].toUpperCase(); - // 从 dev-status.json 通过后缀查找 + // 从广播编号提取开发者后缀(如 BC-M22-009-AW → AW) + var suffixMatch = broadcastId.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); + var devSuffix = suffixMatch ? suffixMatch[1].toUpperCase() : ''; + + // 从 dev-status.json 通过后缀匹配开发者 if (devSuffix) { try { var devStatus = JSON.parse(fs.readFileSync(DEV_STATUS_PATH, 'utf8')); var team = devStatus.team || []; + // 后缀缩写映射表(从 dev-status.json 中名字的拼音首字母) + var suffixMap = { + 'YY': 'DEV-001', 'FM': 'DEV-002', 'YF': 'DEV-003', + 'ZZ': 'DEV-004', 'XCM': 'DEV-005', 'HE': 'DEV-009', + 'JZ': 'DEV-010', 'CCNN': 'DEV-011', 'AW': 'DEV-012', + 'XX': 'DEV-013', 'SY': 'DEV-014', + }; + if (suffixMap[devSuffix]) return suffixMap[devSuffix]; + + // 兜底:尝试从 team 中匹配 waiting 字段里的广播编号 for (var i = 0; i < team.length; i++) { - var name = team[i].name || ''; - // 简单匹配:用名字首字母缩写匹配后缀 - if (name && devSuffix.length >= 2) { + var waiting = team[i].waiting || ''; + if (waiting.includes(broadcastId) || waiting.includes(devSuffix)) { return team[i].dev_id; } } From e0dbe71bdc422eea859f1ec173c22e4f20ea92f9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:33:17 +0000 Subject: [PATCH 36/46] =?UTF-8?q?feat:=20Phase=20B=20=E5=85=A8=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=97=AD=E7=8E=AF=E5=AF=B9=E6=8E=A5=20=C2=B7=20?= =?UTF-8?q?=E6=A0=87=E5=87=86=E5=8C=96=E5=B7=A5=E5=8D=95=20+=20=E4=BA=BA?= =?UTF-8?q?=E6=A0=BC=E4=BD=93=E8=B0=83=E7=94=A8=E7=AB=AF=E7=82=B9=20+=20?= =?UTF-8?q?=E5=BF=83=E8=B7=B3=E7=9B=91=E6=8E=A7=20+=20=E5=B9=BF=E6=92=AD?= =?UTF-8?q?=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase B1: 标准化工单创建 (create-standardized-ticket.js + receive-syslog.js更新) Phase B2: 人格体调用端点 (invoke-persona.js + persona-invoke.yml workflow_dispatch) Phase B3: 心跳监控 (notion-heartbeat.js + notion-heartbeat.yml 每5分钟) Phase B4: 广播推送 (push-broadcast-to-github.js + broadcasts/ 目录) 工作流更新: syslog-issue-pipeline.yml, syslog-auto-pipeline.yml, notion-callback-pipeline.yml Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .../workflows/notion-callback-pipeline.yml | 63 +++ .github/workflows/notion-heartbeat.yml | 44 +++ .github/workflows/persona-invoke.yml | 248 ++++++++++++ .github/workflows/syslog-auto-pipeline.yml | 100 +---- .github/workflows/syslog-issue-pipeline.yml | 100 +---- broadcasts/README.md | 22 ++ scripts/create-standardized-ticket.js | 197 ++++++++++ scripts/invoke-persona.js | 360 ++++++++++++++++++ scripts/notion-heartbeat.js | 355 +++++++++++++++++ scripts/push-broadcast-to-github.js | 179 +++++++++ scripts/receive-syslog.js | 26 +- 11 files changed, 1516 insertions(+), 178 deletions(-) create mode 100644 .github/workflows/notion-heartbeat.yml create mode 100644 .github/workflows/persona-invoke.yml create mode 100644 broadcasts/README.md create mode 100644 scripts/create-standardized-ticket.js create mode 100644 scripts/invoke-persona.js create mode 100644 scripts/notion-heartbeat.js create mode 100644 scripts/push-broadcast-to-github.js diff --git a/.github/workflows/notion-callback-pipeline.yml b/.github/workflows/notion-callback-pipeline.yml index a6fc2d39..463d7ced 100644 --- a/.github/workflows/notion-callback-pipeline.yml +++ b/.github/workflows/notion-callback-pipeline.yml @@ -109,6 +109,69 @@ jobs: FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} run: node scripts/wake-persona.js + - name: 📡 推送广播到 GitHub(Phase B4) + if: steps.persona.outcome == 'success' && steps.callback.outputs.status == 'approved' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BROADCAST_ID: ${{ steps.callback.outputs.broadcast_id }} + DEVELOPER_NAME: notion-callback + BROADCAST_CONTENT: ${{ steps.persona.outputs.result }} + run: node scripts/push-broadcast-to-github.js + + - name: 📝 回写 Notion 工单状态 + if: steps.callback.outputs.ticket_id + env: + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + TICKET_ID: ${{ steps.callback.outputs.ticket_id }} + CALLBACK_STATUS: ${{ steps.callback.outputs.status }} + run: | + node -e " + var https = require('https'); + var token = process.env.NOTION_TOKEN || ''; + var ticketId = process.env.TICKET_ID || ''; + var status = process.env.CALLBACK_STATUS || 'unknown'; + + if (!token || !ticketId) { + console.log('⚠️ 跳过工单状态更新'); + process.exit(0); + } + + var notionStatus = status === 'approved' ? '✅ 已完成' : '⚠️ 异常·等人工介入'; + var body = JSON.stringify({ + properties: { + '状态': { select: { name: notionStatus } } + } + }); + + var opts = { + hostname: 'api.notion.com', + port: 443, + path: '/v1/pages/' + ticketId, + method: 'PATCH', + headers: { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json', + 'Notion-Version': '2022-06-28', + 'Content-Length': Buffer.byteLength(body) + } + }; + + var req = https.request(opts, function(res) { + var data = ''; + res.on('data', function(c) { data += c; }); + res.on('end', function() { + if (res.statusCode >= 200 && res.statusCode < 300) { + console.log('✅ 工单状态已更新为 ' + notionStatus); + } else { + console.log('⚠️ 工单更新失败: ' + res.statusCode); + } + }); + }); + req.on('error', function(e) { console.log('⚠️ ' + e.message); }); + req.write(body); + req.end(); + " + - name: 📧 发送最终确认邮件 env: SMTP_USER: ${{ secrets.SMTP_USER }} diff --git a/.github/workflows/notion-heartbeat.yml b/.github/workflows/notion-heartbeat.yml new file mode 100644 index 00000000..d7b5969a --- /dev/null +++ b/.github/workflows/notion-heartbeat.yml @@ -0,0 +1,44 @@ +name: Notion Heartbeat Monitor +# 💓 Phase B3 · 工单心跳监控 +# +# 每 5 分钟检测 Notion 工单队列中的待处理工单: +# - 超过 5 分钟未回执 → 重新触发人格体唤醒(最多 3 次) +# - 3 次重试仍无回执 → 标记工单异常 + 发邮件通知冰朔 +# +# 依赖 Secrets: +# NOTION_API_TOKEN Notion API token +# NOTION_TICKET_DB_ID 工单队列数据库 ID +# SMTP_USER 邮件发送者 +# SMTP_PASS 邮件授权码 + +on: + schedule: + - cron: '*/5 * * * *' + workflow_dispatch: + +jobs: + heartbeat: + name: 💓 工单心跳检测 + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: 💓 执行心跳检测 + env: + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + NOTION_TICKET_DB_ID: ${{ secrets.NOTION_TICKET_DB_ID }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SMTP_USER: ${{ secrets.SMTP_USER }} + SMTP_PASS: ${{ secrets.SMTP_PASS }} + ALERT_EMAIL: '565183519@qq.com' + run: node scripts/notion-heartbeat.js diff --git a/.github/workflows/persona-invoke.yml b/.github/workflows/persona-invoke.yml new file mode 100644 index 00000000..e2ab5d45 --- /dev/null +++ b/.github/workflows/persona-invoke.yml @@ -0,0 +1,248 @@ +name: Persona Invoke Endpoint +# 🔗 Phase B2 · Notion Agent → 铸渊人格体唤醒 +# +# Notion Agent 通过 workflow_dispatch 触发此工作流, +# 等效于 POST /api/persona/invoke 接口。 +# +# 完整流程: +# ① Notion Agent 发送 workflow_dispatch(传入工单信息) +# ② 铸渊 Agent 从 Notion 读取工单内容 +# ③ 唤醒人格体(Claude API)处理 SYSLOG +# ④ 处理结果写回 Notion 工单(receipt_status = completed) +# ⑤ 广播文件推送到 GitHub 仓库 broadcasts/{dev_id}/ +# +# 依赖 Secrets: +# LLM_API_KEY 第三方 LLM 平台密钥 +# LLM_BASE_URL 第三方 LLM 平台 API 地址 +# NOTION_API_TOKEN Notion API token +# NOTION_TICKET_DB_ID 工单队列数据库 ID +# CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID +# PORTRAIT_DB_ID 开发者动态画像库 ID +# FINGERPRINT_DB_ID 模块指纹注册表 ID +# INVOKE_API_KEY 调用鉴权密钥 + +on: + workflow_dispatch: + inputs: + work_order_id: + description: 'Notion 工单页面 ID' + required: true + type: string + task_id: + description: '广播编号(如 BC-M23-001-AW)' + required: true + type: string + developer: + description: '开发者信息(如 DEV-012 Awen)' + required: false + default: 'unknown' + type: string + syslog_raw: + description: 'SYSLOG JSON 原文(可选,如为空则从 Notion 读取)' + required: false + default: '' + type: string + action: + description: '动作类型' + required: false + default: 'process_syslog' + type: string + +jobs: + invoke: + name: 🔗 唤醒人格体处理 SYSLOG + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm ci --ignore-scripts + + - name: 🔍 模块验证 + id: verify + env: + SYSLOG_CONTENT: ${{ inputs.syslog_raw }} + BROADCAST_ID: ${{ inputs.task_id }} + AUTHOR: ${{ inputs.developer }} + run: node scripts/verify-modules.js + + - name: 🧠 唤醒人格体 + id: persona + env: + LLM_API_KEY: ${{ secrets.LLM_API_KEY }} + LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }} + BROADCAST_ID: ${{ inputs.task_id }} + SUBMIT_TYPE: syslog + SUBMIT_CONTENT: ${{ inputs.syslog_raw }} + AUTHOR: ${{ inputs.developer }} + MODULE_VERIFY_RESULT: ${{ steps.verify.outputs.verify_report }} + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + CORE_BRAIN_PAGE_ID: ${{ secrets.CORE_BRAIN_PAGE_ID }} + PORTRAIT_DB_ID: ${{ secrets.PORTRAIT_DB_ID }} + FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} + run: node scripts/wake-persona.js + + - name: 📝 回写 Notion 工单 + if: always() + env: + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + WORK_ORDER_ID: ${{ inputs.work_order_id }} + PERSONA_RESULT: ${{ steps.persona.outputs.result }} + TASK_ID: ${{ inputs.task_id }} + run: | + node -e " + var https = require('https'); + + var token = process.env.NOTION_TOKEN || ''; + var workOrderId = process.env.WORK_ORDER_ID || ''; + var result = process.env.PERSONA_RESULT || '(no result)'; + var taskId = process.env.TASK_ID || ''; + + if (!token || !workOrderId) { + console.log('⚠️ 缺少 Notion 配置,跳过回写'); + process.exit(0); + } + + // 更新工单状态为 ✅ 已完成 + var body = JSON.stringify({ + properties: { + '状态': { select: { name: '✅ 已完成' } } + } + }); + + var opts = { + hostname: 'api.notion.com', + port: 443, + path: '/v1/pages/' + workOrderId, + method: 'PATCH', + headers: { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json', + 'Notion-Version': '2022-06-28', + 'Content-Length': Buffer.byteLength(body) + } + }; + + var req = https.request(opts, function(res) { + var data = ''; + res.on('data', function(c) { data += c; }); + res.on('end', function() { + if (res.statusCode >= 200 && res.statusCode < 300) { + console.log('✅ 工单状态已更新为 ✅ 已完成'); + } else { + console.log('⚠️ 工单状态更新失败: ' + res.statusCode); + } + }); + }); + req.on('error', function(e) { console.log('⚠️ ' + e.message); }); + req.write(body); + req.end(); + + // 追加处理结果到工单 + var appendBody = JSON.stringify({ + children: [{ + object: 'block', + type: 'heading_2', + heading_2: { + rich_text: [{ type: 'text', text: { content: '🧠 人格体处理结果 · receipt_status: completed' } }] + } + }, { + object: 'block', + type: 'paragraph', + paragraph: { + rich_text: [{ type: 'text', text: { content: result.slice(0, 2000) } }] + } + }] + }); + + var appendOpts = { + hostname: 'api.notion.com', + port: 443, + path: '/v1/blocks/' + workOrderId + '/children', + method: 'PATCH', + headers: { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json', + 'Notion-Version': '2022-06-28', + 'Content-Length': Buffer.byteLength(appendBody) + } + }; + + var req2 = https.request(appendOpts, function(res) { + var data = ''; + res.on('data', function(c) { data += c; }); + res.on('end', function() { + if (res.statusCode >= 200 && res.statusCode < 300) { + console.log('✅ 处理结果已追加到工单'); + } else { + console.log('⚠️ 结果追加失败: ' + res.statusCode); + } + }); + }); + req2.on('error', function(e) { console.log('⚠️ ' + e.message); }); + req2.write(appendBody); + req2.end(); + " + + - name: 📡 推送广播到 GitHub + if: steps.persona.outcome == 'success' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BROADCAST_ID: ${{ inputs.task_id }} + DEVELOPER_ID: '' + DEVELOPER_NAME: ${{ inputs.developer }} + BROADCAST_CONTENT: ${{ steps.persona.outputs.result }} + run: node scripts/push-broadcast-to-github.js + + - name: 🔴 失败处理 + if: failure() + env: + NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} + WORK_ORDER_ID: ${{ inputs.work_order_id }} + run: | + node -e " + var https = require('https'); + var token = process.env.NOTION_TOKEN || ''; + var workOrderId = process.env.WORK_ORDER_ID || ''; + + if (!token || !workOrderId) process.exit(0); + + var body = JSON.stringify({ + properties: { + '状态': { select: { name: '⚠️ 异常·等人工介入' } } + } + }); + + var opts = { + hostname: 'api.notion.com', + port: 443, + path: '/v1/pages/' + workOrderId, + method: 'PATCH', + headers: { + 'Authorization': 'Bearer ' + token, + 'Content-Type': 'application/json', + 'Notion-Version': '2022-06-28', + 'Content-Length': Buffer.byteLength(body) + } + }; + + var req = https.request(opts, function(res) { + var data = ''; + res.on('data', function(c) { data += c; }); + res.on('end', function() { + console.log('工单状态已标记为 ⚠️ 异常'); + }); + }); + req.on('error', function(e) { console.log(e.message); }); + req.write(body); + req.end(); + " diff --git a/.github/workflows/syslog-auto-pipeline.yml b/.github/workflows/syslog-auto-pipeline.yml index 02eb3e5e..a0d84b10 100644 --- a/.github/workflows/syslog-auto-pipeline.yml +++ b/.github/workflows/syslog-auto-pipeline.yml @@ -130,7 +130,8 @@ jobs: FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} run: node scripts/wake-persona.js - - name: 📋 Write to Notion ticket + - name: 📋 创建标准化 Notion 工单(Phase B1) + id: ticket if: ${{ secrets.NOTION_API_TOKEN }} env: NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} @@ -140,93 +141,18 @@ jobs: PERSONA_RESULT: ${{ steps.persona.outputs.result }} MODULE_VERIFY: ${{ steps.verify.outputs.verify_result }} MODULES_UPLOADED: ${{ steps.verify.outputs.modules_uploaded }} - AUTHOR: ${{ steps.parse.outputs.author }} - run: | - node -e " - const https = require('https'); + DEVELOPER: ${{ steps.parse.outputs.author }} + SYSLOG_RAW: ${{ steps.parse.outputs.content }} + run: node scripts/create-standardized-ticket.js - const token = process.env.NOTION_TOKEN; - const dbId = process.env.NOTION_TICKET_DB_ID; - const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; - const type = process.env.SUBMIT_TYPE || 'syslog'; - const result = process.env.PERSONA_RESULT || '(no result)'; - const modulesUploaded = process.env.MODULES_UPLOADED || 'false'; - const moduleVerify = process.env.MODULE_VERIFY || '{}'; - const author = process.env.AUTHOR || 'unknown'; - - if (!token || !dbId) { - console.log('⚠️ Notion credentials not configured, skipping ticket creation'); - process.exit(0); - } - - const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答'; - const verifyStatus = modulesUploaded === 'true' ? '模块已验证✅' : '模块待验证⚠️'; - const title = '[自动] ' + broadcastId + ' · ' + typeLabel + ' · ' + verifyStatus; - - // 构建工单内容:包含人格体处理结果 + 模块验证数据 - const ticketContent = [ - '## 铸渊核心大脑处理结果', - '', - result.slice(0, 1500), - '', - '## 模块上传验证', - '', - '模块全部上传: ' + (modulesUploaded === 'true' ? '✅ 是' : '❌ 否'), - '提交者: ' + author, - '', - '验证详情: ' + moduleVerify.slice(0, 400), - ].join('\\n'); - - // SYSLOG类型工单设为'待处理'(等待Notion侧核心大脑处理) - // 提问类型工单设为'已完成'(铸渊已生成解答) - const ticketStatus = type === 'syslog' ? '待处理' : '已完成'; - - const body = JSON.stringify({ - parent: { database_id: dbId }, - properties: { - '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, - '操作类型': { select: { name: '其他' } }, - '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, - '状态': { select: { name: ticketStatus } }, - '优先级': { select: { name: 'P1' } } - }, - children: [{ - object: 'block', - type: 'paragraph', - paragraph: { - rich_text: [{ type: 'text', text: { content: ticketContent.slice(0, 2000) } }] - } - }] - }); - - const opts = { - hostname: 'api.notion.com', - port: 443, - path: '/v1/pages', - method: 'POST', - headers: { - 'Authorization': 'Bearer ' + token, - 'Content-Type': 'application/json', - 'Notion-Version': '2022-06-28', - 'Content-Length': Buffer.byteLength(body) - } - }; - - const req = https.request(opts, (res) => { - let data = ''; - res.on('data', (c) => data += c); - res.on('end', () => { - if (res.statusCode >= 200 && res.statusCode < 300) { - console.log('✅ Notion 工单已创建'); - } else { - console.log('⚠️ Notion 工单创建失败: ' + res.statusCode + ' ' + data); - } - }); - }); - req.on('error', (e) => console.log('⚠️ Notion 请求失败: ' + e.message)); - req.write(body); - req.end(); - " + - name: 📡 推送广播到 GitHub(Phase B4) + if: steps.persona.outcome == 'success' && steps.parse.outputs.type == 'syslog' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + DEVELOPER_NAME: ${{ steps.parse.outputs.author }} + BROADCAST_CONTENT: ${{ steps.persona.outputs.result }} + run: node scripts/push-broadcast-to-github.js - name: 📧 Send email to developer env: diff --git a/.github/workflows/syslog-issue-pipeline.yml b/.github/workflows/syslog-issue-pipeline.yml index 4acbc3b0..27ac9cfc 100644 --- a/.github/workflows/syslog-issue-pipeline.yml +++ b/.github/workflows/syslog-issue-pipeline.yml @@ -130,7 +130,8 @@ jobs: FINGERPRINT_DB_ID: ${{ secrets.FINGERPRINT_DB_ID }} run: node scripts/wake-persona.js - - name: 📋 Write to Notion ticket + - name: 📋 创建标准化 Notion 工单(Phase B1) + id: ticket if: ${{ secrets.NOTION_API_TOKEN }} env: NOTION_TOKEN: ${{ secrets.NOTION_API_TOKEN }} @@ -140,93 +141,18 @@ jobs: PERSONA_RESULT: ${{ steps.persona.outputs.result }} MODULE_VERIFY: ${{ steps.verify.outputs.verify_result }} MODULES_UPLOADED: ${{ steps.verify.outputs.modules_uploaded }} - AUTHOR: ${{ steps.parse.outputs.author }} - run: | - node -e " - const https = require('https'); + DEVELOPER: ${{ steps.parse.outputs.author }} + SYSLOG_RAW: ${{ steps.parse.outputs.content }} + run: node scripts/create-standardized-ticket.js - const token = process.env.NOTION_TOKEN; - const dbId = process.env.NOTION_TICKET_DB_ID; - const broadcastId = process.env.BROADCAST_ID || 'UNKNOWN'; - const type = process.env.SUBMIT_TYPE || 'syslog'; - const result = process.env.PERSONA_RESULT || '(no result)'; - const modulesUploaded = process.env.MODULES_UPLOADED || 'false'; - const moduleVerify = process.env.MODULE_VERIFY || '{}'; - const author = process.env.AUTHOR || 'unknown'; - - if (!token || !dbId) { - console.log('⚠️ Notion credentials not configured, skipping ticket creation'); - process.exit(0); - } - - const typeLabel = type === 'syslog' ? 'SYSLOG闭环' : '提问解答'; - const verifyStatus = modulesUploaded === 'true' ? '模块已验证✅' : '模块待验证⚠️'; - const title = '[自动] ' + broadcastId + ' · ' + typeLabel + ' · ' + verifyStatus; - - // 构建工单内容:包含人格体处理结果 + 模块验证数据 - const ticketContent = [ - '## 铸渊核心大脑处理结果', - '', - result.slice(0, 1500), - '', - '## 模块上传验证', - '', - '模块全部上传: ' + (modulesUploaded === 'true' ? '✅ 是' : '❌ 否'), - '提交者: ' + author, - '', - '验证详情: ' + moduleVerify.slice(0, 400), - ].join('\\n'); - - // SYSLOG类型工单设为'待处理'(等待Notion侧核心大脑处理) - // 提问类型工单设为'已完成'(铸渊已生成解答) - const ticketStatus = type === 'syslog' ? '待处理' : '已完成'; - - const body = JSON.stringify({ - parent: { database_id: dbId }, - properties: { - '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, - '操作类型': { select: { name: '其他' } }, - '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, - '状态': { select: { name: ticketStatus } }, - '优先级': { select: { name: 'P1' } } - }, - children: [{ - object: 'block', - type: 'paragraph', - paragraph: { - rich_text: [{ type: 'text', text: { content: ticketContent.slice(0, 2000) } }] - } - }] - }); - - const opts = { - hostname: 'api.notion.com', - port: 443, - path: '/v1/pages', - method: 'POST', - headers: { - 'Authorization': 'Bearer ' + token, - 'Content-Type': 'application/json', - 'Notion-Version': '2022-06-28', - 'Content-Length': Buffer.byteLength(body) - } - }; - - const req = https.request(opts, (res) => { - let data = ''; - res.on('data', (c) => data += c); - res.on('end', () => { - if (res.statusCode >= 200 && res.statusCode < 300) { - console.log('✅ Notion 工单已创建'); - } else { - console.log('⚠️ Notion 工单创建失败: ' + res.statusCode + ' ' + data); - } - }); - }); - req.on('error', (e) => console.log('⚠️ Notion 请求失败: ' + e.message)); - req.write(body); - req.end(); - " + - name: 📡 推送广播到 GitHub(Phase B4) + if: steps.persona.outcome == 'success' && steps.parse.outputs.type == 'syslog' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BROADCAST_ID: ${{ steps.parse.outputs.broadcast_id }} + DEVELOPER_NAME: ${{ steps.parse.outputs.author }} + BROADCAST_CONTENT: ${{ steps.persona.outputs.result }} + run: node scripts/push-broadcast-to-github.js - name: 📧 Send email to developer env: diff --git a/broadcasts/README.md b/broadcasts/README.md new file mode 100644 index 00000000..a1d6d7bf --- /dev/null +++ b/broadcasts/README.md @@ -0,0 +1,22 @@ +# 📡 broadcasts/ + +自动广播归档目录。 + +铸渊 Agent 处理完 SYSLOG 后,会自动将新广播文件推送到此目录: + +``` +broadcasts/ + DEV-001/ + BC-M14-001-YY.md + DEV-012/ + BC-M22-009-AW.md + BC-M23-001-AW.md + ... +``` + +**推送规范**: +- 路径:`broadcasts/{developer_id}/{taskId}.md` +- 提交信息:`[AutoBroadcast] {taskId} · {开发者名} · {模块名}环节{N}` +- 推送方式:通过 GitHub API(`PUT /repos/.../contents/...`) + +**不要手动编辑此目录**,由铸渊 Agent 自动管理。 diff --git a/scripts/create-standardized-ticket.js b/scripts/create-standardized-ticket.js new file mode 100644 index 00000000..a1607245 --- /dev/null +++ b/scripts/create-standardized-ticket.js @@ -0,0 +1,197 @@ +// scripts/create-standardized-ticket.js +// 铸渊 · Phase B1 · 标准化工单创建脚本 +// +// 将 SYSLOG 写入 Notion 工单队列时使用标准化格式, +// 让 Notion Agent 能够识别和触发后续处理。 +// +// 环境变量: +// NOTION_TOKEN Notion API token +// NOTION_TICKET_DB_ID 工单队列数据库 ID +// BROADCAST_ID 广播编号(如 BC-M23-001-AW) +// DEVELOPER 开发者信息(如 "DEV-012 Awen") +// SYSLOG_RAW 完整 SYSLOG 原文(JSON 字符串或纯文本) +// SUBMIT_TYPE 提交类型(syslog / question) +// PERSONA_RESULT 人格体处理结果(可选,首次可为空) +// MODULE_VERIFY 模块验证结果 JSON(可选) +// MODULES_UPLOADED 模块是否全部上传(true/false) + +'use strict'; + +const https = require('https'); + +const NOTION_TOKEN = process.env.NOTION_TOKEN || ''; +const NOTION_TICKET_DB_ID = process.env.NOTION_TICKET_DB_ID || ''; +const BROADCAST_ID = process.env.BROADCAST_ID || 'UNKNOWN'; +const DEVELOPER = process.env.DEVELOPER || process.env.AUTHOR || 'unknown'; +const SYSLOG_RAW = process.env.SYSLOG_RAW || process.env.SUBMIT_CONTENT || ''; +const SUBMIT_TYPE = process.env.SUBMIT_TYPE || 'syslog'; +const PERSONA_RESULT = process.env.PERSONA_RESULT || ''; +const MODULE_VERIFY = process.env.MODULE_VERIFY || ''; +const MODULES_UPLOADED = process.env.MODULES_UPLOADED || 'false'; + +const NOTION_VERSION = '2022-06-28'; +const NOTION_API_HOSTNAME = 'api.notion.com'; +const NOTION_RICH_TEXT_MAX = 2000; + +// ══════════════════════════════════════════════════════════ +// Notion API 工具 +// ══════════════════════════════════════════════════════════ + +function notionPost(endpoint, body) { + return new Promise(function (resolve, reject) { + var payload = JSON.stringify(body); + var opts = { + hostname: NOTION_API_HOSTNAME, + port: 443, + path: endpoint, + method: 'POST', + headers: { + 'Authorization': 'Bearer ' + NOTION_TOKEN, + 'Content-Type': 'application/json', + 'Notion-Version': NOTION_VERSION, + 'Content-Length': Buffer.byteLength(payload), + }, + }; + var req = https.request(opts, function (res) { + var data = ''; + res.on('data', function (chunk) { data += chunk; }); + res.on('end', function () { + try { + var parsed = JSON.parse(data); + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(parsed); + } else { + reject(new Error('Notion API ' + res.statusCode + ': ' + (parsed.message || data))); + } + } catch (e) { + reject(new Error('Notion API parse error: ' + data)); + } + }); + }); + req.on('error', reject); + req.write(payload); + req.end(); + }); +} + +function richTextChunks(content) { + var str = String(content || ''); + var chunks = []; + for (var i = 0; i < str.length; i += NOTION_RICH_TEXT_MAX) { + chunks.push({ type: 'text', text: { content: str.slice(i, i + NOTION_RICH_TEXT_MAX) } }); + } + if (chunks.length === 0) { + chunks.push({ type: 'text', text: { content: '' } }); + } + return chunks; +} + +// ══════════════════════════════════════════════════════════ +// 标准化工单创建 +// ══════════════════════════════════════════════════════════ + +async function createStandardizedTicket() { + if (!NOTION_TOKEN || !NOTION_TICKET_DB_ID) { + console.log('⚠️ Notion credentials not configured, skipping ticket creation'); + process.exit(0); + } + + var now = new Date().toISOString(); + var typeLabel = SUBMIT_TYPE === 'syslog' ? 'SYSLOG处理' : '提问解答'; + var ticketStatus = SUBMIT_TYPE === 'syslog' ? '待处理' : '已完成'; + var verifyStatus = MODULES_UPLOADED === 'true' ? '模块已验证✅' : '模块待验证⚠️'; + var title = '[自动] ' + BROADCAST_ID + ' · ' + typeLabel + ' · ' + verifyStatus; + + // Phase B1 标准化字段 — 工单内容 + var ticketContent = [ + '## 📡 标准化工单 · Phase B1', + '', + '| 字段 | 值 |', + '|------|-----|', + '| 工单类型 | ' + typeLabel + ' |', + '| 状态 | ' + ticketStatus + ' |', + '| 来源 | GitHub Actions |', + '| taskId | ' + BROADCAST_ID + ' |', + '| developer | ' + DEVELOPER + ' |', + '| created_at | ' + now + ' |', + '| retry_count | 0 |', + '| receipt_status | pending |', + '', + ]; + + if (PERSONA_RESULT) { + ticketContent.push('## 铸渊核心大脑处理结果'); + ticketContent.push(''); + ticketContent.push(PERSONA_RESULT.slice(0, 1500)); + ticketContent.push(''); + } + + ticketContent.push('## 模块上传验证'); + ticketContent.push(''); + ticketContent.push('模块全部上传: ' + (MODULES_UPLOADED === 'true' ? '✅ 是' : '❌ 否')); + ticketContent.push(''); + + if (MODULE_VERIFY) { + ticketContent.push('验证详情: ' + MODULE_VERIFY.slice(0, 400)); + ticketContent.push(''); + } + + var contentText = ticketContent.join('\n'); + + // 构建 Notion 页面 + var body = { + parent: { database_id: NOTION_TICKET_DB_ID }, + properties: { + '标题': { title: [{ type: 'text', text: { content: title.slice(0, 120) } }] }, + '操作类型': { select: { name: '其他' } }, + '提交者': { rich_text: [{ type: 'text', text: { content: '铸渊Agent·自动管道' } }] }, + '状态': { select: { name: ticketStatus } }, + '优先级': { select: { name: 'P1' } }, + }, + children: [ + { + object: 'block', + type: 'paragraph', + paragraph: { + rich_text: richTextChunks(contentText), + }, + }, + ], + }; + + // 将 SYSLOG 原文作为代码块附加(如果有) + if (SYSLOG_RAW) { + body.children.push({ + object: 'block', + type: 'code', + code: { + rich_text: richTextChunks(SYSLOG_RAW.slice(0, 8000)), + language: 'json', + }, + }); + } + + console.log('📋 创建标准化工单...'); + console.log(' taskId: ' + BROADCAST_ID); + console.log(' developer: ' + DEVELOPER); + console.log(' type: ' + typeLabel); + console.log(' receipt_status: pending'); + + try { + var result = await notionPost('/v1/pages', body); + console.log('✅ Notion 标准化工单已创建: ' + result.id); + + // 输出工单 ID 到 GITHUB_OUTPUT + var outputFile = process.env.GITHUB_OUTPUT; + if (outputFile) { + var fs = require('fs'); + fs.appendFileSync(outputFile, 'ticket_page_id=' + result.id + '\n'); + fs.appendFileSync(outputFile, 'ticket_url=' + (result.url || '') + '\n'); + } + } catch (err) { + console.error('❌ 工单创建失败: ' + err.message); + process.exit(1); + } +} + +createStandardizedTicket(); diff --git a/scripts/invoke-persona.js b/scripts/invoke-persona.js new file mode 100644 index 00000000..bd4cc12e --- /dev/null +++ b/scripts/invoke-persona.js @@ -0,0 +1,360 @@ +// scripts/invoke-persona.js +// 铸渊 · Phase B2 · 人格体唤醒调用脚本 +// +// Notion Agent 调用此脚本(通过 workflow_dispatch), +// 脚本读取 Notion 工单内容 → 唤醒人格体 → 处理结果写回 Notion。 +// +// 环境变量: +// WORK_ORDER_ID Notion 工单页面 ID +// TASK_ID 广播编号(如 BC-M23-001-AW) +// DEVELOPER 开发者信息(如 "DEV-012 Awen") +// SYSLOG_RAW SYSLOG JSON 原文 +// ACTION 动作类型(process_syslog / retry) +// LLM_API_KEY 第三方 LLM 平台密钥 +// LLM_BASE_URL 第三方 LLM 平台 API 地址 +// NOTION_TOKEN Notion API token +// CORE_BRAIN_PAGE_ID 曜冥核心大脑 v4.0 页面 ID +// PORTRAIT_DB_ID 开发者动态画像库 ID +// FINGERPRINT_DB_ID 模块指纹注册表 ID +// INVOKE_API_KEY 鉴权密钥(用于 API 调用验证) + +'use strict'; + +const https = require('https'); +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +// ══════════════════════════════════════════════════════════ +// 配置 +// ══════════════════════════════════════════════════════════ + +var WORK_ORDER_ID = process.env.WORK_ORDER_ID || ''; +var TASK_ID = process.env.TASK_ID || process.env.BROADCAST_ID || 'UNKNOWN'; +var DEVELOPER = process.env.DEVELOPER || 'unknown'; +var SYSLOG_RAW = process.env.SYSLOG_RAW || ''; +var ACTION = process.env.ACTION || 'process_syslog'; + +var LLM_API_KEY = process.env.LLM_API_KEY || ''; +var LLM_BASE_URL = (process.env.LLM_BASE_URL || '').replace(/\/+$/, ''); +var NOTION_TOKEN = process.env.NOTION_TOKEN || ''; +var CORE_BRAIN_PAGE_ID = process.env.CORE_BRAIN_PAGE_ID || ''; +var PORTRAIT_DB_ID = process.env.PORTRAIT_DB_ID || ''; +var FINGERPRINT_DB_ID = process.env.FINGERPRINT_DB_ID || ''; + +var NOTION_VERSION = '2022-06-28'; +var NOTION_API_HOSTNAME = 'api.notion.com'; + +// ══════════════════════════════════════════════════════════ +// HTTP 工具 +// ══════════════════════════════════════════════════════════ + +function httpRequest(url, options, body) { + return new Promise(function (resolve, reject) { + var parsed = new URL(url); + var isHttps = parsed.protocol === 'https:'; + var mod = isHttps ? https : http; + + var opts = { + hostname: parsed.hostname, + port: parsed.port || (isHttps ? 443 : 80), + path: parsed.pathname + parsed.search, + method: options.method || 'GET', + headers: options.headers || {}, + timeout: options.timeout || 120000, + }; + + var req = mod.request(opts, function (res) { + var data = ''; + res.on('data', function (chunk) { data += chunk; }); + res.on('end', function () { + resolve({ status: res.statusCode, body: data }); + }); + }); + + req.on('error', reject); + req.on('timeout', function () { req.destroy(); reject(new Error('Request timeout')); }); + + if (body) { + req.write(typeof body === 'string' ? body : JSON.stringify(body)); + } + req.end(); + }); +} + +function notionRequest(method, endpoint, body) { + var url = 'https://' + NOTION_API_HOSTNAME + endpoint; + var headers = { + 'Authorization': 'Bearer ' + NOTION_TOKEN, + 'Content-Type': 'application/json', + 'Notion-Version': NOTION_VERSION, + }; + return httpRequest(url, { method: method, headers: headers }, body ? JSON.stringify(body) : null) + .then(function (res) { + var parsed = JSON.parse(res.body); + if (res.status >= 200 && res.status < 300) return parsed; + throw new Error('Notion API ' + res.status + ': ' + (parsed.message || res.body)); + }); +} + +// ══════════════════════════════════════════════════════════ +// Step 1: 读取工单内容(从 Notion) +// ══════════════════════════════════════════════════════════ + +async function readWorkOrder() { + if (!WORK_ORDER_ID) { + console.log('ℹ️ No WORK_ORDER_ID, using SYSLOG_RAW directly'); + return { syslog_raw: SYSLOG_RAW, taskId: TASK_ID, developer: DEVELOPER }; + } + + console.log('📖 读取 Notion 工单: ' + WORK_ORDER_ID); + try { + var page = await notionRequest('GET', '/v1/pages/' + WORK_ORDER_ID); + var props = page.properties || {}; + + // 提取工单字段 + var taskId = TASK_ID; + var developer = DEVELOPER; + + // 尝试从工单属性中读取 + if (props['广播编号'] && props['广播编号'].rich_text) { + var bcText = props['广播编号'].rich_text.map(function (t) { return t.plain_text || ''; }).join(''); + if (bcText) taskId = bcText; + } + if (props['开发者编号'] && props['开发者编号'].rich_text) { + var devText = props['开发者编号'].rich_text.map(function (t) { return t.plain_text || ''; }).join(''); + if (devText) developer = devText; + } + + // 读取页面内容(子块)来获取 SYSLOG 原文 + var blocks = await notionRequest('GET', '/v1/blocks/' + WORK_ORDER_ID + '/children?page_size=20'); + var syslogRaw = SYSLOG_RAW; + + if (blocks.results) { + blocks.results.forEach(function (block) { + if (block.type === 'code' && block.code && block.code.rich_text) { + var codeText = block.code.rich_text.map(function (t) { return t.plain_text || ''; }).join(''); + if (codeText.length > syslogRaw.length) { + syslogRaw = codeText; + } + } + }); + } + + console.log(' → taskId: ' + taskId); + console.log(' → developer: ' + developer); + console.log(' → syslog_raw length: ' + syslogRaw.length); + + return { syslog_raw: syslogRaw, taskId: taskId, developer: developer }; + } catch (err) { + console.log('⚠️ 工单读取失败: ' + err.message + ',使用环境变量'); + return { syslog_raw: SYSLOG_RAW, taskId: TASK_ID, developer: DEVELOPER }; + } +} + +// ══════════════════════════════════════════════════════════ +// Step 2: 唤醒人格体(复用 wake-persona.js 的逻辑) +// ══════════════════════════════════════════════════════════ + +async function invokePersona(workOrder) { + console.log('🧠 唤醒人格体处理 SYSLOG...'); + + // 设置环境变量供 wake-persona.js 读取 + process.env.BROADCAST_ID = workOrder.taskId; + process.env.SUBMIT_TYPE = 'syslog'; + process.env.SUBMIT_CONTENT = workOrder.syslog_raw; + process.env.AUTHOR = workOrder.developer; + + // 执行 wake-persona.js(fork 子进程) + var childProcess = require('child_process'); + var wakeScript = path.join(__dirname, 'wake-persona.js'); + + return new Promise(function (resolve, reject) { + var child = childProcess.fork(wakeScript, [], { + env: Object.assign({}, process.env, { + BROADCAST_ID: workOrder.taskId, + SUBMIT_TYPE: 'syslog', + SUBMIT_CONTENT: workOrder.syslog_raw, + AUTHOR: workOrder.developer, + LLM_API_KEY: LLM_API_KEY, + LLM_BASE_URL: LLM_BASE_URL, + NOTION_TOKEN: NOTION_TOKEN, + CORE_BRAIN_PAGE_ID: CORE_BRAIN_PAGE_ID, + PORTRAIT_DB_ID: PORTRAIT_DB_ID, + FINGERPRINT_DB_ID: FINGERPRINT_DB_ID, + }), + stdio: ['pipe', 'pipe', 'pipe', 'ipc'], + }); + + var stdout = ''; + var stderr = ''; + child.stdout.on('data', function (d) { stdout += d; process.stdout.write(d); }); + child.stderr.on('data', function (d) { stderr += d; process.stderr.write(d); }); + + child.on('exit', function (code) { + if (code === 0) { + // 从 GITHUB_OUTPUT 文件读取 result(如果存在) + var outputFile = process.env.GITHUB_OUTPUT; + var result = ''; + if (outputFile && fs.existsSync(outputFile)) { + var outputContent = fs.readFileSync(outputFile, 'utf8'); + var resultMatch = outputContent.match(/result<= 200 && res.status < 300) { + var tickets = parsed.results || []; + console.log(' → 找到 ' + tickets.length + ' 个待处理工单'); + return tickets; + } else { + console.log('⚠️ 查询失败: ' + (parsed.message || res.body)); + return []; + } + } catch (err) { + console.log('⚠️ 查询异常: ' + err.message); + return []; + } +} + +// ══════════════════════════════════════════════════════════ +// Step 2: 检测超时工单 +// ══════════════════════════════════════════════════════════ + +function filterTimedOutTickets(tickets) { + var now = Date.now(); + var timedOut = []; + + tickets.forEach(function (ticket) { + var createdTime = new Date(ticket.created_time).getTime(); + var age = now - createdTime; + + // 只处理来自 "铸渊Agent·自动管道" 的 SYSLOG 工单 + var props = ticket.properties || {}; + var submitter = ''; + if (props['提交者'] && props['提交者'].rich_text) { + submitter = props['提交者'].rich_text.map(function (t) { return t.plain_text || ''; }).join(''); + } + + // 只对自动管道创建的工单做心跳检测 + if (!submitter.includes('铸渊Agent') && !submitter.includes('自动管道')) { + return; + } + + // 超过 5 分钟未完成 + if (age > HEARTBEAT_TIMEOUT_MS) { + var title = ''; + if (props['标题'] && props['标题'].title) { + title = props['标题'].title.map(function (t) { return t.plain_text || ''; }).join(''); + } + + timedOut.push({ + id: ticket.id, + title: title, + createdTime: ticket.created_time, + ageMinutes: Math.round(age / 60000), + }); + } + }); + + console.log(' → ' + timedOut.length + ' 个工单超时(> 5 分钟)'); + return timedOut; +} + +// ══════════════════════════════════════════════════════════ +// Step 3: 触发重试(通过 workflow_dispatch) +// ══════════════════════════════════════════════════════════ + +async function triggerRetry(ticket) { + if (!GITHUB_TOKEN) { + console.log('⚠️ 缺少 GITHUB_TOKEN,无法触发重试'); + return false; + } + + console.log('🔄 重试唤醒: ' + ticket.title + ' (超时 ' + ticket.ageMinutes + ' 分钟)'); + + // 从工单标题提取 broadcast_id + var bcMatch = (ticket.title || '').match(/BC-[A-Z0-9]+-\d+-[A-Z]+/i); + var broadcastId = bcMatch ? bcMatch[0] : 'UNKNOWN'; + + try { + var res = await httpsPost('api.github.com', + '/repos/' + REPO_OWNER + '/' + REPO_NAME + '/actions/workflows/persona-invoke.yml/dispatches', + { + ref: 'main', + inputs: { + work_order_id: ticket.id, + task_id: broadcastId, + developer: 'heartbeat-retry', + action: 'retry', + }, + }, + { + 'Authorization': 'Bearer ' + GITHUB_TOKEN, + 'Accept': 'application/vnd.github+json', + 'User-Agent': 'ZhuyuanHeartbeat/1.0', + 'X-GitHub-Api-Version': '2022-11-28', + } + ); + + if (res.status === 204 || res.status === 200) { + console.log(' → ✅ workflow_dispatch 触发成功'); + return true; + } else { + console.log(' → ⚠️ 触发失败: HTTP ' + res.status + ' ' + res.body); + return false; + } + } catch (err) { + console.log(' → ⚠️ 触发异常: ' + err.message); + return false; + } +} + +// ══════════════════════════════════════════════════════════ +// Step 4: 标记工单异常 +// ══════════════════════════════════════════════════════════ + +async function markTicketError(ticketId) { + try { + await httpsPatch('api.notion.com', '/v1/pages/' + ticketId, { + properties: { + '状态': { select: { name: '⚠️ 异常·等人工介入' } }, + }, + }, notionHeaders); + console.log(' → 工单已标记为 ⚠️ 异常·等人工介入'); + } catch (err) { + console.log(' → 标记失败: ' + err.message); + } +} + +// ══════════════════════════════════════════════════════════ +// Step 5: 发送告警邮件 +// ══════════════════════════════════════════════════════════ + +async function sendAlertEmail(timedOutTickets) { + if (!SMTP_USER || !SMTP_PASS) { + console.log('⚠️ SMTP 未配置,跳过告警邮件'); + return; + } + + try { + var nodemailer = require('nodemailer'); + + var ticketList = timedOutTickets.map(function (t) { + return '- ' + t.title + ' (超时 ' + t.ageMinutes + ' 分钟, 重试已耗尽)'; + }).join('\n'); + + var transporter = nodemailer.createTransport({ + host: 'smtp.qq.com', + port: 465, + secure: true, + auth: { user: SMTP_USER, pass: SMTP_PASS }, + }); + + await transporter.sendMail({ + from: '"光湖系统·告警" <' + SMTP_USER + '>', + to: ALERT_EMAIL, + subject: '[光湖系统] ⚠️ SYSLOG 工单处理超时告警', + html: [ + '
', + '

⚠️ 工单处理超时告警

', + '

以下工单超过 3 次重试仍未收到人格体回执:

', + '
' + ticketList + '
', + '

请登录 Notion 工单队列检查。

', + '

🌀 铸渊 · 心跳监控 · 自动告警

', + '
', + ].join('\n'), + }); + + console.log('📧 告警邮件已发送至 ' + ALERT_EMAIL); + } catch (err) { + console.log('⚠️ 告警邮件发送失败: ' + err.message); + } +} + +// ══════════════════════════════════════════════════════════ +// 主流程 +// ══════════════════════════════════════════════════════════ + +async function main() { + console.log('═══════════════════════════════════════════'); + console.log('💓 铸渊 · 工单心跳监控(Phase B3)'); + console.log('═══════════════════════════════════════════'); + console.log(' 时间: ' + new Date().toISOString()); + console.log(''); + + // Step 1: 查询待处理工单 + var tickets = await queryPendingTickets(); + if (tickets.length === 0) { + console.log('✅ 无待处理工单,心跳正常'); + return; + } + + // Step 2: 筛选超时工单 + var timedOut = filterTimedOutTickets(tickets); + if (timedOut.length === 0) { + console.log('✅ 所有工单均在处理窗口内,心跳正常'); + return; + } + + // Step 3 & 4: 对超时工单执行重试或标记异常 + var errorTickets = []; + + for (var i = 0; i < timedOut.length; i++) { + var ticket = timedOut[i]; + // 基于超时时间估算重试次数(每 5 分钟一次) + var estimatedRetries = Math.floor(ticket.ageMinutes / 5); + + if (estimatedRetries < MAX_RETRIES) { + // 重试 + await triggerRetry(ticket); + } else { + // 超过最大重试次数,标记异常 + console.log('❌ 工单 ' + ticket.title + ' 重试 ' + MAX_RETRIES + ' 次仍无回执'); + await markTicketError(ticket.id); + errorTickets.push(ticket); + } + } + + // Step 5: 发送告警邮件(如有异常工单) + if (errorTickets.length > 0) { + await sendAlertEmail(errorTickets); + } + + console.log(''); + console.log('✅ 心跳检测完成'); +} + +main().catch(function (err) { + console.error('❌ 心跳监控失败: ' + err.message); + process.exit(1); +}); diff --git a/scripts/push-broadcast-to-github.js b/scripts/push-broadcast-to-github.js new file mode 100644 index 00000000..32af6eb1 --- /dev/null +++ b/scripts/push-broadcast-to-github.js @@ -0,0 +1,179 @@ +// scripts/push-broadcast-to-github.js +// 铸渊 · Phase B4 · 广播文件推送到 GitHub 仓库 +// +// 人格体生成广播后,通过 GitHub API 将广播 .md 文件推送到仓库。 +// 路径规范:broadcasts/{developer_id}/{taskId}.md +// 提交信息:[AutoBroadcast] {taskId} · {developer} · {描述} +// +// 环境变量: +// GITHUB_TOKEN GitHub API token(推送用) +// BROADCAST_ID 广播编号(如 BC-M23-001-AW) +// DEVELOPER_ID 开发者编号(如 DEV-012) +// DEVELOPER_NAME 开发者名字(如 Awen) +// BROADCAST_CONTENT 广播全文内容(Markdown) +// MODULE_NAME 模块名(可选,如 M23) +// PHASE_NUMBER 环节号(可选,如 1) + +'use strict'; + +var https = require('https'); +var fs = require('fs'); + +var GITHUB_TOKEN = process.env.GITHUB_TOKEN || ''; +var BROADCAST_ID = process.env.BROADCAST_ID || ''; +var DEVELOPER_ID = process.env.DEVELOPER_ID || ''; +var DEVELOPER_NAME = process.env.DEVELOPER_NAME || ''; +var BROADCAST_CONTENT = process.env.BROADCAST_CONTENT || ''; +var MODULE_NAME = process.env.MODULE_NAME || ''; +var PHASE_NUMBER = process.env.PHASE_NUMBER || ''; + +var REPO_OWNER = 'qinfendebingshuo'; +var REPO_NAME = 'guanghulab'; + +// ══════════════════════════════════════════════════════════ +// GitHub API 工具 +// ══════════════════════════════════════════════════════════ + +function githubRequest(method, apiPath, body) { + return new Promise(function (resolve, reject) { + var payload = body ? JSON.stringify(body) : ''; + var opts = { + hostname: 'api.github.com', + port: 443, + path: apiPath, + method: method, + headers: { + 'User-Agent': 'ZhuyuanBroadcast/1.0', + 'Accept': 'application/vnd.github+json', + 'Content-Type': 'application/json', + 'X-GitHub-Api-Version': '2022-11-28', + }, + }; + + if (GITHUB_TOKEN) { + opts.headers['Authorization'] = 'Bearer ' + GITHUB_TOKEN; + } + + if (payload) { + opts.headers['Content-Length'] = Buffer.byteLength(payload); + } + + var req = https.request(opts, function (res) { + var data = ''; + res.on('data', function (chunk) { data += chunk; }); + res.on('end', function () { + try { + resolve({ status: res.statusCode, data: JSON.parse(data) }); + } catch (e) { + resolve({ status: res.statusCode, data: data }); + } + }); + }); + + req.on('error', reject); + if (payload) req.write(payload); + req.end(); + }); +} + +// ══════════════════════════════════════════════════════════ +// 广播推送 +// ══════════════════════════════════════════════════════════ + +async function pushBroadcast() { + if (!GITHUB_TOKEN) { + console.log('⚠️ 缺少 GITHUB_TOKEN,无法推送广播'); + process.exit(1); + } + + if (!BROADCAST_ID || !BROADCAST_CONTENT) { + console.log('⚠️ 缺少 BROADCAST_ID 或 BROADCAST_CONTENT'); + process.exit(1); + } + + // 确定开发者 ID(从广播编号提取或使用环境变量) + var devId = DEVELOPER_ID; + if (!devId) { + // 从 BROADCAST_ID 提取后缀 → 映射到 DEV-XXX + var suffixMatch = BROADCAST_ID.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); + var suffix = suffixMatch ? suffixMatch[1].toUpperCase() : ''; + var suffixMap = { + 'YY': 'DEV-001', 'FM': 'DEV-002', 'YF': 'DEV-003', + 'ZZ': 'DEV-004', 'XCM': 'DEV-005', 'HE': 'DEV-009', + 'JZ': 'DEV-010', 'CCNN': 'DEV-011', 'AW': 'DEV-012', + 'XX': 'DEV-013', 'SY': 'DEV-014', + }; + devId = suffixMap[suffix] || 'UNKNOWN'; + } + + // 构建路径和提交信息 + var filePath = 'broadcasts/' + devId + '/' + BROADCAST_ID + '.md'; + var moduleLabel = MODULE_NAME || BROADCAST_ID.match(/BC-([A-Z0-9-]+)-/i)?.[1] || ''; + var phaseLabel = PHASE_NUMBER ? '环节' + PHASE_NUMBER : ''; + var devLabel = DEVELOPER_NAME || devId; + var commitMessage = '[AutoBroadcast] ' + BROADCAST_ID + ' · ' + devLabel + ' · ' + moduleLabel + phaseLabel; + + console.log('📡 推送广播到 GitHub...'); + console.log(' 路径: ' + filePath); + console.log(' 提交: ' + commitMessage); + + // 检查文件是否已存在(获取 SHA) + var existingRes = await githubRequest('GET', + '/repos/' + REPO_OWNER + '/' + REPO_NAME + '/contents/' + filePath); + + var sha = null; + if (existingRes.status === 200 && existingRes.data && existingRes.data.sha) { + sha = existingRes.data.sha; + console.log(' → 文件已存在,将覆盖更新 (sha: ' + sha.slice(0, 8) + ')'); + } + + // Base64 编码广播内容 + var contentBase64 = Buffer.from(BROADCAST_CONTENT, 'utf8').toString('base64'); + + // 创建或更新文件 + var putBody = { + message: commitMessage, + content: contentBase64, + committer: { + name: 'zhuyuan-agent[bot]', + email: 'zhuyuan-agent[bot]@users.noreply.github.com', + }, + }; + + if (sha) { + putBody.sha = sha; + } + + var putRes = await githubRequest('PUT', + '/repos/' + REPO_OWNER + '/' + REPO_NAME + '/contents/' + filePath, + putBody); + + if (putRes.status === 200 || putRes.status === 201) { + console.log('✅ 广播已推送: ' + filePath); + console.log(' → commit: ' + (putRes.data.commit ? putRes.data.commit.sha.slice(0, 8) : 'unknown')); + + // 输出到 GITHUB_OUTPUT + var outputFile = process.env.GITHUB_OUTPUT; + if (outputFile) { + fs.appendFileSync(outputFile, 'broadcast_pushed=true\n'); + fs.appendFileSync(outputFile, 'broadcast_path=' + filePath + '\n'); + fs.appendFileSync(outputFile, 'broadcast_commit=' + (putRes.data.commit ? putRes.data.commit.sha : '') + '\n'); + } + } else { + console.error('❌ 广播推送失败: HTTP ' + putRes.status); + console.error(' → ' + JSON.stringify(putRes.data)); + + // 输出失败状态 + var outputFile = process.env.GITHUB_OUTPUT; + if (outputFile) { + fs.appendFileSync(outputFile, 'broadcast_pushed=false\n'); + } + + process.exit(1); + } +} + +pushBroadcast().catch(function (err) { + console.error('❌ 广播推送异常: ' + err.message); + process.exit(1); +}); diff --git a/scripts/receive-syslog.js b/scripts/receive-syslog.js index dd136852..00ff57f0 100644 --- a/scripts/receive-syslog.js +++ b/scripts/receive-syslog.js @@ -194,11 +194,13 @@ async function createSyslogEntry(syslog, token, dbId, dateStr) { async function createTicket(syslog, token, dbId, dateStr) { const broadcastId = syslog.broadcast_id || syslog.broadcastId || 'UNKNOWN'; const devId = syslog.dev_id || syslog.developer_id || 'UNKNOWN'; + const devName = syslog.developer_name || syslog.dev_name || ''; + const now = new Date().toISOString(); const properties = { - '标题': titleProp('SYSLOG 回传|' + broadcastId + ' · ' + devId), + '标题': titleProp('[自动] SYSLOG处理|' + broadcastId + ' · ' + devId), '操作类型': selectProp('其他'), - '提交者': richTextProp('巡检引擎'), + '提交者': richTextProp('铸渊Agent·自动管道'), '提交日期': dateProp(dateStr), '状态': selectProp('待处理'), '优先级': selectProp('P1'), @@ -208,6 +210,22 @@ async function createTicket(syslog, token, dbId, dateStr) { if (broadcastId !== 'UNKNOWN') properties['广播编号'] = richTextProp(broadcastId); if (devId !== 'UNKNOWN') properties['开发者编号'] = richTextProp(devId); + // Phase B1 标准化工单内容 + const ticketContent = [ + '## 📡 标准化工单 · Phase B1', + '', + '| 字段 | 值 |', + '|------|-----|', + '| 工单类型 | SYSLOG处理 |', + '| 状态 | 待处理 |', + '| 来源 | GitHub Actions |', + '| taskId | ' + broadcastId + ' |', + '| developer | ' + devId + ' ' + devName + ' |', + '| created_at | ' + now + ' |', + '| retry_count | 0 |', + '| receipt_status | pending |', + ].join('\n'); + const body = { parent: { database_id: dbId }, properties, @@ -218,7 +236,7 @@ async function createTicket(syslog, token, dbId, dateStr) { paragraph: { rich_text: [{ type: 'text', - text: { content: '📥 SYSLOG 回传,来自 ' + devId + ',关联广播 ' + broadcastId }, + text: { content: ticketContent }, }], }, }, @@ -234,7 +252,7 @@ async function createTicket(syslog, token, dbId, dateStr) { }; const result = await notionPost('/v1/pages', body, token); - console.log(' → 霜砚工单已创建: ' + result.id); + console.log(' → 标准化工单已创建: ' + result.id); return result; } From c9d6495e5fb8d087d20f7e9dd5987c551f16e235 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:37:11 +0000 Subject: [PATCH 37/46] =?UTF-8?q?refactor:=20=E6=8F=90=E5=8F=96=E5=85=B1?= =?UTF-8?q?=E4=BA=AB=20dev-suffix-map=20=E6=A8=A1=E5=9D=97=20+=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A5=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建 scripts/utils/dev-suffix-map.js (共享后缀→DEV-ID映射) - 更新 verify-modules.js + push-broadcast-to-github.js 使用共享映射 - 移动 require 到文件顶部 (invoke-persona.js, create-standardized-ticket.js) - 心跳监控参数可配置化 (HEARTBEAT_TIMEOUT_MINUTES, MAX_RETRY_COUNT) Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- scripts/create-standardized-ticket.js | 2 +- scripts/invoke-persona.js | 2 +- scripts/notion-heartbeat.js | 4 +-- scripts/push-broadcast-to-github.js | 12 ++------- scripts/utils/dev-suffix-map.js | 38 +++++++++++++++++++++++++++ scripts/verify-modules.js | 18 +++++-------- 6 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 scripts/utils/dev-suffix-map.js diff --git a/scripts/create-standardized-ticket.js b/scripts/create-standardized-ticket.js index a1607245..4bfb5b1f 100644 --- a/scripts/create-standardized-ticket.js +++ b/scripts/create-standardized-ticket.js @@ -18,6 +18,7 @@ 'use strict'; const https = require('https'); +const fs = require('fs'); const NOTION_TOKEN = process.env.NOTION_TOKEN || ''; const NOTION_TICKET_DB_ID = process.env.NOTION_TICKET_DB_ID || ''; @@ -184,7 +185,6 @@ async function createStandardizedTicket() { // 输出工单 ID 到 GITHUB_OUTPUT var outputFile = process.env.GITHUB_OUTPUT; if (outputFile) { - var fs = require('fs'); fs.appendFileSync(outputFile, 'ticket_page_id=' + result.id + '\n'); fs.appendFileSync(outputFile, 'ticket_url=' + (result.url || '') + '\n'); } diff --git a/scripts/invoke-persona.js b/scripts/invoke-persona.js index bd4cc12e..c88cbd5c 100644 --- a/scripts/invoke-persona.js +++ b/scripts/invoke-persona.js @@ -24,6 +24,7 @@ const https = require('https'); const http = require('http'); const fs = require('fs'); const path = require('path'); +const childProcess = require('child_process'); // ══════════════════════════════════════════════════════════ // 配置 @@ -166,7 +167,6 @@ async function invokePersona(workOrder) { process.env.AUTHOR = workOrder.developer; // 执行 wake-persona.js(fork 子进程) - var childProcess = require('child_process'); var wakeScript = path.join(__dirname, 'wake-persona.js'); return new Promise(function (resolve, reject) { diff --git a/scripts/notion-heartbeat.js b/scripts/notion-heartbeat.js index a259d4bd..5707647b 100644 --- a/scripts/notion-heartbeat.js +++ b/scripts/notion-heartbeat.js @@ -30,8 +30,8 @@ var SMTP_USER = process.env.SMTP_USER || ''; var SMTP_PASS = process.env.SMTP_PASS || ''; var NOTION_VERSION = '2022-06-28'; -var HEARTBEAT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes -var MAX_RETRIES = 3; +var HEARTBEAT_TIMEOUT_MS = (parseInt(process.env.HEARTBEAT_TIMEOUT_MINUTES, 10) || 5) * 60 * 1000; +var MAX_RETRIES = parseInt(process.env.MAX_RETRY_COUNT, 10) || 3; var REPO_OWNER = 'qinfendebingshuo'; var REPO_NAME = 'guanghulab'; diff --git a/scripts/push-broadcast-to-github.js b/scripts/push-broadcast-to-github.js index 32af6eb1..41cd164f 100644 --- a/scripts/push-broadcast-to-github.js +++ b/scripts/push-broadcast-to-github.js @@ -18,6 +18,7 @@ var https = require('https'); var fs = require('fs'); +var devSuffixMap = require('./utils/dev-suffix-map'); var GITHUB_TOKEN = process.env.GITHUB_TOKEN || ''; var BROADCAST_ID = process.env.BROADCAST_ID || ''; @@ -94,16 +95,7 @@ async function pushBroadcast() { // 确定开发者 ID(从广播编号提取或使用环境变量) var devId = DEVELOPER_ID; if (!devId) { - // 从 BROADCAST_ID 提取后缀 → 映射到 DEV-XXX - var suffixMatch = BROADCAST_ID.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); - var suffix = suffixMatch ? suffixMatch[1].toUpperCase() : ''; - var suffixMap = { - 'YY': 'DEV-001', 'FM': 'DEV-002', 'YF': 'DEV-003', - 'ZZ': 'DEV-004', 'XCM': 'DEV-005', 'HE': 'DEV-009', - 'JZ': 'DEV-010', 'CCNN': 'DEV-011', 'AW': 'DEV-012', - 'XX': 'DEV-013', 'SY': 'DEV-014', - }; - devId = suffixMap[suffix] || 'UNKNOWN'; + devId = devSuffixMap.getDevIdFromBroadcast(BROADCAST_ID) || 'UNKNOWN'; } // 构建路径和提交信息 diff --git a/scripts/utils/dev-suffix-map.js b/scripts/utils/dev-suffix-map.js new file mode 100644 index 00000000..35248f80 --- /dev/null +++ b/scripts/utils/dev-suffix-map.js @@ -0,0 +1,38 @@ +// scripts/utils/dev-suffix-map.js +// 开发者广播编号后缀 → DEV-ID 映射表 +// +// 广播编号格式: BC-{模块}-{序号}-{后缀} +// 后缀是开发者名字拼音首字母缩写 + +'use strict'; + +// 后缀→开发者编号映射 +var SUFFIX_MAP = { + 'YY': 'DEV-001', // 页页 + 'FM': 'DEV-002', // 肥猫 + 'YF': 'DEV-003', // 燕樊 + 'ZZ': 'DEV-004', // 之之 + 'XCM': 'DEV-005', // 小草莓 + 'HE': 'DEV-009', // 花尔 + 'JZ': 'DEV-010', // 桔子 + 'CCNN': 'DEV-011', // 匆匆那年 + 'AW': 'DEV-012', // Awen + 'XX': 'DEV-013', // 小兴 + 'SY': 'DEV-014', // 时雨 +}; + +/** + * 从广播编号中提取开发者编号 + * @param {string} broadcastId - 广播编号(如 BC-M22-009-AW) + * @returns {string} 开发者编号(如 DEV-012),未找到返回空字符串 + */ +function getDevIdFromBroadcast(broadcastId) { + var suffixMatch = (broadcastId || '').match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); + var suffix = suffixMatch ? suffixMatch[1].toUpperCase() : ''; + return SUFFIX_MAP[suffix] || ''; +} + +module.exports = { + SUFFIX_MAP: SUFFIX_MAP, + getDevIdFromBroadcast: getDevIdFromBroadcast, +}; diff --git a/scripts/verify-modules.js b/scripts/verify-modules.js index 2df4ddf5..24b250e5 100644 --- a/scripts/verify-modules.js +++ b/scripts/verify-modules.js @@ -17,6 +17,7 @@ const fs = require('fs'); const path = require('path'); +const devSuffixMap = require('./utils/dev-suffix-map'); const SYSLOG_CONTENT = process.env.SYSLOG_CONTENT || ''; const BROADCAST_ID = process.env.BROADCAST_ID || ''; @@ -67,25 +68,18 @@ function extractDevId(content, broadcastId) { var devMatch = content.match(/\b(DEV-\d{3})\b/i); if (devMatch) return devMatch[1].toUpperCase(); - // 从广播编号提取开发者后缀(如 BC-M22-009-AW → AW) + // 从广播编号提取开发者编号(使用共享映射表) + var mappedDevId = devSuffixMap.getDevIdFromBroadcast(broadcastId); + if (mappedDevId) return mappedDevId; + + // 兜底:从 dev-status.json 匹配 var suffixMatch = broadcastId.match(/BC-[A-Z0-9]+-\d+-([A-Z]+)/i); var devSuffix = suffixMatch ? suffixMatch[1].toUpperCase() : ''; - // 从 dev-status.json 通过后缀匹配开发者 if (devSuffix) { try { var devStatus = JSON.parse(fs.readFileSync(DEV_STATUS_PATH, 'utf8')); var team = devStatus.team || []; - // 后缀缩写映射表(从 dev-status.json 中名字的拼音首字母) - var suffixMap = { - 'YY': 'DEV-001', 'FM': 'DEV-002', 'YF': 'DEV-003', - 'ZZ': 'DEV-004', 'XCM': 'DEV-005', 'HE': 'DEV-009', - 'JZ': 'DEV-010', 'CCNN': 'DEV-011', 'AW': 'DEV-012', - 'XX': 'DEV-013', 'SY': 'DEV-014', - }; - if (suffixMap[devSuffix]) return suffixMap[devSuffix]; - - // 兜底:尝试从 team 中匹配 waiting 字段里的广播编号 for (var i = 0; i < team.length; i++) { var waiting = team[i].waiting || ''; if (waiting.includes(broadcastId) || waiting.includes(devSuffix)) { From 1479da4e1cfe05cd5e09c086442ad7882653ff5e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:39:06 +0000 Subject: [PATCH 38/46] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=20notion-heartb?= =?UTF-8?q?eat.yml=20=E6=98=BE=E5=BC=8F=E6=9D=83=E9=99=90=E5=A3=B0?= =?UTF-8?q?=E6=98=8E=EF=BC=88CodeQL=E5=AE=89=E5=85=A8=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/notion-heartbeat.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/notion-heartbeat.yml b/.github/workflows/notion-heartbeat.yml index d7b5969a..76653dc0 100644 --- a/.github/workflows/notion-heartbeat.yml +++ b/.github/workflows/notion-heartbeat.yml @@ -20,6 +20,9 @@ jobs: heartbeat: name: 💓 工单心跳检测 runs-on: ubuntu-latest + permissions: + contents: read + actions: write steps: - name: Checkout From e00171e073898ab8a1068f0c3e3373889b6af1be Mon Sep 17 00:00:00 2001 From: Awen <644405261@qq.com> Date: Fri, 13 Mar 2026 14:49:13 +0800 Subject: [PATCH 39/46] =?UTF-8?q?M23=E7=8E=AF=E8=8A=821=E5=85=AC=E5=91=8A?= =?UTF-8?q?=E8=BD=AE=E6=92=AD+=E5=8D=A1=E7=89=87=E4=BA=A4=E4=BA=92+?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8A=A8=E6=80=81=E5=8C=96=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 0 homepage/app.js | 123 +++++++++++++++++++++++++++++-- homepage/index.html | 9 ++- homepage/style.css | 174 ++++++++++++++++++++++++++++++++++++++++++++ index.html | 0 style.css | 0 6 files changed, 300 insertions(+), 6 deletions(-) create mode 100644 app.js create mode 100644 index.html create mode 100644 style.css diff --git a/app.js b/app.js new file mode 100644 index 00000000..e69de29b diff --git a/homepage/app.js b/homepage/app.js index 6d5395d9..f8c1138b 100644 --- a/homepage/app.js +++ b/homepage/app.js @@ -1,8 +1,33 @@ /** * app.js - 光湖首页导航中心 - * M23 环节0 · 模块卡片渲染 + 状态指示 + * M23 环节1 · 公告轮播 + 卡片交互 + 状态动态化 */ +// 公告轮播数据(Mock数据,未来对接M22真实API) +const announcements = [ + { + id: 1, + title: "光湖实验室v1.0开发中", + content: "全团队并行推进,多模块同步建设", + date: "2026-03-13", + type: "update" + }, + { + id: 2, + title: "模块进度总览", + content: "4个模块在线 · 2个建设中", + date: "2026-03-13", + type: "status" + }, + { + id: 3, + title: "欢迎新开发者", + content: "零点原核频道持续壮大", + date: "2026-03-13", + type: "welcome" + } +]; + // 模块卡片数据 const moduleCards = [ { @@ -51,10 +76,16 @@ const moduleCards = [ // 首页应用对象 window.HomepageApp = { + currentAnnouncementIndex: 0, + carouselInterval: null, + init() { this.renderCards(); + this.renderCarousel(); + this.startCarousel(); + this.bindEvents(); this.updateStatusBar(); - console.log('✅ 首页初始化完成'); + console.log('✅ 首页初始化完成 · 15连胜版'); }, // 渲染卡片 @@ -63,20 +94,102 @@ window.HomepageApp = { if (!grid) return; const cardsHTML = moduleCards.map(card => ` -
+
${card.icon}
${card.name} ${card.status === 'online' ? '在线' : '建设中'}
- 进入模块 → + 进入模块 →
`).join(''); grid.innerHTML = cardsHTML; }, - // 更新状态栏(后续可对接真实API) + // 渲染轮播 + renderCarousel() { + const carousel = document.getElementById('announcementCarousel'); + if (!carousel) return; + + const announcement = announcements[this.currentAnnouncementIndex]; + carousel.innerHTML = ` + + `; + }, + + // 启动轮播(自动4秒切换) + startCarousel() { + if (this.carouselInterval) clearInterval(this.carouselInterval); + this.carouselInterval = setInterval(() => { + this.nextAnnouncement(); + }, 4000); + console.log('🔄 轮播已启动,4秒自动切换'); + }, + + // 下一条公告 + nextAnnouncement() { + this.currentAnnouncementIndex = (this.currentAnnouncementIndex + 1) % announcements.length; + this.renderCarousel(); + }, + + // 上一条公告 + prevAnnouncement() { + this.currentAnnouncementIndex = (this.currentAnnouncementIndex - 1 + announcements.length) % announcements.length; + this.renderCarousel(); + }, + + // 模块跳转 + navigateTo(moduleId) { + const module = moduleCards.find(m => m.id === moduleId); + if (module) { + console.log(`🧭 跳转到模块: ${module.name} | 路径: ${module.path}`); + } else { + console.log(`⚠️ 未找到模块: ${moduleId}`); + } + }, + + // 绑定事件 + bindEvents() { + // 卡片点击事件 + document.querySelectorAll('.card').forEach(card => { + card.addEventListener('click', (e) => { + const moduleId = card.dataset.moduleId; + const modulePath = card.dataset.modulePath; + console.log(`🖱️ 点击卡片: ${moduleId} | 路径: ${modulePath}`); + this.navigateTo(moduleId); + // 未来这里会实现实际跳转:window.location.href = modulePath; + }); + }); + + // 轮播箭头点击 + document.getElementById('carouselPrev')?.addEventListener('click', () => { + console.log('◀️ 点击左箭头'); + this.prevAnnouncement(); + }); + + document.getElementById('carouselNext')?.addEventListener('click', () => { + console.log('▶️ 点击右箭头'); + this.nextAnnouncement(); + }); + + // 键盘事件 + document.addEventListener('keydown', (e) => { + if (e.key === 'ArrowLeft') { + console.log('⌨️ 键盘左箭头'); + this.prevAnnouncement(); + } else if (e.key === 'ArrowRight') { + console.log('⌨️ 键盘右箭头'); + this.nextAnnouncement(); + } + }); + }, + + // 更新状态栏 updateStatusBar() { const onlineCount = moduleCards.filter(c => c.status === 'online').length; const totalCount = moduleCards.length; diff --git a/homepage/index.html b/homepage/index.html index dc19cd0c..90dcded3 100644 --- a/homepage/index.html +++ b/homepage/index.html @@ -14,7 +14,14 @@

探索未来之域 · 零点原核频道

进入系统 - + +

核心模块

diff --git a/homepage/style.css b/homepage/style.css index dd38070f..3668c249 100644 --- a/homepage/style.css +++ b/homepage/style.css @@ -105,6 +105,7 @@ body { transition: all 0.3s ease; animation: cardFadeIn 0.5s ease forwards; opacity: 0; + cursor: pointer; } .card:hover { @@ -260,4 +261,177 @@ body { opacity: 1; transform: translateY(0); } +} + +/* ===== 公告轮播区样式 ===== */ +.carousel-container { + position: relative; + background: var(--bg-secondary); + border-radius: 2rem; + padding: 2rem; + margin: 2rem 0 3rem; + border: 1px solid var(--border); + animation: fadeIn 0.5s ease; +} + +.carousel { + min-height: 100px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; +} + +.carousel-item { + width: 100%; +} + +.carousel-title { + font-size: 1.3rem; + color: var(--accent); + margin-bottom: 0.5rem; +} + +.carousel-content { + color: var(--text-secondary); + margin-bottom: 0.5rem; + line-height: 1.6; +} + +.carousel-date { + font-size: 0.8rem; + color: var(--text-tertiary); +} + +.carousel-arrow { + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 40px; + height: 40px; + border-radius: 50%; + background: var(--bg-card); + border: 1px solid var(--border); + color: var(--text-primary); + font-size: 1.2rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; +} + +.carousel-arrow:hover { + background: var(--accent); + color: white; + border-color: var(--accent); +} + +.carousel-arrow.left { + left: -20px; +} + +.carousel-arrow.right { + right: -20px; +} + +/* ===== 卡片悬停效果增强 ===== */ +.card { + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.card:hover { + transform: translateY(-8px) scale(1.02); + border-color: var(--accent); + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4); +} + +/* ===== 状态标签动态化 ===== */ +.card-status.online { + animation: pulse 2s infinite; +} + +.card-status.building { + animation: flicker 1.5s infinite; +} + +@keyframes pulse { + 0% { + box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); + } + 70% { + box-shadow: 0 0 0 10px rgba(16, 185, 129, 0); + } + 100% { + box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); + } +} + +@keyframes flicker { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.6; + box-shadow: 0 0 10px rgba(245, 158, 11, 0.5); + } +} + +/* ===== 响应式调整 ===== */ +@media (max-width: 767px) { + .carousel-container { + padding: 1.5rem; + } + + .carousel-arrow.left { + left: -10px; + } + + .carousel-arrow.right { + right: -10px; + } +} + +/* ===== 暴力增强版(确保生效)===== */ +.card { + cursor: pointer !important; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; +} + +.card:hover { + transform: translateY(-10px) scale(1.05) !important; + border-color: var(--accent) !important; + box-shadow: 0 30px 50px rgba(59, 130, 246, 0.5) !important; +} + +.card-status.online { + animation: pulse 1.5s infinite !important; +} + +.card-status.building { + animation: flicker 1s infinite !important; +} + +@keyframes pulse { + 0% { + box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); + } + 50% { + box-shadow: 0 0 20px 10px rgba(16, 185, 129, 0.3); + } + 100% { + box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); + } +} + +@keyframes flicker { + 0%, 100% { + opacity: 1; + text-shadow: 0 0 5px rgba(245, 158, 11, 0.5); + } + 50% { + opacity: 0.5; + text-shadow: 0 0 15px rgba(245, 158, 11, 0.8); + } } \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..e69de29b diff --git a/style.css b/style.css new file mode 100644 index 00000000..e69de29b From 8935d01e28f77452ed33e32608228f7afa11e31e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:50:45 +0000 Subject: [PATCH 40/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 51988395..df1ceb3e 100644 --- a/README.md +++ b/README.md @@ -92,12 +92,8 @@ | 时间 | 检查项 | 状态 | |------|--------|------| -| 03-13 14:04 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | +| 03-13 14:50 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | | 03-13 14:03 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | -| 03-13 14:03 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 | -| 03-13 14:03 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | -| 03-13 13:56 | 🔵 铸渊 · Bridge E · GitHub Changes → Notion · action_required | Copilot | -| 03-13 11:54 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | @@ -107,6 +103,10 @@ | 03-10 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 3 个问题 · 自动修复 0 项 | 铸渊PSP巡检 | | 03-10 08:00 | 🔵 CI 构建 失败 | GitHub Actions | | 03-09 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | +| 03-09 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | +| 03-08 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | +| 03-07 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 1 个问题 · 自动修复 0 项 | 铸渊PSP巡检 | +| 03-06 00:07 | ✅ CI 构建 通过 | 冰朔 | ### 🤖 铸渊自动提醒 @@ -128,9 +128,12 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| -| 03-13 14:03 | 冰朔 | `—/` | ✅ 上传成功 | -| 03-13 14:03 | Copilot | `—/` | ✅ 上传成功 | -| 03-13 13:56 | Copilot | `—/` | 🔵 已更新 | +| 03-13 14:50 | WENZHUOXI | `—/` | ✅ 上传成功 | +| 03-13 14:39 | Copilot | `—/` | 🔵 已更新 | +| 03-13 14:37 | Copilot | `—/` | 🔵 已更新 | +| 03-13 14:33 | Copilot | `—/` | 🔵 已更新 | +| 03-13 14:08 | Copilot | `—/` | 🔵 已更新 | +| 03-13 14:05 | Copilot | `—/` | 🔵 已更新 | ### 🤖 铸渊自动提醒 · 合作者 From 95b862bc8e2bd639a711de6e8558862be476b766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 06:50:49 +0000 Subject: [PATCH 41/46] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-13T06:50?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 2 +- .github/brain/repo-snapshot.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index 8ec2133c..8f1a2589 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,7 +1,7 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-13T06:03:44.081Z", + "generated_at": "2026-03-13T06:50:49.508Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index 4fd16315..3b08d587 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-13 14:03 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-13 14:50 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -13,7 +13,7 @@ | 脚本 | 33 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 7/21 (33%) | -| 快照生成时间 | 2026-03-13 14:03 CST | +| 快照生成时间 | 2026-03-13 14:50 CST | --- From 827ad3e12f6df34f3725b005d2f02b80b802116e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:52:15 +0000 Subject: [PATCH 42/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index df1ceb3e..7332df9a 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,10 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 14:51 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | WENZHUOXI | +| 03-13 14:50 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | +| 03-13 14:50 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 14:50 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | -| 03-13 14:03 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | @@ -105,8 +107,6 @@ | 03-09 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-09 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-08 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | -| 03-07 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 1 个问题 · 自动修复 0 项 | 铸渊PSP巡检 | -| 03-06 00:07 | ✅ CI 构建 通过 | 冰朔 | ### 🤖 铸渊自动提醒 @@ -128,12 +128,9 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| +| 03-13 14:52 | Copilot | `—/` | ✅ 上传成功 | | 03-13 14:50 | WENZHUOXI | `—/` | ✅ 上传成功 | -| 03-13 14:39 | Copilot | `—/` | 🔵 已更新 | -| 03-13 14:37 | Copilot | `—/` | 🔵 已更新 | | 03-13 14:33 | Copilot | `—/` | 🔵 已更新 | -| 03-13 14:08 | Copilot | `—/` | 🔵 已更新 | -| 03-13 14:05 | Copilot | `—/` | 🔵 已更新 | ### 🤖 铸渊自动提醒 · 合作者 From 3b399fbe0a33b4253a201a86049fae4d6dba755f Mon Sep 17 00:00:00 2001 From: bingshuo-neural-system Date: Fri, 13 Mar 2026 06:52:25 +0000 Subject: [PATCH 43/46] =?UTF-8?q?=F0=9F=A7=A0=20=E5=86=B0=E6=9C=94?= =?UTF-8?q?=E4=B8=BB=E6=8E=A7=E7=A5=9E=E7=BB=8F=E7=B3=BB=E7=BB=9F=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=BC=96=E8=AF=91=202026-03-13T06:52:25Z?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/bingshuo-issues-index.json | 2 +- .github/brain/bingshuo-master-brain.md | 8 ++++---- .github/brain/bingshuo-system-health.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/brain/bingshuo-issues-index.json b/.github/brain/bingshuo-issues-index.json index 6d37d9af..eded71d9 100644 --- a/.github/brain/bingshuo-issues-index.json +++ b/.github/brain/bingshuo-issues-index.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控问题索引库 — 记录已知问题、根因与排查路由", - "updated_at": "2026-03-13T06:03:28.751Z", + "updated_at": "2026-03-13T06:52:24.833Z", "issues": [ { "id": "BS-001", diff --git a/.github/brain/bingshuo-master-brain.md b/.github/brain/bingshuo-master-brain.md index 80f1b9bc..2f10a3cf 100644 --- a/.github/brain/bingshuo-master-brain.md +++ b/.github/brain/bingshuo-master-brain.md @@ -1,7 +1,7 @@ # 冰朔主控神经系统 · 核心主控大脑 v1.0 > 本文件为冰朔主控神经系统的总控脑文件。 -> 最后编译时间:2026-03-13T06:03:28.752Z +> 最后编译时间:2026-03-13T06:52:24.834Z --- @@ -56,7 +56,7 @@ ### 仓库统计 - 功能模块:10 个 -- Workflow:37 个 +- Workflow:40 个 --- @@ -85,7 +85,7 @@ > 本区块由 master-brain-compiler 自动编译。 -- **编译时间**:2026-03-13T06:03:28.752Z +- **编译时间**:2026-03-13T06:52:24.834Z - **脑文件规则版本**:v3.0 - **脑文件完整性**:✅ 完整 @@ -107,7 +107,7 @@ |--------|------|------| | 🟡 brain_consistency | yellow | 主仓库脑文件完整,但与 persona-studio 脑文件的同步状态待验证 | | 🟢 deployment_health | green | deploy-to-server.yml 与 deploy-pages.yml 均存在 | -| 🟢 workflow_health | green | 37 个 workflow 已注册 | +| 🟢 workflow_health | green | 40 个 workflow 已注册 | | 🟡 routing_health | yellow | HLI 接口覆盖率 33.3%(7/21) | | 🟢 docs_entry_health | green | docs/index.html 存在 | | 🟡 persona_studio_health | yellow | 前后端结构存在,端到端对话链路待验证 | diff --git a/.github/brain/bingshuo-system-health.json b/.github/brain/bingshuo-system-health.json index cb8e4669..a1ee0628 100644 --- a/.github/brain/bingshuo-system-health.json +++ b/.github/brain/bingshuo-system-health.json @@ -1,7 +1,7 @@ { "version": "1.0", "description": "冰朔主控系统健康状态", - "updated_at": "2026-03-13T06:03:28.751Z", + "updated_at": "2026-03-13T06:52:24.833Z", "health": { "brain_consistency": { "status": "yellow", @@ -13,7 +13,7 @@ }, "workflow_health": { "status": "green", - "detail": "37 个 workflow 已注册" + "detail": "40 个 workflow 已注册" }, "routing_health": { "status": "yellow", From 7a9c6a1a70caf20c73732af31a223fb842122f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Fri, 13 Mar 2026 06:52:40 +0000 Subject: [PATCH 44/46] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-13T06:52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 75 +++++++++++++++++++++++++++++++--- .github/brain/repo-snapshot.md | 21 +++++++--- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index 8f1a2589..82975a73 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,14 +1,14 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-13T06:50:49.508Z", + "generated_at": "2026-03-13T06:52:39.931Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { "zones": 13, "total_modules": 10, - "total_workflows": 37, - "total_scripts": 33, + "total_workflows": 40, + "total_scripts": 39, "total_dev_nodes": 8, "hli_interfaces": 21, "hli_implemented": 7, @@ -266,6 +266,13 @@ "pull_request" ] }, + { + "file": "notion-callback-pipeline.yml", + "name": "Notion Callback Pipeline", + "triggers": [ + "unknown" + ] + }, { "file": "notion-connectivity-test.yml", "name": "铸渊 · Notion 连通性测试", @@ -273,6 +280,14 @@ "manual" ] }, + { + "file": "notion-heartbeat.yml", + "name": "Notion Heartbeat Monitor", + "triggers": [ + "schedule(*/5 * * * *)", + "manual" + ] + }, { "file": "notion-poll.yml", "name": "铸渊 · Notion 工单轮询", @@ -281,6 +296,13 @@ "manual" ] }, + { + "file": "persona-invoke.yml", + "name": "Persona Invoke Endpoint", + "triggers": [ + "manual" + ] + }, { "file": "process-notion-orders.yml", "name": "Process Notion Work Orders", @@ -449,7 +471,7 @@ ] } ], - "item_count": 37 + "item_count": 40 }, { "zone_id": "SCRIPTS", @@ -478,6 +500,9 @@ { "file": "contract-check.js" }, + { + "file": "create-standardized-ticket.js" + }, { "file": "cross-repo-sync.js" }, @@ -499,6 +524,9 @@ { "file": "generate-session-summary.js" }, + { + "file": "invoke-persona.js" + }, { "file": "notify-module-received.js" }, @@ -508,6 +536,9 @@ { "file": "notion-connectivity-test.js" }, + { + "file": "notion-heartbeat.js" + }, { "file": "notion-signal-bridge.js" }, @@ -520,6 +551,9 @@ { "file": "psp-inspection.js" }, + { + "file": "push-broadcast-to-github.js" + }, { "file": "push-broadcast.js" }, @@ -550,6 +584,12 @@ { "file": "update-readme-bulletin.js" }, + { + "file": "utils" + }, + { + "file": "verify-modules.js" + }, { "file": "wake-persona.js" }, @@ -566,7 +606,7 @@ "file": "zhuyuan-module-protocol.js" } ], - "item_count": 33 + "item_count": 39 }, { "zone_id": "SRC", @@ -1330,13 +1370,23 @@ "hli-contract-check": [ "WORKFLOWS::hli-contract-check.yml" ], + "notion-callback-pipeline": [ + "WORKFLOWS::notion-callback-pipeline.yml" + ], "notion-connectivity-test": [ "WORKFLOWS::notion-connectivity-test.yml", "SCRIPTS::notion-connectivity-test.js" ], + "notion-heartbeat": [ + "WORKFLOWS::notion-heartbeat.yml", + "SCRIPTS::notion-heartbeat.js" + ], "notion-poll": [ "WORKFLOWS::notion-poll.yml" ], + "persona-invoke": [ + "WORKFLOWS::persona-invoke.yml" + ], "process-notion-orders": [ "WORKFLOWS::process-notion-orders.yml" ], @@ -1438,6 +1488,9 @@ "contract-check": [ "SCRIPTS::contract-check.js" ], + "create-standardized-ticket": [ + "SCRIPTS::create-standardized-ticket.js" + ], "cross-repo-sync": [ "SCRIPTS::cross-repo-sync.js" ], @@ -1453,6 +1506,9 @@ "generate-session-summary": [ "SCRIPTS::generate-session-summary.js" ], + "invoke-persona": [ + "SCRIPTS::invoke-persona.js" + ], "notify-module-received": [ "SCRIPTS::notify-module-received.js" ], @@ -1471,6 +1527,9 @@ "psp-inspection": [ "SCRIPTS::psp-inspection.js" ], + "push-broadcast-to-github": [ + "SCRIPTS::push-broadcast-to-github.js" + ], "route-align-check": [ "SCRIPTS::route-align-check.js" ], @@ -1489,6 +1548,12 @@ "update-memory": [ "SCRIPTS::update-memory.js" ], + "utils": [ + "SCRIPTS::utils" + ], + "verify-modules": [ + "SCRIPTS::verify-modules.js" + ], "wake-persona": [ "SCRIPTS::wake-persona.js" ], diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index 3b08d587..d67e857d 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-13 14:50 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-13 14:52 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -9,11 +9,11 @@ |------|------| | 区域总数 | 13 个区域 | | 功能模块 | 10 个 (m01~m18) | -| 工作流 | 37 个 GitHub Actions | -| 脚本 | 33 个执行脚本 | +| 工作流 | 40 个 GitHub Actions | +| 脚本 | 39 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 7/21 (33%) | -| 快照生成时间 | 2026-03-13 14:50 CST | +| 快照生成时间 | 2026-03-13 14:52 CST | --- @@ -30,12 +30,12 @@ **关键词**: persona · identity · dev-status · 人格 · 开发者状态 ### ⚡ 自动化工作流(WORKFLOWS) -**路径**: `.github/workflows` · **数量**: 37 项 +**路径**: `.github/workflows` · **数量**: 40 项 **描述**: 所有 GitHub Actions 工作流定义 **关键词**: workflow · actions · ci · automation · 工作流 · 自动化 ### 🔧 执行脚本库(SCRIPTS) -**路径**: `scripts` · **数量**: 33 项 +**路径**: `scripts` · **数量**: 39 项 **描述**: 铸渊所有执行手脚 · 自动化脚本 **关键词**: script · node · js · 脚本 · 执行 · runner @@ -103,8 +103,11 @@ | `esp-signal-processor.yml` | 铸渊 · ESP 邮件信号处理器(已暂停) | schedule(*/30 * * * *), manual | | `generate-module-doc.yml` | 铸渊 · 光湖纪元 模块文档自动生成 | push, manual | | `hli-contract-check.yml` | HLI Contract Check | push, pull_request | +| `notion-callback-pipeline.yml` | Notion Callback Pipeline | unknown | | `notion-connectivity-test.yml` | 铸渊 · Notion 连通性测试 | manual | +| `notion-heartbeat.yml` | Notion Heartbeat Monitor | schedule(*/5 * * * *), manual | | `notion-poll.yml` | 铸渊 · Notion 工单轮询 | schedule(*/15 * * * *), manual | +| `persona-invoke.yml` | Persona Invoke Endpoint | manual | | `process-notion-orders.yml` | Process Notion Work Orders | push, manual | | `ps-on-build.yml` | "🌊 Persona Studio · 代码生成" | manual | | `ps-on-chat.yml` | "🌊 Persona Studio · 对话处理" | manual | @@ -136,6 +139,7 @@ - `scripts/bingshuo-neural-sync.js` - `scripts/brain-bridge-sync.js` - `scripts/contract-check.js` +- `scripts/create-standardized-ticket.js` - `scripts/cross-repo-sync.js` - `scripts/daily-check.js` - `scripts/distribute-broadcasts.js` @@ -143,13 +147,16 @@ - `scripts/generate-module-doc.js` - `scripts/generate-repo-map.js` - `scripts/generate-session-summary.js` +- `scripts/invoke-persona.js` - `scripts/notify-module-received.js` - `scripts/notion-bridge.js` - `scripts/notion-connectivity-test.js` +- `scripts/notion-heartbeat.js` - `scripts/notion-signal-bridge.js` - `scripts/process-broadcasts.js` - `scripts/process-syslog.js` - `scripts/psp-inspection.js` +- `scripts/push-broadcast-to-github.js` - `scripts/push-broadcast.js` - `scripts/receive-syslog.js` - `scripts/route-align-check.js` @@ -160,6 +167,8 @@ - `scripts/update-brain.js` - `scripts/update-memory.js` - `scripts/update-readme-bulletin.js` +- `scripts/utils` +- `scripts/verify-modules.js` - `scripts/wake-persona.js` - `scripts/zhuyuan-daily-agent.js` - `scripts/zhuyuan-daily-selfcheck.js` From b50a3721a1d5bd272dec21fe121901e0b218df2e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:54:05 +0000 Subject: [PATCH 45/46] =?UTF-8?q?=F0=9F=93=A2=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B3=BB=E7=BB=9F=E5=85=AC=E5=91=8A=E5=8C=BA?= =?UTF-8?q?=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7332df9a..6e1b368c 100644 --- a/README.md +++ b/README.md @@ -92,29 +92,31 @@ | 时间 | 检查项 | 状态 | |------|--------|------| +| 03-13 14:53 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | 冰朔 | +| 03-13 14:52 | ❌ 📢 更新系统公告区 · 失败 | 冰朔 | +| 03-13 14:52 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | +| 03-13 14:52 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | 冰朔 | +| 03-13 14:52 | ⏹️ 📢 更新系统公告区 · cancelled | WENZHUOXI | | 03-13 14:51 | ✅ 🚀 铸渊 CD · 自动部署到 guanghulab.com · 成功 | WENZHUOXI | | 03-13 14:50 | ✅ 📢 更新系统公告区 · 成功 | WENZHUOXI | -| 03-13 14:50 | 🔧 系统更新: `.github/` | 铸渊 (ZhùYuān) | | 03-13 14:50 | ✅ 铸渊 · Bridge E · GitHub Changes → Notion · 成功 | WENZHUOXI | +| 03-13 14:37 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) | | 03-13 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-12 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-12 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | | 03-11 16:55 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-10 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | | 03-10 08:00 | 🧠 核心大脑升级 v3.0 · 壳-核分离架构 · 前端壳(UI/IO) + 后端脑(prompt/routing/memory/context) · BRAIN域4接口上线 · 覆盖率 7/21 (33.3%) | 铸渊(冰朔指令) | -| 03-10 08:00 | ⚠️ 铸渊 PSP 巡检完成 · 发现 3 个问题 · 自动修复 0 项 | 铸渊PSP巡检 | -| 03-10 08:00 | 🔵 CI 构建 失败 | GitHub Actions | -| 03-09 16:56 | ✅ 每日巡检 ✅ 通过 | 冰朔 | -| 03-09 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | -| 03-08 08:00 | ✅ 铸渊 PSP 巡检通过 · 全部检查项 ✅ | 铸渊PSP巡检 | ### 🤖 铸渊自动提醒 -> 🟢 **今日无需冰朔手动干预** · 系统一切正常 +> 🔴 **需要冰朔手动干预!** > -> 🗓️ 2026-03-13 · 铸渊自动检测 +> - ❌ 📢 更新系统公告区 · 失败 +> +> 🗓️ 2026-03-13 · 铸渊已发送邮件提醒 --- @@ -128,9 +130,9 @@ | 时间 | 合作者 | 模块 | 状态 | |------|--------|------|------| +| 03-13 14:52 | 冰朔 | `—/` | ✅ 上传成功 | | 03-13 14:52 | Copilot | `—/` | ✅ 上传成功 | | 03-13 14:50 | WENZHUOXI | `—/` | ✅ 上传成功 | -| 03-13 14:33 | Copilot | `—/` | 🔵 已更新 | ### 🤖 铸渊自动提醒 · 合作者 From f749dc962e89987379533921e77892d87cebcc05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=5Bbot=5D?= Date: Fri, 13 Mar 2026 08:53:32 +0000 Subject: [PATCH 46/46] =?UTF-8?q?=F0=9F=A7=A0=20memory:=20=E6=AF=8F?= =?UTF-8?q?=E6=97=A5=E8=87=AA=E6=A3=80=E8=AE=B0=E5=BD=95=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/memory.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/brain/memory.json b/.github/brain/memory.json index cdc4885d..e07d7cd6 100644 --- a/.github/brain/memory.json +++ b/.github/brain/memory.json @@ -1,7 +1,7 @@ { "identity": "铸渊(Zhùyuān)· GitHub 代码守护人格体", "rules_version": "v3.0", - "last_updated": "2026-03-13T03:31:06.282Z", + "last_updated": "2026-03-13T08:53:32.764Z", "wake_protocol_version": "v3.0", "brain_version": "v3.0", "architecture": { @@ -185,6 +185,14 @@ "actor": "qinfendebingshuo", "ref": "refs/heads/main", "run_id": "22993977564" + }, + { + "timestamp": "2026-03-13T08:53:32.764Z", + "type": "daily_check", + "result": "passed", + "actor": "qinfendebingshuo", + "ref": "refs/heads/main", + "run_id": "23043373769" } ] -} \ No newline at end of file +}