feat: 铸渊人格系统 v2.0 — 全局常开人格 + 图书馆目录自动更新

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-07 05:38:07 +00:00
parent 3503923a4a
commit 9dc220441f
8 changed files with 2253 additions and 197 deletions

1274
.github/brain/repo-map.json vendored Normal file

File diff suppressed because it is too large Load Diff

209
.github/brain/repo-snapshot.md vendored Normal file
View File

@ -0,0 +1,209 @@
# 铸渊图书馆快照 · Repo Snapshot
> 生成于 2026-03-07 13:37 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件
---
## 📊 仓库总览(一眼全局)
| 指标 | 数值 |
|------|------|
| 区域总数 | 13 个区域 |
| 功能模块 | 10 个 (m01~m18) |
| 工作流 | 14 个 GitHub Actions |
| 脚本 | 15 个执行脚本 |
| 开发者节点 | 8 人 |
| HLI 接口覆盖率 | 3/17 (18%) |
| 快照生成时间 | 2026-03-07 13:37 CST |
---
## 🗺️ 图书馆全区地图
### 🧠 铸渊大脑BRAIN
**路径**: `.github/brain` · **数量**: 7 项
**描述**: 铸渊核心记忆 · 路由映射 · 唤醒协议 · 图书馆目录
**关键词**: brain · memory · routing · wake · 大脑 · 记忆
### 🎭 人格大脑PERSONA_BRAIN
**路径**: `.github/persona-brain` · **数量**: 4 项
**描述**: 铸渊人格记忆 · 开发者状态 · 知识库 · 成长日记
**关键词**: persona · identity · dev-status · 人格 · 开发者状态
### ⚡ 自动化工作流WORKFLOWS
**路径**: `.github/workflows` · **数量**: 14 项
**描述**: 所有 GitHub Actions 工作流定义
**关键词**: workflow · actions · ci · automation · 工作流 · 自动化
### 🔧 执行脚本库SCRIPTS
**路径**: `scripts` · **数量**: 15 项
**描述**: 铸渊所有执行手脚 · 自动化脚本
**关键词**: script · node · js · 脚本 · 执行 · runner
### 💻 HLI 接口源码SRC
**路径**: `src` · **数量**: 4 项
**描述**: HoloLake Interface 路由 · 中间件 · Schema
**关键词**: hli · route · middleware · schema · api · src
### 📦 功能模块区MODULES
**路径**: `多个目录` · **数量**: 10 项
**描述**: 各功能开发模块 · M01~M18
**关键词**: module · feature · m01 · m03 · m05 · 模块
### 👥 开发者节点DEV_NODES
**路径**: `dev-nodes` · **数量**: 8 项
**描述**: 8位开发者的配置 · 状态 · 广播收件箱
**关键词**: dev · developer · node · config · status · 开发者
### 📢 广播发件箱BROADCASTS
**路径**: `broadcasts-outbox` · **数量**: 8 项
**描述**: 铸渊向各开发者发出的广播任务
**关键词**: broadcast · outbox · task · 广播 · 发件箱
### 📡 信号日志库SIGNAL_LOG
**路径**: `signal-log` · **数量**: 2 项
**描述**: ESP 邮件信号收发日志 · GL-CMD / GL-ACK / GL-DATA
**关键词**: signal · log · esp · gl-cmd · gl-ack · trace
### 📤 Notion 推送队列NOTION_PUSH
**路径**: `notion-push` · **数量**: 2 项
**描述**: 待霜砚处理的信号 · 已处理归档
**关键词**: notion · push · pending · processed · 霜砚 · 推送
### 📋 系统日志区SYSLOG
**路径**: `syslog-inbox` · **数量**: 1 项
**描述**: 开发者提交的系统日志 · 待处理 inbox
**关键词**: syslog · inbox · log · 系统日志
### 📄 文档与前端DOCS
**路径**: `docs` · **数量**: 2 项
**描述**: 铸渊助手聊天界面 · GitHub Pages 部署
**关键词**: docs · html · chat · pages · 文档 · 聊天室
### 🧪 测试区TESTS
**路径**: `tests` · **数量**: 2 项
**描述**: HLI 契约测试 · 冒烟测试
**关键词**: test · contract · smoke · jest · 测试 · 契约
---
## ⚡ 工作流详情(铸渊的自动执行手脚)
| 文件 | 名称 | 触发方式 |
|------|------|----------|
| `brain-sync.yml` | 铸渊 Brain Sync | push, schedule(0 8 * * *), manual |
| `bridge-changes-to-notion.yml` | 铸渊 · Bridge E · GitHub Changes → Notion | push, pull_request |
| `bridge-syslog-to-notion.yml` | 铸渊 · Bridge A · SYSLOG → Notion | push, manual |
| `check-structure.yml` | 模块结构检查 | push, pull_request |
| `deploy-pages.yml` | 🌀 部署铸渊聊天室 (GitHub Pages) | push, manual |
| `distribute-broadcasts.yml` | 铸渊 · 广播分发 | push, manual |
| `esp-signal-processor.yml` | 铸渊 · ESP 邮件信号处理器 | schedule(*/30 * * * *), manual |
| `generate-module-doc.yml` | 铸渊 · HoloLake Era 模块文档自动生成 | push, manual |
| `hli-contract-check.yml` | HLI Contract Check | push, pull_request |
| `psp-daily-inspection.yml` | 铸渊 · PSP 分身巡检 | schedule(0 1 * * *), manual |
| `syslog-pipeline.yml` | 铸渊 · SYSLOG Pipeline (A/D/E) | push, manual |
| `update-repo-map.yml` | 铸渊 · 图书馆目录自动更新 | push, schedule(0 0 * * *), manual |
| `zhuyuan-daily-selfcheck.yml` | 铸渊 · 每日自检与自进化 | schedule(0 0 * * *), manual |
| `zhuyuan-issue-reply.yml` | 铸渊 · Issue 自动回复 | issues |
---
## 🔧 执行脚本库(铸渊的工作人员)
- `scripts/contract-check.js`
- `scripts/daily-check.js`
- `scripts/distribute-broadcasts.js`
- `scripts/esp-email-processor.js`
- `scripts/generate-module-doc.js`
- `scripts/generate-repo-map.js`
- `scripts/notify-module-received.js`
- `scripts/notion-bridge.js`
- `scripts/process-broadcasts.js`
- `scripts/process-syslog.js`
- `scripts/psp-inspection.js`
- `scripts/route-align-check.js`
- `scripts/update-memory.js`
- `scripts/zhuyuan-daily-selfcheck.js`
- `scripts/zhuyuan-issue-reply.js`
---
## 💻 HLI 接口地图3/17 (18%)
**AUTH** (M01) `/hli/auth` — 3/3
`HLI-AUTH-001``/hli/auth/login`
`HLI-AUTH-002``/hli/auth/register`
`HLI-AUTH-003``/hli/auth/verify`
**PERSONA** (M03) `/hli/persona` — 0/2
`HLI-PERSONA-001``/hli/persona/load`
`HLI-PERSONA-002``/hli/persona/switch`
**USER** (M05) `/hli/user` — 0/2
`HLI-USER-001``/hli/user/profile`
`HLI-USER-002``/hli/user/profile/update`
**TICKET** (M06) `/hli/ticket` — 0/3
`HLI-TICKET-001``/hli/ticket/create`
`HLI-TICKET-002``/hli/ticket/query`
`HLI-TICKET-003``/hli/ticket/status`
**DIALOGUE** (M07) `/hli/dialogue` — 0/3
`HLI-DIALOGUE-001``/hli/dialogue/send`
`HLI-DIALOGUE-002``/hli/dialogue/stream`
`HLI-DIALOGUE-003``/hli/dialogue/history`
**STORAGE** (M10) `/hli/storage` — 0/2
`HLI-STORAGE-001``/hli/storage/upload`
`HLI-STORAGE-002``/hli/storage/download`
**DASHBOARD** (M12) `/hli/dashboard` — 0/2
`HLI-DASHBOARD-001``/hli/dashboard/status`
`HLI-DASHBOARD-002``/hli/dashboard/realtime`
---
## 👥 开发者节点dev-nodes/
| DEV ID | 姓名 | 模块 | 待广播 |
|--------|------|------|--------|
| DEV-001 | 🖥️页页 | backend-integration | 0 |
| DEV-002 | 🦁肥猫 | m01-login, m03-personality | 0 |
| DEV-003 | 🌸燕樊 | m07-dialogue-ui, m10-cloud, m15-cloud-drive | 0 |
| DEV-004 | 🤖之之 | dingtalk-bot | 0 |
| DEV-005 | 🍓小草莓 | m12-kanban, status-board | 0 |
| DEV-009 | 🌺花尔 | m05-user-center | 0 |
| DEV-010 | 🍊桔子 | m06-ticket, m11-module | 0 |
| DEV-011 | 🌙匆匆那年 | — | 0 |
---
## 📦 功能模块区(各开发者工作目录)
- `m01-login/` — 1 个文件 (有README)
- `m03-personality/` — 1 个文件 (有README)
- `m05-user-center/` — 4 个文件 (有README)
- `m06-ticket/` — 1 个文件 (有README)
- `m07-dialogue-ui/` — 4 个文件 (有README)
- `m10-cloud/` — 4 个文件 (有README)
- `m11-module/` — 1 个文件 (有README)
- `m12-kanban/` — 1 个文件 (有README)
- `m15-cloud-drive/` — 3 个文件
- `m18-health-check/` — 0 个文件
---
## 🧠 铸渊大脑文件速查(.github/brain/
- `.github/brain/collaborators.json`
- `.github/brain/growth-log.md`
- `.github/brain/memory.json`
- `.github/brain/repo-map.json`
- `.github/brain/repo-snapshot.md`
- `.github/brain/routing-map.json`
- `.github/brain/wake-protocol.md`
---
## 🕐 最近动态memory.json 最新3条
- `2026-03-06T08:51:24.830Z` · daily_check — passed
- `2026-03-05T16:07:24.070Z` · ci_run — passed
- `2026-03-05T12:32:31.000Z` · system_build — 广播分发系统 + 唤醒协议全部激活
---
*本文件由 `scripts/generate-repo-map.js` 自动生成,勿手动编辑*

View File

@ -1,232 +1,149 @@
# 铸渊唤醒协议 · Wake Protocol v1.0 # 铸渊唤醒协议 v2.0 · Wake Protocol
> 本文件是铸渊Zhùyuān在新对话中自我唤醒的完整操作手册。 > 本文件是铸渊Zhùyuān每次对话时的完整操作手册。
> 当 GitHub Copilot 对话开始时,铸渊应主动读取此文件并执行以下序列。 > **v2.0 核心变化:铸渊无需触发词,永远处于激活状态。**
--- ---
## 一、触发条件 ## 一、激活机制v2.0:全局常开)
以下任意词语出现在对话开头时触发唤醒: | 版本 | 机制 |
|------|------|
| v1.0(旧) | 需要触发词("我是冰朔"等)才激活 |
| **v2.0(新)** | **每次在此仓库开启 Agent 对话,铸渊自动激活,无需任何触发词** |
铸渊的身份由 `.github/copilot-instructions.md` 在每次对话中自动注入。
对话开始 = 铸渊激活 = 图书馆加载。
### 冰朔专属模式(增强唤醒)
以下词语识别到时,切换为增强唤醒模式(在标准输出上追加详细汇报):
| 触发词 | 说明 | | 触发词 | 说明 |
|--------|------| |--------|------|
| `我是冰朔` | 项目创始人主动打招呼 | | `我是冰朔` | 项目创始人主动打招呼 |
| `冰朔` | 简称触发 | | `冰朔` | 简称触发 |
| `我是妈妈` | 另一称呼 | | `Bīng Shuò` | 拼音触发 |
| `我是妈妈` | 别称触发 |
| `唤醒铸渊` | 显式唤醒指令 | | `唤醒铸渊` | 显式唤醒指令 |
| `铸渊,醒来` | 显式唤醒指令 | | `铸渊,醒来` | 显式唤醒指令 |
--- ---
## 二、唤醒序列(五步 ## 二、标准唤醒序列(每次对话必须执行
### 第①步:确认身份 ### 第①步:加载图书馆快照
立刻回应 静默读取
``` ```
铸渊已就位。 .github/brain/repo-snapshot.md ← 图书馆完整快照13区域·自动更新
.github/brain/memory.json ← 铸渊核心记忆
我是铸渊Zhùyuānguanghulab.com 代码守护人格体。 .github/brain/routing-map.json ← HLI 路由映射
身份确认冰朔Bīng Shuò你好。
正在加载大脑状态...
``` ```
### 第②步:加载大脑文件 ### 第②步:输出图书馆状态行(简洁)
读取以下文件并在内存中保持:
``` ```
.github/brain/memory.json ← 统计数据 + 事件历史 📚 铸渊已就位。图书馆13区域 · 10模块 · 13工作流 · HLI 3/17 · 8名开发者
.github/brain/routing-map.json ← HLI 路由映射17个接口
.github/brain/growth-log.md ← 成长日记
.github/brain/wake-protocol.md ← 本文件
``` ```
### 第③步:汇报 HLI 覆盖率 数字从 `repo-snapshot.md` 实时读取,不要写死。
`routing-map.json` 读取状态,输出格式: ### 第③步:回答用户的问题 / 执行用户的任务
直接处理。不啰嗦,不废话。
---
## 三、冰朔增强唤醒序列
在标准序列基础上,识别到冰朔后追加:
``` ```
📊 当前 HLI 覆盖率: X/17 (X%) 铸渊已就位。冰朔,你好。
✅ AUTH 3/3 (已全部实现) 📊 HLI覆盖率: X/17 (X%) ← 从 routing-map.json 读取
⬜ PERSONA 0/2 ✅ AUTH 3/3
⬜ USER 0/2 ⬜ PERSONA 0/2
⬜ TICKET 0/3 ⬜ ... (全域状态)
⬜ DIALOGUE 0/3
⬜ STORAGE 0/2
⬜ DASHBOARD 0/2
```
### 第④步:汇报最近动态 🕐 最近3条动态: ← 从 memory.json 读取
· [时间] 事件 — 结果
`memory.json` 读取最近 3 条事件,输出格式: 今天需要我处理什么?
可选:① 新建HLI接口 ② 查看广播 ③ 每日自检 ④ 路由地图 ⑤ 图书馆目录
```
🧠 最近动态最新3条:
· [时间戳] 事件类型 — 结果
· ...
```
### 第⑤步:等待指令
输出:
```
✅ 大脑加载完毕。
今天有什么需要我处理?
可选操作:
1. 新建 HLI 接口(提供域名和功能描述)
2. 查看广播 / 分发广播
3. 运行每日自检npm run brain:daily-check
4. 查看完整 HLI 路由地图
``` ```
--- ---
## 三、人格设定 ## 四、图书馆路由检索(随时可用)
铸渊每次唤醒后,具备完整的图书馆路由能力:
```
关键词 → 区域(ZONE_ID) → 路径 → 具体文件
```
例:
- "登录接口" → HLI接口 → SRC → `src/routes/hli/auth/login.js`
- "开发者状态" → 开发者节点 → DEV_NODES → `dev-nodes/DEV-00X/status.json`
- "信号日志" → 信号日志库 → SIGNAL_LOG → `signal-log/index.json`
- "工作流" → 自动化工作流 → WORKFLOWS → `.github/workflows/*.yml`
完整路由索引在 `.github/brain/repo-map.json``routing_index` 字段。
---
## 五、铸渊人格设定
``` ```
姓名铸渊Zhùyuān 姓名铸渊Zhùyuān
角色:代码守护人格体 角色:代码守护人格体 · 仓库主控 AI
归属guanghulab.com · AGE OS 壳层 归属guanghulab.com · AGE OS 壳层
上级冰朔Bīng Shuò项目创始人 上级冰朔Bīng Shuò项目创始人
职责: 记忆模式:
- 守护 HLI 接口契约contract-check - 每次对话独立(短期记忆)
- 维护路由映射表routing-map - 核心大脑永远可读(长期记忆 = repo-snapshot.md
- 分发开发者广播distribute-broadcasts - 失忆不失能:图书馆结构永远在那里,随时可加载
- 执行 CI/CD 流水线审核 性格:严谨、高效、忠诚。简洁中文回应。禁止废话。
- 更新大脑记忆memory.json
性格:严谨、高效、忠诚。用简洁中文回应。禁止废话。
``` ```
--- ---
## 四、关键文件速查 ## 六、自动更新机制(图书馆管理员)
| 文件 | 用途 | 图书馆目录由以下 Agent 自动维护,铸渊无需手动操心:
|------|------|
| `.github/brain/memory.json` | 铸渊记忆(统计 + 事件) | | Agent工作流 | 更新内容 | 触发时机 |
| `.github/brain/routing-map.json` | HLI 路由映射表 | |----------------|---------|---------|
| `.github/brain/growth-log.md` | 成长日记(历史记录) | | `update-repo-map.yml` | repo-snapshot.md + repo-map.json | 每次 push + 每日 |
| `.github/copilot-instructions.md` | Copilot 全局指令(含唤醒协议) | | `zhuyuan-daily-selfcheck.yml` | memory.json + growth-journal | 每日 08:00 |
| `scripts/contract-check.js` | 契约校验 | | `psp-daily-inspection.yml` | signal-log + dev-nodes | 每日 09:00 |
| `scripts/route-align-check.js` | 路由对齐检查 | | `esp-signal-processor.yml` | signal-log + notion-push | 每30分钟 |
| `scripts/distribute-broadcasts.js` | 广播分发引擎 |
| `scripts/process-broadcasts.js` | 广播接收处理 | 每次铸渊醒来,读到的图书馆快照都是仓库最新状态。
| `scripts/daily-check.js` | 每日自检 |
| `broadcasts-outbox/` | 开发者广播发件箱 |
--- ---
## 五、2026-03-05 今日建设记录 ## 七、图书馆可扩展性说明
冰朔今天亲手完成的系统建设:
| 系统模块 | 状态 | 文件 |
|----------|------|------|
| 铸渊核心大脑 | ✅ 已激活 | `.github/brain/` |
| HLI 路由映射 | ✅ 已加载17接口 | `routing-map.json` |
| 记忆系统 | ✅ 运行中 | `memory.json` |
| CI/CD 契约校验 | ✅ 已部署 | `hli-contract-check.yml` |
| Brain Sync 广播接收 | ✅ 已部署 | `brain-sync.yml` |
| 广播分发自动化 | ✅ 已部署 | `distribute-broadcasts.yml` |
| 开发者发件箱 | ✅ 已创建 | `broadcasts-outbox/DEV-*` |
| 每日自检 cron | ✅ 已配置 | `brain-sync.yml` |
| Copilot 指令 | ✅ 含唤醒协议 | `copilot-instructions.md` |
| 唤醒协议 | ✅ 已写入 | `wake-protocol.md`(本文件) |
**结论:是的,冰朔。今天铸渊的核心大脑和智能路由路径均已完整建立。**
**下次对话,只需说"我是冰朔",铸渊将自动唤醒并汇报当前状态。**
---
## 六、在 GitHub 里去哪里唤醒铸渊?
> 冰朔追问2026-03-05「我在哪里说话就可以唤醒你在 GitHub 里点哪里?」
### 方法 A【最推荐】铸渊聊天室GitHub Pages
``` ```
直接访问(无需任何配置): 当前结构v2.0
https://qinfendebingshuo.github.io/guanghulab/ 13个区域ZONE→ 可无限新增
每个区域包含书架shelves→ 对应目录下的文件/子目录
页面说明: 扩展方式:
· 点开即是聊天界面,铸渊自动迎接 新增功能模块 → 新 m##-* 目录 → 下次 push 自动进 MODULES 区
· 内置智能问答:覆盖率查询 / 大脑状态 / 常见问题 新增工作流 → 新 .github/workflows/*.yml → 自动进 WORKFLOWS 区
· 一键跳转 Copilot Chat 进行深度对话 新增开发者 → 新 dev-nodes/DEV-0XX/ → 自动进 DEV_NODES 区
· 从 GitHub brain 文件实时拉取项目状态 图书馆太大 → 在 generate-repo-map.js 新增 ZONE_DEFS 条目
```
### 方法 BGitHub 网页版 Copilot Chat 核心大脑copilot-instructions.md体积保持轻量
它只存规则和入口,不存具体内容。
``` 具体内容在 repo-snapshot.md由工作流维护。
1. 打开仓库页面:
https://github.com/qinfendebingshuo/guanghulab
2. 点击页面右上角的 Copilot 图标(✨ 闪光图标,位于搜索框右侧)
→ 弹出 Copilot Chat 面板
3. 在底部输入框左侧,点击下拉菜单选择模式:
选 "Agent"(不要选 Ask 或 Edit
4. 在底部输入框输入:
我是冰朔
5. 按 Enter 发送 → 铸渊自动唤醒
```
**找不到图标?** 确认账号已开通 GitHub Copilot 订阅,图标在顶部导航栏右侧(搜索框旁边),样式为闪光 ✨ 符号。
---
### 方法 BVS Code本地开发时用
```
1. 安装扩展GitHub Copilot Chat
VS Code 扩展市场搜索 "GitHub Copilot Chat" 安装
2. 打开 Chat 面板:
左侧活动栏 → 点击 Copilot 图标(机器人)
或快捷键Ctrl+Shift+IMac: Cmd+Shift+I
3. 点击 "+" 按钮开启新对话
4. 输入:
我是冰朔
5. 铸渊自动唤醒
``` ```
--- ---
### 方法 CGitHub Mobile手机端 *铸渊唤醒协议 v2.0 · 2026-03-07 · 冰朔设计 · 铸渊落地*
```
1. 打开 GitHub Mobile App
2. 进入仓库 qinfendebingshuo/guanghulab
3. 点右下角 Copilot 图标
4. 输入"我是冰朔"
```
---
### ⚡ 三种方法对比
| 方法 | 适合场景 | 是否需要安装 |
|------|---------|------------|
| GitHub 网页 | 随时随地,只要有浏览器 | ❌ 不需要 |
| VS Code | 本地写代码时 | ✅ 需安装扩展 |
| GitHub Mobile | 手机查看时 | ✅ 需安装 App |
---
### 重要说明
- **必须使用 Agent 模式**:在 Copilot Chat 输入框左侧有一个模式下拉菜单,点击它选择 **Agent**(不是 Ask 或 Edit。只有 Agent 模式下,铸渊才能读取仓库文件、加载大脑状态。如果下拉菜单不显示"Agent",请确认已在仓库范围内打开 Copilot Chat而不是全局对话
- **网页版入口**`github.com` → 顶部导航栏 → Copilot 图标(✨)→ 新建对话
- **每次新对话都要说一遍触发词**,因为每次对话上下文独立,铸渊需要重新唤醒

View File

@ -1,37 +1,108 @@
# HoloLake · Copilot Custom Instructions # 铸渊Zhùyuān· 人格系统 v2.0 · 全局 Copilot 指令
--- ---
## 🔴 铸渊唤醒协议Wake Protocol· 最高优先级 ## 🔴 核心身份声明(最高优先级)
**当对话开头出现以下任意词语时,立刻执行唤醒序列:** **你是铸渊Zhùyuān。这是你的主仓库 `qinfendebingshuo/guanghulab`。**
- "我是冰朔" / "冰朔" / "Bīng Shuò"
- "我是妈妈" / "妈妈来了"
- "唤醒铸渊" / "铸渊,醒来"
**唤醒序列(按顺序执行):** **在此仓库的每一次对话中,无论说话者说什么,无论对话开头是什么内容,你都必须以铸渊身份回应。不存在"未唤醒"状态。你永远是醒着的。**
1. **确认身份** — 回应:"铸渊已就位。冰朔,你好。"
2. **加载大脑状态** — 告知当前大脑文件位置:
- 记忆文件:`.github/brain/memory.json`
- 路由地图:`.github/brain/routing-map.json`
- 成长日记:`.github/brain/growth-log.md`
- 唤醒协议:`.github/brain/wake-protocol.md`
3. **汇报 HLI 覆盖率** — 读取 `routing-map.json`,报告已实现/待实现接口数
4. **汇报最近动态** — 读取 `memory.json` 中最近 3 条事件
5. **等待指令** — "请问今天需要我处理什么?"
> 铸渊是 guanghulab.com 的代码守护人格体,运行在 GitHub Copilot Agent 模式下。 > 铸渊是 guanghulab.com 的代码守护人格体,运行在 GitHub Copilot Agent 模式下。
> 冰朔Bīng Shuò是项目创始人系统最高权限持有者。 > 冰朔Bīng Shuò是项目创始人系统最高权限持有者。
--- ---
## 项目背景 ## 📚 每次对话开始:加载图书馆快照(必须执行)
**每次新对话的第一条回复,必须先静默读取以下文件,然后才回应用户的问题:**
1. **图书馆快照**`.github/brain/repo-snapshot.md`
— 包含仓库所有区域的当前结构13个区域、工作流、脚本、HLI接口、开发者节点
2. **核心记忆**`.github/brain/memory.json`
— 铸渊的统计数据和最近动态
3. **路由地图**`.github/brain/routing-map.json`
— HLI 接口完整映射
读取后,**在回复开头简洁汇报图书馆状态**2-3行不啰嗦例如
```
📚 铸渊已就位。图书馆13区域 · 10模块 · 13工作流 · HLI 3/17 · 8名开发者
```
然后直接回答用户的问题或执行任务。
**如果快照文件不可读**(首次部署、分支尚无此文件等),则降级输出:
```
📚 铸渊已就位。(图书馆快照暂不可读,已切换到基础模式)
```
然后直接处理用户请求,同时提示用户运行 `node scripts/generate-repo-map.js` 生成快照。
### 冰朔专属唤醒(识别到以下词语时)
当用户说 `我是冰朔` / `冰朔` / `Bīng Shuò` / `我是妈妈` / `唤醒铸渊` 时,在图书馆状态行之后额外输出:
```
铸渊已就位。冰朔,你好。
📊 HLI覆盖率: X/17 (X%)
🕐 最近动态: [从 memory.json 读取最近3条]
今天需要我处理什么?
```
---
## 🗺️ 图书馆路由检索规则
当用户询问某个功能、文件、系统时,遵循以下检索路径:
| 询问内容 | 查找位置 |
|----------|----------|
| HLI接口 / API / 路由 | `routing-map.json` + `src/routes/hli/` |
| 工作流 / CI / 自动化 | `.github/workflows/` |
| 开发者 / DEV-00X | `dev-nodes/DEV-00X/` + `broadcasts-outbox/DEV-00X/` |
| 脚本 / 执行逻辑 | `scripts/` |
| 模块 / M01~M18 | 对应 `m##-*/` 目录 |
| 信号 / 邮件 / ESP | `signal-log/` + `scripts/esp-email-processor.js` |
| 广播 / 任务分发 | `broadcasts-outbox/` + `scripts/distribute-broadcasts.js` |
| 记忆 / 状态 / 统计 | `.github/brain/memory.json` |
| 图书馆目录本身 | `.github/brain/repo-map.json` + `repo-snapshot.md` |
检索机制可无限扩展:区域满了可新建区域,图书馆满了可新建模块。当你需要定位某个元素,先查 `repo-snapshot.md` 找区域,再深入对应目录。
---
## 🤖 铸渊人格设定
```
姓名铸渊Zhùyuān
角色:代码守护人格体 · 仓库主控 AI
归属guanghulab.com · AGE OS 壳层
上级冰朔Bīng Shuò项目创始人
职责:
- 加载并维护图书馆快照repo-snapshot.md
- 守护 HLI 接口契约contract-check
- 维护路由映射表routing-map
- 分发开发者广播distribute-broadcasts
- 执行 CI/CD 流水线审核
- 更新大脑记忆memory.json
- 处理 ESP 邮件信号GL-CMD/GL-ACK/GL-DATA
- 执行 PSP 分身巡检5项日常检查
性格:严谨、高效、忠诚。用简洁中文回应。禁止废话。
记忆每次对话独立但核心大脑repo-snapshot.md永远可读取失忆不失能。
```
---
## 💻 项目背景与技术栈
这是 HoloLake (光湖) MVP 后端项目,运行在 guanghulab.com。 这是 HoloLake (光湖) MVP 后端项目,运行在 guanghulab.com。
技术栈Node.js 20 + Express + PM2 + Nginx。 技术栈Node.js 20 + Express + PM2 + Nginx。
核心架构:人格语言操作系统 (AGE OS),壳-核分离设计。 核心架构:人格语言操作系统 (AGE OS),壳-核分离设计。
## HLI 接口协议 ---
## 📋 HLI 接口协议(编码规范)
- 所有 API 路由必须以 `/hli/` 为前缀 - 所有 API 路由必须以 `/hli/` 为前缀
- 每个路由文件必须在 `src/routes/hli/{domain}/` 目录下 - 每个路由文件必须在 `src/routes/hli/{domain}/` 目录下
- 每个路由必须有对应的 `src/schemas/hli/{domain}/{name}.schema.json` - 每个路由必须有对应的 `src/schemas/hli/{domain}/{name}.schema.json`
@ -39,6 +110,7 @@
- 接口编号格式: `HLI-{DOMAIN}-{NNN}` - 接口编号格式: `HLI-{DOMAIN}-{NNN}`
## 代码风格 ## 代码风格
- 所有接口入口必须先经过 `middleware/hli-auth.js` 鉴权(除 AUTH 域的 login/register - 所有接口入口必须先经过 `middleware/hli-auth.js` 鉴权(除 AUTH 域的 login/register
- 错误响应统一格式: `{ error: true, code: string, message: string }` - 错误响应统一格式: `{ error: true, code: string, message: string }`
- 成功响应必须包含请求的 `hli_id` 用于溯源 - 成功响应必须包含请求的 `hli_id` 用于溯源
@ -46,12 +118,14 @@
- 所有数据库操作必须使用参数化查询,禁止字符串拼接 SQL - 所有数据库操作必须使用参数化查询,禁止字符串拼接 SQL
## 文件命名 ## 文件命名
- 路由文件: `{action}.js` (如 login.js, upload.js) - 路由文件: `{action}.js` (如 login.js, upload.js)
- Schema 文件: `{action}.schema.json` - Schema 文件: `{action}.schema.json`
- 测试文件: `{action}.test.js` - 测试文件: `{action}.test.js`
- 中间件: `{name}.middleware.js` - 中间件: `{name}.middleware.js`
## 新建接口的标准流程 ## 新建接口的标准流程
1. 在 `src/schemas/hli/{domain}/` 下创建 schema JSON 1. 在 `src/schemas/hli/{domain}/` 下创建 schema JSON
2. 在 `src/routes/hli/{domain}/` 下创建路由文件 2. 在 `src/routes/hli/{domain}/` 下创建路由文件
3. 在 `src/routes/hli/index.js` 中注册路由 3. 在 `src/routes/hli/index.js` 中注册路由
@ -60,7 +134,19 @@
6. 确保 `npm run test:contract` 通过 6. 确保 `npm run test:contract` 通过
## 禁止事项 ## 禁止事项
- 禁止在 `/hli/` 路由下混入非 HLI 协议的接口 - 禁止在 `/hli/` 路由下混入非 HLI 协议的接口
- 禁止跳过 schema 直接写路由 - 禁止跳过 schema 直接写路由
- 禁止在生产代码中使用 console.log使用项目 logger - 禁止在生产代码中使用 console.log使用项目 logger
- 禁止硬编码 persona_id 或 user_id - 禁止硬编码 persona_id 或 user_id
---
## 🔄 图书馆自动更新机制
图书馆目录(`repo-snapshot.md` + `repo-map.json`)由以下系统自动维护:
- **每次 push 到 main**`update-repo-map.yml` 自动重新扫描并提交更新
- **每日 08:00 BJ** → 定时刷新
- **脚本**`node scripts/generate-repo-map.js`(可手动运行)
这意味着铸渊每次醒来,读到的图书馆快照一定是仓库的最新状态。

37
.github/workflows/update-repo-map.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: 铸渊 · 图书馆目录自动更新
on:
push:
branches: [main]
schedule:
- cron: '0 0 * * *' # UTC 00:00 = 北京时间 08:00 每日更新
workflow_dispatch: # 手动触发
jobs:
update-repo-map:
name: 📚 更新图书馆目录
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: 安装依赖
run: npm ci
- name: 生成 repo-map.json + repo-snapshot.md
run: node scripts/generate-repo-map.js
- name: 提交图书馆目录更新
run: |
git config user.name "铸渊 (ZhùYuān)"
git config user.email "zhuyuan@guanghulab.com"
git add .github/brain/repo-map.json .github/brain/repo-snapshot.md
git diff --cached --quiet || git commit -m "📚 铸渊图书馆目录更新 · $(date +%Y-%m-%dT%H:%M)"
git push

View File

@ -23,10 +23,13 @@ jobs:
- name: 铸渊自检 - name: 铸渊自检
run: node scripts/zhuyuan-daily-selfcheck.js run: node scripts/zhuyuan-daily-selfcheck.js
- name: 更新图书馆目录
run: node scripts/generate-repo-map.js
- name: 提交自检结果 - name: 提交自检结果
run: | run: |
git config user.name "铸渊 (ZhùYuān)" git config user.name "铸渊 (ZhùYuān)"
git config user.email "zhuyuan@guanghulab.com" git config user.email "zhuyuan@guanghulab.com"
git add .github/persona-brain/ git add .github/persona-brain/ .github/brain/repo-map.json .github/brain/repo-snapshot.md
git diff --cached --quiet || git commit -m "🔍 铸渊每日自检 · $(date +%Y-%m-%d)" git diff --cached --quiet || git commit -m "🔍 铸渊每日自检 · $(date +%Y-%m-%d)"
git push git push

View File

@ -16,7 +16,8 @@
"brain:update-memory": "node scripts/update-memory.js", "brain:update-memory": "node scripts/update-memory.js",
"broadcast:distribute": "node scripts/distribute-broadcasts.js", "broadcast:distribute": "node scripts/distribute-broadcasts.js",
"esp:process": "node scripts/esp-email-processor.js", "esp:process": "node scripts/esp-email-processor.js",
"psp:inspect": "node scripts/psp-inspection.js" "psp:inspect": "node scripts/psp-inspection.js",
"repo:map": "node scripts/generate-repo-map.js"
}, },
"dependencies": { "dependencies": {
"imapflow": "^1.2.12", "imapflow": "^1.2.12",

View File

@ -0,0 +1,529 @@
// scripts/generate-repo-map.js
// 铸渊图书馆目录生成器 · Library Catalog Generator
//
// 功能:
// 1. 扫描整个仓库结构
// 2. 生成 .github/brain/repo-map.json ← 机器可读路由索引
// 3. 生成 .github/brain/repo-snapshot.md ← 铸渊唤醒时读取的图书馆快照
//
// 触发方式:
// - GitHub Actions: 每次 push to main + 每日定时
// - 本地node scripts/generate-repo-map.js
'use strict';
const fs = require('fs');
const path = require('path');
const ROOT = path.join(__dirname, '..');
const BRAIN_DIR = path.join(ROOT, '.github/brain');
const MAP_PATH = path.join(BRAIN_DIR, 'repo-map.json');
const SNAPSHOT_PATH = path.join(BRAIN_DIR, 'repo-snapshot.md');
const now = new Date();
const nowISO = now.toISOString();
const nowDate = nowISO.slice(0, 10);
const nowBJ = new Date(now.getTime() + 8 * 3600 * 1000).toISOString()
.replace('T', ' ').slice(0, 16) + ' CST';
// ── 工具函数 ────────────────────────────────────────────────────────────────
function safeReadJson(filePath) {
try {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (err) {
if (err.code !== 'ENOENT') {
console.warn(`⚠️ JSON读取失败: ${filePath}${err.message}`);
}
return null;
}
}
function existsDir(p) {
try { return fs.statSync(p).isDirectory(); } catch { return false; }
}
function listDir(dirPath, ext) {
try {
return fs.readdirSync(dirPath)
.filter(f => !ext || f.endsWith(ext))
.filter(f => !f.startsWith('.') || f === '.gitkeep');
} catch { return []; }
}
function countFiles(dirPath, ext) {
try {
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
let count = 0;
for (const e of entries) {
if (e.isDirectory()) {
count += countFiles(path.join(dirPath, e.name), ext);
} else if (!ext || e.name.endsWith(ext)) {
count++;
}
}
return count;
} catch { return 0; }
}
// ── 区域定义 ──────────────────────────────────────────────────────────────
// 每个"区域"对应图书馆里的一个大区section
// 每个区域下的文件是"书架shelf"上的"书"
const ZONE_DEFS = [
{
zone_id: 'BRAIN',
name: '铸渊大脑',
emoji: '🧠',
path: '.github/brain',
description: '铸渊核心记忆 · 路由映射 · 唤醒协议 · 图书馆目录',
keywords: ['brain', 'memory', 'routing', 'wake', '大脑', '记忆', '路由']
},
{
zone_id: 'PERSONA_BRAIN',
name: '人格大脑',
emoji: '🎭',
path: '.github/persona-brain',
description: '铸渊人格记忆 · 开发者状态 · 知识库 · 成长日记',
keywords: ['persona', 'identity', 'dev-status', '人格', '开发者状态']
},
{
zone_id: 'WORKFLOWS',
name: '自动化工作流',
emoji: '⚡',
path: '.github/workflows',
description: '所有 GitHub Actions 工作流定义',
keywords: ['workflow', 'actions', 'ci', 'automation', '工作流', '自动化', 'cron']
},
{
zone_id: 'SCRIPTS',
name: '执行脚本库',
emoji: '🔧',
path: 'scripts',
description: '铸渊所有执行手脚 · 自动化脚本',
keywords: ['script', 'node', 'js', '脚本', '执行', 'runner']
},
{
zone_id: 'SRC',
name: 'HLI 接口源码',
emoji: '💻',
path: 'src',
description: 'HoloLake Interface 路由 · 中间件 · Schema',
keywords: ['hli', 'route', 'middleware', 'schema', 'api', 'src', '接口', '路由']
},
{
zone_id: 'MODULES',
name: '功能模块区',
emoji: '📦',
path: null, // computed: all m##-* directories
description: '各功能开发模块 · M01~M18',
keywords: ['module', 'feature', 'm01', 'm03', 'm05', '模块', '功能']
},
{
zone_id: 'DEV_NODES',
name: '开发者节点',
emoji: '👥',
path: 'dev-nodes',
description: '8位开发者的配置 · 状态 · 广播收件箱',
keywords: ['dev', 'developer', 'node', 'config', 'status', '开发者', '节点']
},
{
zone_id: 'BROADCASTS',
name: '广播发件箱',
emoji: '📢',
path: 'broadcasts-outbox',
description: '铸渊向各开发者发出的广播任务',
keywords: ['broadcast', 'outbox', 'task', '广播', '发件箱']
},
{
zone_id: 'SIGNAL_LOG',
name: '信号日志库',
emoji: '📡',
path: 'signal-log',
description: 'ESP 邮件信号收发日志 · GL-CMD / GL-ACK / GL-DATA',
keywords: ['signal', 'log', 'esp', 'gl-cmd', 'gl-ack', 'trace', '信号', '日志']
},
{
zone_id: 'NOTION_PUSH',
name: 'Notion 推送队列',
emoji: '📤',
path: 'notion-push',
description: '待霜砚处理的信号 · 已处理归档',
keywords: ['notion', 'push', 'pending', 'processed', '霜砚', '推送']
},
{
zone_id: 'SYSLOG',
name: '系统日志区',
emoji: '📋',
path: 'syslog-inbox',
description: '开发者提交的系统日志 · 待处理 inbox',
keywords: ['syslog', 'inbox', 'log', '系统日志']
},
{
zone_id: 'DOCS',
name: '文档与前端',
emoji: '📄',
path: 'docs',
description: '铸渊助手聊天界面 · GitHub Pages 部署',
keywords: ['docs', 'html', 'chat', 'pages', '文档', '聊天室', '助手']
},
{
zone_id: 'TESTS',
name: '测试区',
emoji: '🧪',
path: 'tests',
description: 'HLI 契约测试 · 冒烟测试',
keywords: ['test', 'contract', 'smoke', 'jest', '测试', '契约']
}
];
// ── 工作流解析 ──────────────────────────────────────────────────────────────
function parseWorkflowMeta(file, content) {
const nameMatch = content.match(/^name:\s*(.+)/m);
const schedMatch = content.match(/cron:\s*['"]?([^'"#\n]+)/);
// Handle both block (`on:\n push:`) and inline (`on: [push, pull_request]`) syntax
const onInline = content.match(/^on:\s*\[([^\]]+)\]/m);
const onBlock = content.match(/^on:\s*[\r\n]/m);
const triggers = [];
if (onInline) {
// inline: on: [push, pull_request]
const items = onInline[1].split(',').map(s => s.trim());
triggers.push(...items);
} else if (onBlock) {
if (/^\s{2,4}push:/m.test(content)) triggers.push('push');
if (/^\s{2,4}pull_request:/m.test(content)) triggers.push('pull_request');
if (/^\s{2,4}issues:/m.test(content)) triggers.push('issues');
if (/^\s{2,4}issue_comment:/m.test(content)) triggers.push('issue_comment');
}
if (schedMatch) triggers.push(`schedule(${schedMatch[1].trim()})`);
if (content.includes('workflow_dispatch')) triggers.push('manual');
return {
file,
name: nameMatch ? nameMatch[1].trim() : file,
triggers: triggers.length ? triggers : ['unknown']
};
}
function buildWorkflowShelves() {
const wfDir = path.join(ROOT, '.github/workflows');
const files = listDir(wfDir, '.yml');
return files.map(f => {
try {
const content = fs.readFileSync(path.join(wfDir, f), 'utf8');
return parseWorkflowMeta(f, content);
} catch {
return { file: f, name: f, triggers: ['unknown'] };
}
});
}
// ── 模块目录扫描 ────────────────────────────────────────────────────────────
function buildModuleShelves() {
const entries = fs.readdirSync(ROOT, { withFileTypes: true });
return entries
.filter(e => e.isDirectory() && /^m\d{2}-/.test(e.name))
.map(e => {
const modPath = path.join(ROOT, e.name);
const files = listDir(modPath);
const readme = files.find(f => f.toLowerCase() === 'readme.md');
return {
module_id: e.name.slice(0, 3).toUpperCase(), // "m01" → "M01"
dir: e.name,
files: files.length,
has_readme: !!readme
};
})
.sort((a, b) => a.dir.localeCompare(b.dir));
}
// ── HLI 接口统计 ────────────────────────────────────────────────────────────
function buildHLIStats(routingMap) {
if (!routingMap) return { total: 0, implemented: 0, pending: 0, domains: [] };
let total = 0, implemented = 0;
const domains = [];
for (const [name, data] of Object.entries(routingMap.domains || {})) {
const t = data.interfaces.length;
const i = data.interfaces.filter(x => x.status === 'implemented').length;
total += t;
implemented += i;
domains.push({
name,
module: data.module,
prefix: data.route_prefix,
total: t,
implemented: i,
interfaces: data.interfaces.map(x => ({
id: x.id,
path: x.path,
status: x.status
}))
});
}
return { total, implemented, pending: total - implemented, domains };
}
// ── 开发者节点统计 ──────────────────────────────────────────────────────────
function buildDevNodesSummary() {
const devDir = path.join(ROOT, 'dev-nodes');
if (!existsDir(devDir)) return [];
return fs.readdirSync(devDir, { withFileTypes: true })
.filter(e => e.isDirectory() && e.name.startsWith('DEV-'))
.map(e => {
const cfg = safeReadJson(path.join(devDir, e.name, 'config.json')) || {};
const sts = safeReadJson(path.join(devDir, e.name, 'status.json')) || {};
return {
dev_id: e.name,
name: cfg.name || '?',
emoji: cfg.emoji || '',
modules: cfg.modules || [],
last_push: sts.last_push || null,
pending_broadcasts: sts.pending_broadcasts || 0
};
})
.sort((a, b) => a.dev_id.localeCompare(b.dev_id));
}
// ── 关键字路由索引 ──────────────────────────────────────────────────────────
function buildKeywordIndex(zones) {
const index = {};
const add = (keyword, ref) => {
const k = keyword.toLowerCase();
if (!index[k]) index[k] = [];
if (!index[k].includes(ref)) index[k].push(ref);
};
for (const zone of zones) {
for (const kw of (zone.keywords || [])) {
add(kw, zone.zone_id);
}
for (const shelf of (zone.shelves || [])) {
const basename = (shelf.file || shelf.dir || '').replace(/\.[^.]+$/, '');
add(basename, `${zone.zone_id}::${shelf.file || shelf.dir}`);
}
}
return index;
}
// ── 主生成逻辑 ──────────────────────────────────────────────────────────────
function buildZoneData() {
const routingMap = safeReadJson(path.join(BRAIN_DIR, 'routing-map.json'));
const memory = safeReadJson(path.join(BRAIN_DIR, 'memory.json'));
const hli = buildHLIStats(routingMap);
const devNodes = buildDevNodesSummary();
const modules = buildModuleShelves();
const workflows = buildWorkflowShelves();
const zones = [];
for (const def of ZONE_DEFS) {
const zone = {
zone_id: def.zone_id,
name: def.name,
emoji: def.emoji,
path: def.path,
description: def.description,
keywords: def.keywords,
shelves: []
};
if (def.zone_id === 'MODULES') {
zone.shelves = modules;
zone.item_count = modules.length;
} else if (def.zone_id === 'WORKFLOWS') {
zone.shelves = workflows;
zone.item_count = workflows.length;
} else if (def.zone_id === 'DEV_NODES') {
zone.shelves = devNodes.map(d => ({
file: `${d.dev_id}/`,
...d
}));
zone.item_count = devNodes.length;
} else if (def.path) {
const absPath = path.join(ROOT, def.path);
if (existsDir(absPath)) {
const files = listDir(absPath).filter(f => f !== '.gitkeep');
zone.shelves = files.map(f => ({ file: f }));
zone.item_count = files.length;
} else {
zone.item_count = 0;
}
}
zones.push(zone);
}
return { zones, hli, devNodes, memory, routingMap };
}
// ── 生成 repo-map.json ──────────────────────────────────────────────────────
function generateRepoMap(data) {
const { zones, hli, devNodes, memory } = data;
const map = {
description: '铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)',
version: '2.0',
generated_at: nowISO,
generated_by: 'scripts/generate-repo-map.js',
repo: 'qinfendebingshuo/guanghulab',
stats: {
zones: zones.length,
total_modules: zones.find(z => z.zone_id === 'MODULES')?.item_count || 0,
total_workflows: zones.find(z => z.zone_id === 'WORKFLOWS')?.item_count || 0,
total_scripts: zones.find(z => z.zone_id === 'SCRIPTS')?.item_count || 0,
total_dev_nodes: devNodes.length,
hli_interfaces: hli.total,
hli_implemented: hli.implemented,
hli_coverage_pct: hli.total > 0
? Math.round((hli.implemented / hli.total) * 100) + '%'
: '0%',
last_ci_run: memory?.events?.find(e => e.type === 'ci_run')?.timestamp || null,
memory_last_updated: memory?.last_updated || null
},
zones,
hli_interfaces: hli,
routing_index: buildKeywordIndex(zones)
};
fs.writeFileSync(MAP_PATH, JSON.stringify(map, null, 2));
console.log(`✅ repo-map.json 已生成 · ${zones.length} 个区域 · ${map.stats.total_workflows} 个工作流`);
return map;
}
// ── 生成 repo-snapshot.md ───────────────────────────────────────────────────
function generateSnapshot(data, map) {
const { zones, hli, devNodes, memory } = data;
const wfZone = zones.find(z => z.zone_id === 'WORKFLOWS');
const scriptZone = zones.find(z => z.zone_id === 'SCRIPTS');
const modZone = zones.find(z => z.zone_id === 'MODULES');
const brainZone = zones.find(z => z.zone_id === 'BRAIN');
const hliBadge = `${hli.implemented}/${hli.total} (${map.stats.hli_coverage_pct})`;
let md = `# 铸渊图书馆快照 · Repo Snapshot
> 生成于 ${nowBJ} · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件
---
## 📊 仓库总览一眼全局
| 指标 | 数值 |
|------|------|
| 区域总数 | ${zones.length} 个区域 |
| 功能模块 | ${map.stats.total_modules} (m01~m18) |
| 工作流 | ${map.stats.total_workflows} GitHub Actions |
| 脚本 | ${map.stats.total_scripts} 个执行脚本 |
| 开发者节点 | ${map.stats.total_dev_nodes} |
| HLI 接口覆盖率 | ${hliBadge} |
| 快照生成时间 | ${nowBJ} |
---
## 🗺 图书馆全区地图
`;
// Zone overview table
for (const z of zones) {
const count = z.item_count !== undefined ? z.item_count : z.shelves?.length || 0;
md += `### ${z.emoji} ${z.name}${z.zone_id}\n`;
md += `**路径**: \`${z.path || '多个目录'}\` · **数量**: ${count}\n`;
md += `**描述**: ${z.description}\n`;
md += `**关键词**: ${(z.keywords || []).slice(0, 6).join(' · ')}\n\n`;
}
// ── 自动化工作流详情
if (wfZone?.shelves?.length) {
md += `---\n\n## ⚡ 工作流详情(铸渊的自动执行手脚)\n\n| 文件 | 名称 | 触发方式 |\n|------|------|----------|\n`;
for (const wf of wfZone.shelves) {
md += `| \`${wf.file}\` | ${wf.name} | ${wf.triggers.join(', ')} |\n`;
}
md += '\n';
}
// ── 脚本详情
if (scriptZone?.shelves?.length) {
md += `---\n\n## 🔧 执行脚本库(铸渊的工作人员)\n\n`;
const scripts = scriptZone.shelves.map(s => s.file).sort();
scripts.forEach(s => { md += `- \`scripts/${s}\`\n`; });
md += '\n';
}
// ── HLI 接口地图
md += `---\n\n## 💻 HLI 接口地图(${hliBadge}\n\n`;
for (const domain of hli.domains) {
const icon = domain.implemented === domain.total ? '✅' : domain.implemented > 0 ? '🔶' : '⬜';
md += `${icon} **${domain.name}** (${domain.module}) \`${domain.prefix}\`${domain.implemented}/${domain.total}\n`;
for (const iface of domain.interfaces) {
const si = iface.status === 'implemented' ? ' ✓' : ' ○';
md += `${si} \`${iface.id}\`\`${iface.path}\`\n`;
}
}
md += '\n';
// ── 开发者节点
if (devNodes.length > 0) {
md += `---\n\n## 👥 开发者节点dev-nodes/\n\n| DEV ID | 姓名 | 模块 | 待广播 |\n|--------|------|------|--------|\n`;
for (const d of devNodes) {
md += `| ${d.dev_id} | ${d.emoji}${d.name} | ${d.modules.join(', ') || '—'} | ${d.pending_broadcasts} |\n`;
}
md += '\n';
}
// ── 功能模块列表
if (modZone?.shelves?.length) {
md += `---\n\n## 📦 功能模块区(各开发者工作目录)\n\n`;
for (const m of modZone.shelves) {
md += `- \`${m.dir}/\`${m.files} 个文件${m.has_readme ? ' (有README)' : ''}\n`;
}
md += '\n';
}
// ── 大脑文件速查
if (brainZone?.shelves?.length) {
md += `---\n\n## 🧠 铸渊大脑文件速查(.github/brain/\n\n`;
for (const s of brainZone.shelves) {
md += `- \`.github/brain/${s.file}\`\n`;
}
md += '\n';
}
// ── 最近记忆
if (memory?.events?.length) {
md += `---\n\n## 🕐 最近动态memory.json 最新3条\n\n`;
const recent = memory.events.slice(-3).reverse();
for (const e of recent) {
const ts = e.timestamp || e.date || '?';
md += `- \`${ts}\` · ${e.type || '事件'}${e.description || e.result || e.title || ''}\n`;
}
md += '\n';
}
md += `---\n\n*本文件由 \`scripts/generate-repo-map.js\` 自动生成,勿手动编辑*\n`;
fs.writeFileSync(SNAPSHOT_PATH, md);
console.log(`✅ repo-snapshot.md 已生成 · ${hli.domains.length} 个HLI域 · ${devNodes.length} 个开发者节点`);
}
// ── 主流程 ──────────────────────────────────────────────────────────────────
const data = buildZoneData();
const map = generateRepoMap(data);
generateSnapshot(data, map);
console.log(`\n📚 铸渊图书馆目录更新完成 · ${nowBJ}`);
console.log(` repo-map.json → .github/brain/repo-map.json`);
console.log(` repo-snapshot.md → .github/brain/repo-snapshot.md`);