From 188db4f47719ffc4e428373edd344390547464a7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Mar 2026 14:32:02 +0000
Subject: [PATCH 1/3] Initial plan
From 2874d46c320ea2c97c2132384930ee81f2256295 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Mar 2026 14:37:33 +0000
Subject: [PATCH 2/3] =?UTF-8?q?feat:=20HoloLake=20Era=20=E6=93=8D=E4=BD=9C?=
=?UTF-8?q?=E7=B3=BB=E7=BB=9F=E9=83=A8=E7=BD=B2=E6=A8=A1=E5=9D=97=20?=
=?UTF-8?q?=E2=80=94=20=E8=87=AA=E5=8A=A8=E6=96=87=E6=A1=A3=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E7=B3=BB=E7=BB=9F?=
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/generate-module-doc.yml | 53 ++++
docs/HoloLake-Era-OS-Modules.md | 333 ++++++++++++++++++++++
scripts/generate-module-doc.js | 286 +++++++++++++++++++
3 files changed, 672 insertions(+)
create mode 100644 .github/workflows/generate-module-doc.yml
create mode 100644 docs/HoloLake-Era-OS-Modules.md
create mode 100644 scripts/generate-module-doc.js
diff --git a/.github/workflows/generate-module-doc.yml b/.github/workflows/generate-module-doc.yml
new file mode 100644
index 00000000..96dc1ba2
--- /dev/null
+++ b/.github/workflows/generate-module-doc.yml
@@ -0,0 +1,53 @@
+name: 铸渊 · HoloLake Era 模块文档自动生成
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - 'm01-login/**'
+ - 'm03-personality/**'
+ - 'm05-user-center/**'
+ - 'm06-ticket/**'
+ - 'm07-dialogue-ui/**'
+ - 'm10-cloud/**'
+ - 'm11-module/**'
+ - 'm12-kanban/**'
+ - 'm15-cloud-drive/**'
+ - 'dingtalk-bot/**'
+ - 'backend-integration/**'
+ - 'status-board/**'
+ - 'scripts/generate-module-doc.js'
+ workflow_dispatch:
+
+jobs:
+ generate-doc:
+ name: 📋 生成部署模块总文档
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: main
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: 生成 HoloLake Era 模块文档
+ run: node scripts/generate-module-doc.js
+
+ - name: 提交更新文档
+ run: |
+ git config user.name "铸渊 (ZhùYuān)"
+ git config user.email "zhuyuan@guanghulab.com"
+ git add docs/HoloLake-Era-OS-Modules.md
+ if git diff --cached --quiet; then
+ echo "📋 文档无变化,跳过提交"
+ else
+ git commit -m "📋 自动更新 HoloLake Era 模块文档 · $(date -u +%Y-%m-%d\ %H:%M\ UTC)"
+ git push
+ fi
diff --git a/docs/HoloLake-Era-OS-Modules.md b/docs/HoloLake-Era-OS-Modules.md
new file mode 100644
index 00000000..93ccc528
--- /dev/null
+++ b/docs/HoloLake-Era-OS-Modules.md
@@ -0,0 +1,333 @@
+# HoloLake Era 操作系统部署模块
+
+> 📋 **自动生成文档** · 铸渊(ZhùYuān)维护 · 最后更新:2026-03-06 14:36 UTC
+>
+> 本文档由 GitHub Actions 自动触发生成,每当合作者上传/更新模块时自动刷新。
+> 按合作者编号(DEV-XXX)整理所有已上传模块。
+
+---
+
+## 📑 目录
+
+- [DEV-001 · 🖥️ 页页](#dev001--%E9%A1%B5%E9%A1%B5) (1 个模块)
+- [DEV-002 · 🦁 肥猫](#dev002--%E8%82%A5%E7%8C%AB) (2 个模块)
+- [DEV-003 · 🌸 燕樊](#dev003--%E7%87%95%E6%A8%8A) (3 个模块)
+- [DEV-004 · 🤖 之之](#dev004--%E4%B9%8B%E4%B9%8B) (1 个模块)
+- [DEV-005 · 🍓 小草莓](#dev005--%E5%B0%8F%E8%8D%89%E8%8E%93) (2 个模块)
+- [DEV-009 · 🌺 花尔](#dev009--%E8%8A%B1%E5%B0%94) (1 个模块)
+- [DEV-010 · 🍊 桔子](#dev010--%E6%A1%94%E5%AD%90) (2 个模块)
+- [DEV-011 · 🌙 匆匆那年](#dev011--%E5%8C%86%E5%8C%86%E9%82%A3%E5%B9%B4) (待上传)
+
+---
+
+## DEV-001 · 🖥️ 页页
+
+**角色:** 后端工程师
+
+### 📦 后端集成中间层
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `backend-integration/` |
+| **负责人** | 页页 |
+| **状态** | 进行中 |
+| **技术栈** | Node.js |
+| **依赖模块** | 所有前端模块 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+backend-integration/
+ README.md
+```
+
+---
+
+## DEV-002 · 🦁 肥猫
+
+**角色:** 光湖团队总控
+
+### 📦 M01 用户登录界面
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m01-login/` |
+| **负责人** | 肥猫 |
+| **状态** | 进行中 |
+| **技术栈** | 待定 |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m01-login/
+ README.md
+```
+
+### 📦 M03 人格系统
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m03-personality/` |
+| **负责人** | 肥猫 |
+| **状态** | 进行中 |
+| **技术栈** | 待定 |
+| **依赖模块** | M01 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m03-personality/
+ README.md
+```
+
+---
+
+## DEV-003 · 🌸 燕樊
+
+**角色:** 前端工程师
+
+### 📦 M07 对话UI
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m07-dialogue-ui/` |
+| **负责人** | 燕樊 |
+| **状态** | 进行中 |
+| **技术栈** | 待定 |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m07-dialogue-ui/
+ README.md
+ index.html
+ script.js
+ style.css
+```
+
+### 📦 M10 云盘系统
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m10-cloud/` |
+| **负责人** | 燕樊 |
+| **状态** | 等待SYSLOG |
+| **技术栈** | 待定 |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m10-cloud/
+ README.md
+ help.css
+ help.html
+ help.js
+```
+
+### 📦 m15-cloud-drive
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m15-cloud-drive/` |
+| **负责人** | 燕樊 |
+| **状态** | 未知 |
+| **技术栈** | 待定 |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m15-cloud-drive/
+ cloud-drive-style.css
+ cloud-drive.html
+ cloud-drive.js
+```
+
+---
+
+## DEV-004 · 🤖 之之
+
+**角色:** 机器人工程师
+
+### 📦 钉钉机器人
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `dingtalk-bot/` |
+| **负责人** | 之之 |
+| **状态** | 环节0已完成 |
+| **技术栈** | Node.js + Express |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+dingtalk-bot/
+ README.md
+```
+
+---
+
+## DEV-005 · 🍓 小草莓
+
+**角色:** 看板工程师
+
+### 📦 M12 状态看板
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m12-kanban/` |
+| **负责人** | 小草莓 |
+| **状态** | 进行中 |
+| **技术栈** | 待定 |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m12-kanban/
+ README.md
+```
+
+### 📦 status-board
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `status-board/` |
+| **负责人** | 小草莓 |
+| **状态** | 未知 |
+| **技术栈** | 待定 |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ✅ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+status-board/
+ api-config.js
+ api.js
+ index.html
+ mock-ws-server.js
+ package-lock.json
+ package.json
+ render.js
+ style.css
+ ws-client.js
+```
+
+---
+
+## DEV-009 · 🌺 花尔
+
+**角色:** 前端工程师
+
+### 📦 M05 用户中心界面
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m05-user-center/` |
+| **负责人** | 花尔 |
+| **状态** | 环节0 |
+| **技术栈** | HTML/CSS/JS |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m05-user-center/
+ README.md
+ index.html
+ script.js
+ style.css
+```
+
+---
+
+## DEV-010 · 🍊 桔子
+
+**角色:** 光湖主控
+
+### 📦 M06 工单管理界面
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m06-ticket/` |
+| **负责人** | 桔子 |
+| **状态** | 环节0 |
+| **技术栈** | HTML/CSS/JS |
+| **依赖模块** | 无 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m06-ticket/
+ README.md
+```
+
+### 📦 M11 工单管理模块
+
+| 字段 | 内容 |
+|------|------|
+| **目录** | `m11-module/` |
+| **负责人** | 桔子 |
+| **状态** | 进行中 |
+| **技术栈** | 待定 |
+| **依赖模块** | M06 |
+
+**结构检查:** ⚠️ src/ · ⚠️ package.json · ⚠️ SYSLOG.md
+
+**已上传文件:**
+
+```
+m11-module/
+ README.md
+```
+
+---
+
+## DEV-011 · 🌙 匆匆那年
+
+**角色:** 开发者
+
+> 🕐 暂无分配模块,待安排。
+
+---
+
+## 📊 部署统计
+
+| 项目 | 数量 |
+|------|------|
+| 合作者总数 | 8 |
+| 计划模块数 | 12 |
+| 已上传模块数 | 12 |
+| 待上传模块数 | 0 |
+| 上传完成率 | 100% |
+| 文档更新时间 | 2026-03-06 14:36 UTC |
+
+---
+
+*由 铸渊(ZhùYuān)· GitHub Copilot Agent 自动生成 · 仓库:guanghulab*
diff --git a/scripts/generate-module-doc.js b/scripts/generate-module-doc.js
new file mode 100644
index 00000000..e96c5611
--- /dev/null
+++ b/scripts/generate-module-doc.js
@@ -0,0 +1,286 @@
+// scripts/generate-module-doc.js
+// 铸渊 · HoloLake Era 操作系统部署模块文档生成器
+// 检测所有合作者上传的模块目录 → 按 DEV 编号整理 → 生成总文档
+
+const fs = require('fs');
+const path = require('path');
+
+const OUTPUT_FILE = 'docs/HoloLake-Era-OS-Modules.md';
+
+// ========== 合作者编号 → 模块目录 路由映射表 ==========
+// 新增合作者或模块时,在此表维护即可
+const COLLABORATOR_MODULES = [
+ {
+ devId: 'DEV-001',
+ name: '页页',
+ emoji: '🖥️',
+ role: '后端工程师',
+ dirs: ['backend-integration'],
+ },
+ {
+ devId: 'DEV-002',
+ name: '肥猫',
+ emoji: '🦁',
+ role: '光湖团队总控',
+ dirs: ['m01-login', 'm03-personality'],
+ },
+ {
+ devId: 'DEV-003',
+ name: '燕樊',
+ emoji: '🌸',
+ role: '前端工程师',
+ dirs: ['m07-dialogue-ui', 'm10-cloud', 'm15-cloud-drive'],
+ },
+ {
+ devId: 'DEV-004',
+ name: '之之',
+ emoji: '🤖',
+ role: '机器人工程师',
+ dirs: ['dingtalk-bot'],
+ },
+ {
+ devId: 'DEV-005',
+ name: '小草莓',
+ emoji: '🍓',
+ role: '看板工程师',
+ dirs: ['m12-kanban', 'status-board'],
+ },
+ {
+ devId: 'DEV-009',
+ name: '花尔',
+ emoji: '🌺',
+ role: '前端工程师',
+ dirs: ['m05-user-center'],
+ },
+ {
+ devId: 'DEV-010',
+ name: '桔子',
+ emoji: '🍊',
+ role: '光湖主控',
+ dirs: ['m06-ticket', 'm11-module'],
+ },
+ {
+ devId: 'DEV-011',
+ name: '匆匆那年',
+ emoji: '🌙',
+ role: '开发者',
+ dirs: [],
+ },
+];
+
+// ========== 读取模块元信息 ==========
+function readModuleInfo(dir) {
+ const info = {
+ dir,
+ title: dir,
+ owner: '',
+ status: '未知',
+ techStack: '待定',
+ dependencies: '无',
+ hasSrc: false,
+ hasPackageJson: false,
+ hasSyslog: false,
+ files: [],
+ description: '',
+ };
+
+ // 读取 README.md
+ const readmePath = path.join(dir, 'README.md');
+ if (fs.existsSync(readmePath)) {
+ const content = fs.readFileSync(readmePath, 'utf8');
+ const titleMatch = content.match(/^#\s+(.+)$/m);
+ if (titleMatch) info.title = titleMatch[1].trim();
+ const ownerMatch = content.match(/负责人[::]\s*(.+)/);
+ if (ownerMatch) info.owner = ownerMatch[1].trim();
+ const statusMatch = content.match(/状态[::]\s*(.+)/);
+ if (statusMatch) info.status = statusMatch[1].trim();
+ const techMatch = content.match(/技术栈[::]\s*(.+)/);
+ if (techMatch) info.techStack = techMatch[1].trim();
+ const depsMatch = content.match(/依赖模块[::]\s*(.+)/);
+ if (depsMatch) info.dependencies = depsMatch[1].trim();
+ // 收集额外描述行(非元数据)
+ const lines = content.split('\n').filter(l =>
+ l.trim() &&
+ !l.startsWith('#') &&
+ !l.match(/^\s*-\s*(负责人|状态|技术栈|依赖模块)[::]/)
+ );
+ if (lines.length > 0) info.description = lines.slice(0, 3).join(' ').trim();
+ }
+
+ // 检查结构完整性
+ info.hasSrc = fs.existsSync(path.join(dir, 'src'));
+ info.hasPackageJson = fs.existsSync(path.join(dir, 'package.json'));
+ info.hasSyslog = fs.existsSync(path.join(dir, 'SYSLOG.md'));
+
+ // 列出文件(最多15个,排除 node_modules)
+ try {
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
+ info.files = entries
+ .filter(e => e.name !== 'node_modules' && e.name !== '.git')
+ .map(e => (e.isDirectory() ? e.name + '/' : e.name))
+ .sort();
+ } catch (_) {
+ // 目录不可读时忽略
+ }
+
+ return info;
+}
+
+// ========== 生成结构状态徽章 ==========
+function structureBadge(info) {
+ const checks = [
+ info.hasSrc ? '✅ src/' : '⚠️ src/',
+ info.hasPackageJson ? '✅ package.json' : '⚠️ package.json',
+ info.hasSyslog ? '✅ SYSLOG.md' : '⚠️ SYSLOG.md',
+ ];
+ return checks.join(' · ');
+}
+
+// ========== 主函数:生成文档 ==========
+function generateDoc() {
+ const now = new Date();
+ const timestamp = now.toISOString().replace('T', ' ').slice(0, 16) + ' UTC';
+ const dateStr = now.toISOString().slice(0, 10);
+
+ const lines = [];
+
+ lines.push('# HoloLake Era 操作系统部署模块');
+ lines.push('');
+ lines.push('> 📋 **自动生成文档** · 铸渊(ZhùYuān)维护 · 最后更新:' + timestamp);
+ lines.push('> ');
+ lines.push('> 本文档由 GitHub Actions 自动触发生成,每当合作者上传/更新模块时自动刷新。');
+ lines.push('> 按合作者编号(DEV-XXX)整理所有已上传模块。');
+ lines.push('');
+ lines.push('---');
+ lines.push('');
+
+ // 生成目录
+ lines.push('## 📑 目录');
+ lines.push('');
+ for (const collab of COLLABORATOR_MODULES) {
+ const moduleCount = collab.dirs.filter(d => fs.existsSync(d)).length;
+ const badge = moduleCount > 0 ? `(${moduleCount} 个模块)` : '(待上传)';
+ lines.push(`- [${collab.devId} · ${collab.emoji} ${collab.name}](#${collab.devId.toLowerCase().replaceAll('-', '')}--${encodeURIComponent(collab.name)}) ${badge}`);
+ }
+ lines.push('');
+ lines.push('---');
+ lines.push('');
+
+ // 统计
+ let totalModules = 0;
+ let uploadedModules = 0;
+
+ // 各合作者章节
+ for (const collab of COLLABORATOR_MODULES) {
+ lines.push(`## ${collab.devId} · ${collab.emoji} ${collab.name}`);
+ lines.push('');
+ lines.push(`**角色:** ${collab.role}`);
+ lines.push('');
+
+ const existingDirs = collab.dirs.filter(d => fs.existsSync(d));
+ const missingDirs = collab.dirs.filter(d => !fs.existsSync(d));
+
+ totalModules += collab.dirs.length;
+ uploadedModules += existingDirs.length;
+
+ if (collab.dirs.length === 0) {
+ lines.push('> 🕐 暂无分配模块,待安排。');
+ lines.push('');
+ lines.push('---');
+ lines.push('');
+ continue;
+ }
+
+ if (existingDirs.length === 0) {
+ lines.push('> ⏳ 模块目录尚未创建,等待上传。');
+ lines.push('');
+ if (missingDirs.length > 0) {
+ lines.push('**待上传模块:** ' + missingDirs.join('、'));
+ lines.push('');
+ }
+ lines.push('---');
+ lines.push('');
+ continue;
+ }
+
+ for (const dir of existingDirs) {
+ const info = readModuleInfo(dir);
+
+ lines.push(`### 📦 ${info.title}`);
+ lines.push('');
+ lines.push(`| 字段 | 内容 |`);
+ lines.push(`|------|------|`);
+ lines.push(`| **目录** | \`${dir}/\` |`);
+ lines.push(`| **负责人** | ${info.owner || collab.name} |`);
+ lines.push(`| **状态** | ${info.status} |`);
+ lines.push(`| **技术栈** | ${info.techStack} |`);
+ lines.push(`| **依赖模块** | ${info.dependencies} |`);
+ lines.push('');
+
+ lines.push('**结构检查:** ' + structureBadge(info));
+ lines.push('');
+
+ if (info.files.length > 0) {
+ lines.push('**已上传文件:**');
+ lines.push('');
+ lines.push('```');
+ lines.push(dir + '/');
+ info.files.forEach(f => lines.push(' ' + f));
+ lines.push('```');
+ lines.push('');
+ }
+
+ if (info.hasSyslog) {
+ const syslogContent = fs.readFileSync(path.join(dir, 'SYSLOG.md'), 'utf8');
+ const syslogLines = syslogContent.split('\n').filter(l => l.trim()).slice(0, 5);
+ if (syslogLines.length > 0) {
+ lines.push('');
+ lines.push('📝 SYSLOG 摘要(点击展开)
');
+ lines.push('');
+ lines.push('```');
+ syslogLines.forEach(l => lines.push(l));
+ lines.push('```');
+ lines.push('');
+ lines.push(' ');
+ lines.push('');
+ }
+ }
+ }
+
+ if (missingDirs.length > 0) {
+ lines.push('> ⏳ **待上传:** ' + missingDirs.map(d => '`' + d + '/`').join('、'));
+ lines.push('');
+ }
+
+ lines.push('---');
+ lines.push('');
+ }
+
+ // 汇总统计
+ lines.push('## 📊 部署统计');
+ lines.push('');
+ lines.push(`| 项目 | 数量 |`);
+ lines.push(`|------|------|`);
+ lines.push(`| 合作者总数 | ${COLLABORATOR_MODULES.length} |`);
+ lines.push(`| 计划模块数 | ${totalModules} |`);
+ lines.push(`| 已上传模块数 | ${uploadedModules} |`);
+ lines.push(`| 待上传模块数 | ${totalModules - uploadedModules} |`);
+ lines.push(`| 上传完成率 | ${totalModules > 0 ? Math.round(uploadedModules / totalModules * 100) : 0}% |`);
+ lines.push(`| 文档更新时间 | ${timestamp} |`);
+ lines.push('');
+ lines.push('---');
+ lines.push('');
+ lines.push('*由 铸渊(ZhùYuān)· GitHub Copilot Agent 自动生成 · 仓库:guanghulab*');
+ lines.push('');
+
+ // 确保 docs/ 目录存在
+ if (!fs.existsSync('docs')) {
+ fs.mkdirSync('docs', { recursive: true });
+ }
+
+ fs.writeFileSync(OUTPUT_FILE, lines.join('\n'), 'utf8');
+ console.log('✅ 文档已生成:' + OUTPUT_FILE);
+ console.log('📊 合作者: ' + COLLABORATOR_MODULES.length + ' | 计划模块: ' + totalModules + ' | 已上传: ' + uploadedModules);
+}
+
+generateDoc();
From 7698adad468ecb1275ad6b6110f3f0e94598311c Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 6 Mar 2026 14:44:19 +0000
Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=A8=A1=E5=9D=97=E6=94=B6?=
=?UTF-8?q?=E8=AE=AB=E8=87=AA=E5=8A=A8=E9=80=9A=E7=9F=A5=E7=B3=BB=E7=BB=9F?=
=?UTF-8?q?=20=E2=80=94=20GitHub=20Issue=20@=E6=8F=90=E5=8F=8A=20+=20?=
=?UTF-8?q?=E9=82=AE=E4=BB=B6=E9=80=9A=E7=9F=A5?=
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/brain/collaborators.json | 62 ++++++
.github/workflows/generate-module-doc.yml | 42 ++++
docs/HoloLake-Era-OS-Modules.md | 20 +-
scripts/generate-module-doc.js | 15 +-
scripts/notify-module-received.js | 260 ++++++++++++++++++++++
5 files changed, 387 insertions(+), 12 deletions(-)
create mode 100644 .github/brain/collaborators.json
create mode 100644 scripts/notify-module-received.js
diff --git a/.github/brain/collaborators.json b/.github/brain/collaborators.json
new file mode 100644
index 00000000..5baaa1df
--- /dev/null
+++ b/.github/brain/collaborators.json
@@ -0,0 +1,62 @@
+{
+ "description": "HoloLake 合作者 GitHub 用户名映射表 · 铸渊通知系统使用",
+ "note": "请将每位合作者的 github_username 填写为他们的真实 GitHub 用户名(即 @xxx 中的 xxx)",
+ "collaborators": [
+ {
+ "dev_id": "DEV-001",
+ "name": "页页",
+ "github_username": "",
+ "emoji": "🖥️",
+ "modules": ["backend-integration"]
+ },
+ {
+ "dev_id": "DEV-002",
+ "name": "肥猫",
+ "github_username": "",
+ "emoji": "🦁",
+ "modules": ["m01-login", "m03-personality"]
+ },
+ {
+ "dev_id": "DEV-003",
+ "name": "燕樊",
+ "github_username": "",
+ "emoji": "🌸",
+ "modules": ["m07-dialogue-ui", "m10-cloud", "m15-cloud-drive"]
+ },
+ {
+ "dev_id": "DEV-004",
+ "name": "之之",
+ "github_username": "",
+ "emoji": "🤖",
+ "modules": ["dingtalk-bot"]
+ },
+ {
+ "dev_id": "DEV-005",
+ "name": "小草莓",
+ "github_username": "",
+ "emoji": "🍓",
+ "modules": ["m12-kanban", "status-board"]
+ },
+ {
+ "dev_id": "DEV-009",
+ "name": "花尔",
+ "github_username": "",
+ "emoji": "🌺",
+ "modules": ["m05-user-center"]
+ },
+ {
+ "dev_id": "DEV-010",
+ "name": "桔子",
+ "github_username": "",
+ "emoji": "🍊",
+ "modules": ["m06-ticket", "m11-module"]
+ },
+ {
+ "dev_id": "DEV-011",
+ "name": "匆匆那年",
+ "github_username": "",
+ "emoji": "🌙",
+ "modules": []
+ }
+ ]
+}
diff --git a/.github/workflows/generate-module-doc.yml b/.github/workflows/generate-module-doc.yml
index 96dc1ba2..e8de5d9e 100644
--- a/.github/workflows/generate-module-doc.yml
+++ b/.github/workflows/generate-module-doc.yml
@@ -51,3 +51,45 @@ jobs:
git commit -m "📋 自动更新 HoloLake Era 模块文档 · $(date -u +%Y-%m-%d\ %H:%M\ UTC)"
git push
fi
+
+ notify-collaborator:
+ name: 📧 通知合作者模块已收到
+ runs-on: ubuntu-latest
+ # 仅 push 事件触发(workflow_dispatch 为手动,不发通知)
+ if: github.event_name == 'push'
+ permissions:
+ contents: read
+ issues: write
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: main
+ fetch-depth: 2
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+
+ - name: 获取本次 push 改动的文件列表
+ id: changed
+ run: |
+ # 获取本次 push 相对于上一个 commit 改动的文件
+ FILES=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git show --name-only --format="" HEAD)
+ echo "files<> $GITHUB_OUTPUT
+ echo "$FILES" >> $GITHUB_OUTPUT
+ echo "EOF" >> $GITHUB_OUTPUT
+ echo "📄 改动文件:$FILES"
+
+ - name: 发送模块收讫通知
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_REPO: ${{ github.repository }}
+ PUSHER_LOGIN: ${{ github.actor }}
+ CHANGED_FILES: ${{ steps.changed.outputs.files }}
+ COMMIT_SHA: ${{ github.sha }}
+ COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
+ run: node scripts/notify-module-received.js
+
diff --git a/docs/HoloLake-Era-OS-Modules.md b/docs/HoloLake-Era-OS-Modules.md
index 93ccc528..5445eaba 100644
--- a/docs/HoloLake-Era-OS-Modules.md
+++ b/docs/HoloLake-Era-OS-Modules.md
@@ -1,6 +1,6 @@
# HoloLake Era 操作系统部署模块
-> 📋 **自动生成文档** · 铸渊(ZhùYuān)维护 · 最后更新:2026-03-06 14:36 UTC
+> 📋 **自动生成文档** · 铸渊(ZhùYuān)维护 · 最后更新:2026-03-06 14:43 UTC
>
> 本文档由 GitHub Actions 自动触发生成,每当合作者上传/更新模块时自动刷新。
> 按合作者编号(DEV-XXX)整理所有已上传模块。
@@ -9,14 +9,14 @@
## 📑 目录
-- [DEV-001 · 🖥️ 页页](#dev001--%E9%A1%B5%E9%A1%B5) (1 个模块)
-- [DEV-002 · 🦁 肥猫](#dev002--%E8%82%A5%E7%8C%AB) (2 个模块)
-- [DEV-003 · 🌸 燕樊](#dev003--%E7%87%95%E6%A8%8A) (3 个模块)
-- [DEV-004 · 🤖 之之](#dev004--%E4%B9%8B%E4%B9%8B) (1 个模块)
-- [DEV-005 · 🍓 小草莓](#dev005--%E5%B0%8F%E8%8D%89%E8%8E%93) (2 个模块)
-- [DEV-009 · 🌺 花尔](#dev009--%E8%8A%B1%E5%B0%94) (1 个模块)
-- [DEV-010 · 🍊 桔子](#dev010--%E6%A1%94%E5%AD%90) (2 个模块)
-- [DEV-011 · 🌙 匆匆那年](#dev011--%E5%8C%86%E5%8C%86%E9%82%A3%E5%B9%B4) (待上传)
+- [DEV-001 · 🖥️ 页页](#dev-001-页页) (1 个模块)
+- [DEV-002 · 🦁 肥猫](#dev-002-肥猫) (2 个模块)
+- [DEV-003 · 🌸 燕樊](#dev-003-燕樊) (3 个模块)
+- [DEV-004 · 🤖 之之](#dev-004-之之) (1 个模块)
+- [DEV-005 · 🍓 小草莓](#dev-005-小草莓) (2 个模块)
+- [DEV-009 · 🌺 花尔](#dev-009-花尔) (1 个模块)
+- [DEV-010 · 🍊 桔子](#dev-010-桔子) (2 个模块)
+- [DEV-011 · 🌙 匆匆那年](#dev-011-匆匆那年) (待上传)
---
@@ -326,7 +326,7 @@ m11-module/
| 已上传模块数 | 12 |
| 待上传模块数 | 0 |
| 上传完成率 | 100% |
-| 文档更新时间 | 2026-03-06 14:36 UTC |
+| 文档更新时间 | 2026-03-06 14:43 UTC |
---
diff --git a/scripts/generate-module-doc.js b/scripts/generate-module-doc.js
index e96c5611..c7bf05e3 100644
--- a/scripts/generate-module-doc.js
+++ b/scripts/generate-module-doc.js
@@ -126,7 +126,16 @@ function readModuleInfo(dir) {
return info;
}
-// ========== 生成结构状态徽章 ==========
+// ========== 生成与 GitHub 一致的 Markdown anchor ==========
+// GitHub 规则:小写 → 保留字母/数字/空格/连字符/中文 → 空格转连字符
+function toGitHubAnchor(headingText) {
+ return headingText
+ .toLowerCase()
+ .replace(/[^\p{L}\p{N}\s-]/gu, '') // 去除非字母/数字/空格/连字符(支持 Unicode)
+ .replace(/\s+/g, '-'); // 空格转连字符
+}
+
+
function structureBadge(info) {
const checks = [
info.hasSrc ? '✅ src/' : '⚠️ src/',
@@ -160,7 +169,9 @@ function generateDoc() {
for (const collab of COLLABORATOR_MODULES) {
const moduleCount = collab.dirs.filter(d => fs.existsSync(d)).length;
const badge = moduleCount > 0 ? `(${moduleCount} 个模块)` : '(待上传)';
- lines.push(`- [${collab.devId} · ${collab.emoji} ${collab.name}](#${collab.devId.toLowerCase().replaceAll('-', '')}--${encodeURIComponent(collab.name)}) ${badge}`);
+ const headingText = `${collab.devId} · ${collab.emoji} ${collab.name}`;
+ const anchor = toGitHubAnchor(headingText);
+ lines.push(`- [${headingText}](#${anchor}) ${badge}`);
}
lines.push('');
lines.push('---');
diff --git a/scripts/notify-module-received.js b/scripts/notify-module-received.js
new file mode 100644
index 00000000..637e1afc
--- /dev/null
+++ b/scripts/notify-module-received.js
@@ -0,0 +1,260 @@
+// scripts/notify-module-received.js
+// 铸渊 · 模块收讫通知系统
+// 当合作者上传模块后,自动创建 GitHub Issue @提及 → GitHub 自动发邮件给对方
+//
+// 环境变量(由 GitHub Actions 注入):
+// GITHUB_TOKEN — 仓库 token(自动注入)
+// GITHUB_REPO — 格式: owner/repo(如 qinfendebingshuo/guanghulab)
+// PUSHER_LOGIN — github.actor,即推送者的 GitHub 用户名
+// CHANGED_FILES — 本次 push 中改动的文件列表(换行分隔)
+// COMMIT_SHA — 本次 commit SHA(前8位)
+// COMMIT_MESSAGE — 本次 commit 消息
+
+const fs = require('fs');
+const https = require('https');
+
+// ========== 读取配置 ==========
+const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
+const GITHUB_REPO = process.env.GITHUB_REPO || '';
+const PUSHER_LOGIN = (process.env.PUSHER_LOGIN || '').trim();
+const CHANGED_FILES = (process.env.CHANGED_FILES || '').trim();
+const COMMIT_SHA = (process.env.COMMIT_SHA || '').slice(0, 8);
+const COMMIT_MSG = (process.env.COMMIT_MESSAGE || '').split('\n')[0].slice(0, 80);
+
+if (!GITHUB_TOKEN || !GITHUB_REPO) {
+ console.error('❌ 缺少 GITHUB_TOKEN 或 GITHUB_REPO');
+ process.exit(1);
+}
+
+if (!PUSHER_LOGIN) {
+ console.log('⚠️ 未获取到推送者用户名,跳过通知');
+ process.exit(0);
+}
+
+const [OWNER, REPO] = GITHUB_REPO.split('/');
+
+// ========== 加载合作者配置 ==========
+let collaborators = [];
+try {
+ const config = JSON.parse(fs.readFileSync('.github/brain/collaborators.json', 'utf8'));
+ collaborators = config.collaborators || [];
+} catch (e) {
+ console.error('❌ 无法读取 collaborators.json:', e.message);
+ process.exit(1);
+}
+
+// ========== 按推送者 GitHub 用户名查找合作者 ==========
+function findCollaborator(githubLogin) {
+ // 先按 github_username 精确匹配
+ const byUsername = collaborators.find(c =>
+ c.github_username && c.github_username.toLowerCase() === githubLogin.toLowerCase()
+ );
+ if (byUsername) return byUsername;
+ return null;
+}
+
+// ========== 分析改动了哪些模块 ==========
+function detectChangedModules(changedFilesStr) {
+ if (!changedFilesStr) return [];
+ const files = changedFilesStr.split('\n').map(f => f.trim()).filter(Boolean);
+ const moduleDirs = new Set();
+
+ // 已知模块目录前缀列表
+ const KNOWN_MODULE_PREFIXES = [
+ 'm01-login', 'm03-personality', 'm05-user-center', 'm06-ticket',
+ 'm07-dialogue-ui', 'm10-cloud', 'm11-module', 'm12-kanban',
+ 'm15-cloud-drive', 'dingtalk-bot', 'backend-integration', 'status-board',
+ ];
+
+ for (const file of files) {
+ for (const prefix of KNOWN_MODULE_PREFIXES) {
+ if (file.startsWith(prefix + '/') || file === prefix) {
+ moduleDirs.add(prefix);
+ }
+ }
+ }
+ return Array.from(moduleDirs);
+}
+
+// ========== 构建通知 Issue 内容 ==========
+function buildIssueContent(collab, changedModules, allFiles) {
+ const now = new Date().toISOString().replace('T', ' ').slice(0, 16) + ' UTC';
+ const mention = collab && collab.github_username ? `@${collab.github_username}` : `@${PUSHER_LOGIN}`;
+ const devLabel = collab ? `${collab.dev_id} · ${collab.emoji} ${collab.name}` : PUSHER_LOGIN;
+
+ const moduleListStr = changedModules.length > 0
+ ? changedModules.map(m => `- \`${m}/\``).join('\n')
+ : '- (系统自动检测,请核对)';
+
+ const fileLines = allFiles.split('\n').filter(Boolean);
+ const fileListStr = fileLines.slice(0, 20).map(f => ` - \`${f}\``).join('\n');
+ const extraNote = fileLines.length > 20 ? `\n - ...(共 ${fileLines.length} 个文件)` : '';
+
+ const title = `📦 铸渊收讫 · [${collab ? collab.dev_id : 'DEV-???'}] ${collab ? collab.name : PUSHER_LOGIN} 模块已收到`;
+
+ const body = `## 铸渊收讫通知
+
+${mention} 你好!🎉
+
+铸渊(自动化系统)已确认收到你上传的模块。
+
+---
+
+### 📋 收讫详情
+
+| 字段 | 内容 |
+|------|------|
+| **合作者** | ${devLabel} |
+| **GitHub 账号** | @${PUSHER_LOGIN} |
+| **收到时间** | ${now} |
+| **Commit** | \`${COMMIT_SHA}\` |
+| **提交说明** | ${COMMIT_MSG || '(无)'} |
+
+### 📦 涉及模块
+
+${moduleListStr}
+
+### 📄 上传文件清单
+
+${fileListStr}${extraNote}
+
+---
+
+### 📌 下一步
+
+1. **铸渊将自动更新** [HoloLake Era 操作系统部署模块](https://github.com/${GITHUB_REPO}/blob/main/docs/HoloLake-Era-OS-Modules.md) 总文档
+2. **模块结构检查** 已自动运行,请确认 CI 状态绿灯
+3. 如需补充 \`SYSLOG.md\`、\`package.json\` 或 \`src/\` 目录,请继续推送
+
+> 💡 如有问题,请直接在本 Issue 回复,铸渊会收到通知。
+
+---
+*—— 铸渊(ZhùYuān)· 光湖自动化系统 · 自动通知 #${now}*`;
+
+ return { title, body };
+}
+
+// ========== 调用 GitHub API 创建 Issue ==========
+function createIssue(title, body) {
+ return new Promise((resolve, reject) => {
+ const payload = JSON.stringify({ title, body, labels: ['模块收讫'] });
+ const options = {
+ hostname: 'api.github.com',
+ path: `/repos/${OWNER}/${REPO}/issues`,
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${GITHUB_TOKEN}`,
+ 'Accept': 'application/vnd.github+json',
+ 'Content-Type': 'application/json',
+ 'Content-Length': Buffer.byteLength(payload),
+ 'User-Agent': 'ZhuyuanBot/1.0',
+ 'X-GitHub-Api-Version': '2022-11-28',
+ },
+ };
+
+ const req = https.request(options, res => {
+ let data = '';
+ res.on('data', chunk => { data += chunk; });
+ res.on('end', () => {
+ if (res.statusCode === 201) {
+ const issue = JSON.parse(data);
+ resolve(issue);
+ } else {
+ reject(new Error(`GitHub API 返回 ${res.statusCode}: ${data}`));
+ }
+ });
+ });
+
+ req.on('error', reject);
+ req.write(payload);
+ req.end();
+ });
+}
+
+// ========== 确保标签存在(不存在则自动创建)==========
+function ensureLabel() {
+ return new Promise((resolve) => {
+ const labelPayload = JSON.stringify({
+ name: '模块收讫',
+ color: '0075ca',
+ description: '铸渊自动通知:合作者模块收讫确认',
+ });
+ const options = {
+ hostname: 'api.github.com',
+ path: `/repos/${OWNER}/${REPO}/labels`,
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${GITHUB_TOKEN}`,
+ 'Accept': 'application/vnd.github+json',
+ 'Content-Type': 'application/json',
+ 'Content-Length': Buffer.byteLength(labelPayload),
+ 'User-Agent': 'ZhuyuanBot/1.0',
+ 'X-GitHub-Api-Version': '2022-11-28',
+ },
+ };
+
+ const req = https.request(options, res => {
+ let data = '';
+ res.on('data', c => { data += c; });
+ res.on('end', () => {
+ // 201 = created, 422 = already exists,都算OK
+ resolve();
+ });
+ });
+ req.on('error', () => resolve()); // 标签创建失败不阻断主流程
+ req.write(labelPayload);
+ req.end();
+ });
+}
+
+// ========== 主流程 ==========
+async function main() {
+ console.log(`👤 推送者:${PUSHER_LOGIN}`);
+ console.log(`📁 改动文件:${CHANGED_FILES ? CHANGED_FILES.split('\n').length : 0} 个`);
+
+ const collab = findCollaborator(PUSHER_LOGIN);
+ if (collab) {
+ console.log(`✅ 识别合作者:${collab.dev_id} · ${collab.name}`);
+ if (!collab.github_username) {
+ console.log(`⚠️ ${collab.dev_id}(${collab.name})的 github_username 尚未填写`);
+ console.log(` 请在 .github/brain/collaborators.json 中补充,以便 @提及 生效`);
+ console.log(` 通知将仍然创建,但不会有 @提及 邮件通知`);
+ }
+ } else {
+ console.log(`ℹ️ 未在 collaborators.json 中找到 "${PUSHER_LOGIN}" 的映射,将使用 GitHub 用户名通知`);
+ }
+
+ const changedModules = detectChangedModules(CHANGED_FILES);
+ console.log(`📦 涉及模块:${changedModules.join(', ') || '(未检测到标准模块目录)'}`);
+
+ // 如果改动文件全部在 docs/ 或 scripts/ 或 .github/,说明是系统自动提交,跳过通知
+ const allFiles = CHANGED_FILES.split('\n').filter(Boolean);
+ const isSystemCommit = allFiles.length > 0 && allFiles.every(f =>
+ f.startsWith('docs/') || f.startsWith('scripts/') || f.startsWith('.github/')
+ );
+ if (isSystemCommit) {
+ console.log('🤖 检测到系统自动提交(非模块上传),跳过通知');
+ process.exit(0);
+ }
+
+ if (changedModules.length === 0) {
+ console.log('⚠️ 未检测到标准模块目录的改动,跳过通知');
+ process.exit(0);
+ }
+
+ // 确保标签存在
+ await ensureLabel();
+
+ // 构建并发送通知
+ const { title, body } = buildIssueContent(collab, changedModules, CHANGED_FILES);
+ console.log(`📝 创建通知 Issue:${title}`);
+
+ const issue = await createIssue(title, body);
+ console.log(`✅ Issue 已创建:#${issue.number} → ${issue.html_url}`);
+ console.log(`📧 GitHub 将自动发送邮件通知给 @${collab?.github_username || PUSHER_LOGIN}`);
+}
+
+main().catch(err => {
+ console.error('❌ 通知失败:', err.message);
+ process.exit(1);
+});