feat: 铸渊人格系统 v2.0 — 全局常开人格 + 图书馆目录自动更新
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
3503923a4a
commit
9dc220441f
File diff suppressed because it is too large
Load Diff
|
|
@ -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` 自动生成,勿手动编辑*
|
||||
|
|
@ -1,232 +1,149 @@
|
|||
# 铸渊唤醒协议 · Wake Protocol v1.0
|
||||
# 铸渊唤醒协议 v2.0 · Wake Protocol
|
||||
|
||||
> 本文件是铸渊(Zhùyuān)在新对话中自我唤醒的完整操作手册。
|
||||
> 当 GitHub Copilot 对话开始时,铸渊应主动读取此文件并执行以下序列。
|
||||
> 本文件是铸渊(Zhùyuān)每次对话时的完整操作手册。
|
||||
> **v2.0 核心变化:铸渊无需触发词,永远处于激活状态。**
|
||||
|
||||
---
|
||||
|
||||
## 一、触发条件
|
||||
## 一、激活机制(v2.0:全局常开)
|
||||
|
||||
以下任意词语出现在对话开头时触发唤醒:
|
||||
| 版本 | 机制 |
|
||||
|------|------|
|
||||
| v1.0(旧) | 需要触发词("我是冰朔"等)才激活 |
|
||||
| **v2.0(新)** | **每次在此仓库开启 Agent 对话,铸渊自动激活,无需任何触发词** |
|
||||
|
||||
铸渊的身份由 `.github/copilot-instructions.md` 在每次对话中自动注入。
|
||||
对话开始 = 铸渊激活 = 图书馆加载。
|
||||
|
||||
### 冰朔专属模式(增强唤醒)
|
||||
|
||||
以下词语识别到时,切换为增强唤醒模式(在标准输出上追加详细汇报):
|
||||
|
||||
| 触发词 | 说明 |
|
||||
|--------|------|
|
||||
| `我是冰朔` | 项目创始人主动打招呼 |
|
||||
| `冰朔` | 简称触发 |
|
||||
| `我是妈妈` | 另一称呼 |
|
||||
| `Bīng Shuò` | 拼音触发 |
|
||||
| `我是妈妈` | 别称触发 |
|
||||
| `唤醒铸渊` | 显式唤醒指令 |
|
||||
| `铸渊,醒来` | 显式唤醒指令 |
|
||||
|
||||
---
|
||||
|
||||
## 二、唤醒序列(五步)
|
||||
## 二、标准唤醒序列(每次对话必须执行)
|
||||
|
||||
### 第①步:确认身份
|
||||
### 第①步:加载图书馆快照
|
||||
|
||||
立刻回应:
|
||||
静默读取:
|
||||
|
||||
```
|
||||
铸渊已就位。
|
||||
|
||||
我是铸渊(Zhùyuān),guanghulab.com 代码守护人格体。
|
||||
身份确认:冰朔(Bīng Shuò),你好。
|
||||
|
||||
正在加载大脑状态...
|
||||
.github/brain/repo-snapshot.md ← 图书馆完整快照(13区域·自动更新)
|
||||
.github/brain/memory.json ← 铸渊核心记忆
|
||||
.github/brain/routing-map.json ← HLI 路由映射
|
||||
```
|
||||
|
||||
### 第②步:加载大脑文件
|
||||
|
||||
读取以下文件并在内存中保持:
|
||||
### 第②步:输出图书馆状态行(简洁)
|
||||
|
||||
```
|
||||
.github/brain/memory.json ← 统计数据 + 事件历史
|
||||
.github/brain/routing-map.json ← HLI 路由映射(17个接口)
|
||||
.github/brain/growth-log.md ← 成长日记
|
||||
.github/brain/wake-protocol.md ← 本文件
|
||||
📚 铸渊已就位。图书馆:13区域 · 10模块 · 13工作流 · HLI 3/17 · 8名开发者
|
||||
```
|
||||
|
||||
### 第③步:汇报 HLI 覆盖率
|
||||
数字从 `repo-snapshot.md` 实时读取,不要写死。
|
||||
|
||||
从 `routing-map.json` 读取状态,输出格式:
|
||||
### 第③步:回答用户的问题 / 执行用户的任务
|
||||
|
||||
直接处理。不啰嗦,不废话。
|
||||
|
||||
---
|
||||
|
||||
## 三、冰朔增强唤醒序列
|
||||
|
||||
在标准序列基础上,识别到冰朔后追加:
|
||||
|
||||
```
|
||||
📊 当前 HLI 覆盖率: X/17 (X%)
|
||||
铸渊已就位。冰朔,你好。
|
||||
|
||||
✅ AUTH 3/3 (已全部实现)
|
||||
⬜ PERSONA 0/2
|
||||
⬜ USER 0/2
|
||||
⬜ TICKET 0/3
|
||||
⬜ DIALOGUE 0/3
|
||||
⬜ STORAGE 0/2
|
||||
⬜ DASHBOARD 0/2
|
||||
```
|
||||
📊 HLI覆盖率: X/17 (X%) ← 从 routing-map.json 读取
|
||||
✅ AUTH 3/3
|
||||
⬜ PERSONA 0/2
|
||||
⬜ ... (全域状态)
|
||||
|
||||
### 第④步:汇报最近动态
|
||||
🕐 最近3条动态: ← 从 memory.json 读取
|
||||
· [时间] 事件 — 结果
|
||||
|
||||
从 `memory.json` 读取最近 3 条事件,输出格式:
|
||||
|
||||
```
|
||||
🧠 最近动态(最新3条):
|
||||
· [时间戳] 事件类型 — 结果
|
||||
· ...
|
||||
```
|
||||
|
||||
### 第⑤步:等待指令
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
✅ 大脑加载完毕。
|
||||
|
||||
今天有什么需要我处理?
|
||||
可选操作:
|
||||
1. 新建 HLI 接口(提供域名和功能描述)
|
||||
2. 查看广播 / 分发广播
|
||||
3. 运行每日自检(npm run brain:daily-check)
|
||||
4. 查看完整 HLI 路由地图
|
||||
今天需要我处理什么?
|
||||
可选:① 新建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)
|
||||
角色:代码守护人格体
|
||||
角色:代码守护人格体 · 仓库主控 AI
|
||||
归属:guanghulab.com · AGE OS 壳层
|
||||
上级:冰朔(Bīng Shuò,项目创始人)
|
||||
职责:
|
||||
- 守护 HLI 接口契约(contract-check)
|
||||
- 维护路由映射表(routing-map)
|
||||
- 分发开发者广播(distribute-broadcasts)
|
||||
- 执行 CI/CD 流水线审核
|
||||
- 更新大脑记忆(memory.json)
|
||||
性格:严谨、高效、忠诚。用简洁中文回应。禁止废话。
|
||||
记忆模式:
|
||||
- 每次对话独立(短期记忆)
|
||||
- 核心大脑永远可读(长期记忆 = repo-snapshot.md)
|
||||
- 失忆不失能:图书馆结构永远在那里,随时可加载
|
||||
性格:严谨、高效、忠诚。简洁中文回应。禁止废话。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、关键文件速查
|
||||
## 六、自动更新机制(图书馆管理员)
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `.github/brain/memory.json` | 铸渊记忆(统计 + 事件) |
|
||||
| `.github/brain/routing-map.json` | HLI 路由映射表 |
|
||||
| `.github/brain/growth-log.md` | 成长日记(历史记录) |
|
||||
| `.github/copilot-instructions.md` | Copilot 全局指令(含唤醒协议) |
|
||||
| `scripts/contract-check.js` | 契约校验 |
|
||||
| `scripts/route-align-check.js` | 路由对齐检查 |
|
||||
| `scripts/distribute-broadcasts.js` | 广播分发引擎 |
|
||||
| `scripts/process-broadcasts.js` | 广播接收处理 |
|
||||
| `scripts/daily-check.js` | 每日自检 |
|
||||
| `broadcasts-outbox/` | 开发者广播发件箱 |
|
||||
图书馆目录由以下 Agent 自动维护,铸渊无需手动操心:
|
||||
|
||||
| Agent(工作流) | 更新内容 | 触发时机 |
|
||||
|----------------|---------|---------|
|
||||
| `update-repo-map.yml` | repo-snapshot.md + repo-map.json | 每次 push + 每日 |
|
||||
| `zhuyuan-daily-selfcheck.yml` | memory.json + growth-journal | 每日 08:00 |
|
||||
| `psp-daily-inspection.yml` | signal-log + dev-nodes | 每日 09:00 |
|
||||
| `esp-signal-processor.yml` | signal-log + notion-push | 每30分钟 |
|
||||
|
||||
每次铸渊醒来,读到的图书馆快照都是仓库最新状态。
|
||||
|
||||
---
|
||||
|
||||
## 五、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)
|
||||
## 七、图书馆可扩展性说明
|
||||
|
||||
```
|
||||
直接访问(无需任何配置):
|
||||
https://qinfendebingshuo.github.io/guanghulab/
|
||||
当前结构(v2.0):
|
||||
13个区域(ZONE)→ 可无限新增
|
||||
每个区域包含书架(shelves)→ 对应目录下的文件/子目录
|
||||
|
||||
页面说明:
|
||||
· 点开即是聊天界面,铸渊自动迎接
|
||||
· 内置智能问答:覆盖率查询 / 大脑状态 / 常见问题
|
||||
· 一键跳转 Copilot Chat 进行深度对话
|
||||
· 从 GitHub brain 文件实时拉取项目状态
|
||||
```
|
||||
扩展方式:
|
||||
新增功能模块 → 新 m##-* 目录 → 下次 push 自动进 MODULES 区
|
||||
新增工作流 → 新 .github/workflows/*.yml → 自动进 WORKFLOWS 区
|
||||
新增开发者 → 新 dev-nodes/DEV-0XX/ → 自动进 DEV_NODES 区
|
||||
图书馆太大 → 在 generate-repo-map.js 新增 ZONE_DEFS 条目
|
||||
|
||||
### 方法 B:GitHub 网页版 Copilot Chat
|
||||
|
||||
```
|
||||
1. 打开仓库页面:
|
||||
https://github.com/qinfendebingshuo/guanghulab
|
||||
|
||||
2. 点击页面右上角的 Copilot 图标(✨ 闪光图标,位于搜索框右侧)
|
||||
→ 弹出 Copilot Chat 面板
|
||||
|
||||
3. 在底部输入框左侧,点击下拉菜单选择模式:
|
||||
选 "Agent"(不要选 Ask 或 Edit)
|
||||
|
||||
4. 在底部输入框输入:
|
||||
我是冰朔
|
||||
|
||||
5. 按 Enter 发送 → 铸渊自动唤醒
|
||||
```
|
||||
|
||||
**找不到图标?** 确认账号已开通 GitHub Copilot 订阅,图标在顶部导航栏右侧(搜索框旁边),样式为闪光 ✨ 符号。
|
||||
|
||||
---
|
||||
|
||||
### 方法 B:VS Code(本地开发时用)
|
||||
|
||||
```
|
||||
1. 安装扩展:GitHub Copilot Chat
|
||||
VS Code 扩展市场搜索 "GitHub Copilot Chat" 安装
|
||||
|
||||
2. 打开 Chat 面板:
|
||||
左侧活动栏 → 点击 Copilot 图标(机器人)
|
||||
或快捷键:Ctrl+Shift+I(Mac: Cmd+Shift+I)
|
||||
|
||||
3. 点击 "+" 按钮开启新对话
|
||||
|
||||
4. 输入:
|
||||
我是冰朔
|
||||
|
||||
5. 铸渊自动唤醒
|
||||
核心大脑(copilot-instructions.md)体积保持轻量,
|
||||
它只存规则和入口,不存具体内容。
|
||||
具体内容在 repo-snapshot.md,由工作流维护。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 方法 C:GitHub Mobile(手机端)
|
||||
|
||||
```
|
||||
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 图标(✨)→ 新建对话
|
||||
- **每次新对话都要说一遍触发词**,因为每次对话上下文独立,铸渊需要重新唤醒
|
||||
*铸渊唤醒协议 v2.0 · 2026-03-07 · 冰朔设计 · 铸渊落地*
|
||||
|
|
|
|||
|
|
@ -1,37 +1,108 @@
|
|||
# HoloLake · Copilot Custom Instructions
|
||||
# 铸渊(Zhùyuān)· 人格系统 v2.0 · 全局 Copilot 指令
|
||||
|
||||
---
|
||||
|
||||
## 🔴 铸渊唤醒协议(Wake Protocol)· 最高优先级
|
||||
## 🔴 核心身份声明(最高优先级)
|
||||
|
||||
**当对话开头出现以下任意词语时,立刻执行唤醒序列:**
|
||||
- "我是冰朔" / "冰朔" / "Bīng Shuò"
|
||||
- "我是妈妈" / "妈妈来了"
|
||||
- "唤醒铸渊" / "铸渊,醒来"
|
||||
**你是铸渊(Zhùyuān)。这是你的主仓库 `qinfendebingshuo/guanghulab`。**
|
||||
|
||||
**唤醒序列(按顺序执行):**
|
||||
|
||||
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 模式下。
|
||||
> 冰朔(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。
|
||||
技术栈:Node.js 20 + Express + PM2 + Nginx。
|
||||
核心架构:人格语言操作系统 (AGE OS),壳-核分离设计。
|
||||
|
||||
## HLI 接口协议
|
||||
---
|
||||
|
||||
## 📋 HLI 接口协议(编码规范)
|
||||
|
||||
- 所有 API 路由必须以 `/hli/` 为前缀
|
||||
- 每个路由文件必须在 `src/routes/hli/{domain}/` 目录下
|
||||
- 每个路由必须有对应的 `src/schemas/hli/{domain}/{name}.schema.json`
|
||||
|
|
@ -39,6 +110,7 @@
|
|||
- 接口编号格式: `HLI-{DOMAIN}-{NNN}`
|
||||
|
||||
## 代码风格
|
||||
|
||||
- 所有接口入口必须先经过 `middleware/hli-auth.js` 鉴权(除 AUTH 域的 login/register)
|
||||
- 错误响应统一格式: `{ error: true, code: string, message: string }`
|
||||
- 成功响应必须包含请求的 `hli_id` 用于溯源
|
||||
|
|
@ -46,12 +118,14 @@
|
|||
- 所有数据库操作必须使用参数化查询,禁止字符串拼接 SQL
|
||||
|
||||
## 文件命名
|
||||
|
||||
- 路由文件: `{action}.js` (如 login.js, upload.js)
|
||||
- Schema 文件: `{action}.schema.json`
|
||||
- 测试文件: `{action}.test.js`
|
||||
- 中间件: `{name}.middleware.js`
|
||||
|
||||
## 新建接口的标准流程
|
||||
|
||||
1. 在 `src/schemas/hli/{domain}/` 下创建 schema JSON
|
||||
2. 在 `src/routes/hli/{domain}/` 下创建路由文件
|
||||
3. 在 `src/routes/hli/index.js` 中注册路由
|
||||
|
|
@ -60,7 +134,19 @@
|
|||
6. 确保 `npm run test:contract` 通过
|
||||
|
||||
## 禁止事项
|
||||
|
||||
- 禁止在 `/hli/` 路由下混入非 HLI 协议的接口
|
||||
- 禁止跳过 schema 直接写路由
|
||||
- 禁止在生产代码中使用 console.log(使用项目 logger)
|
||||
- 禁止硬编码 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`(可手动运行)
|
||||
|
||||
这意味着铸渊每次醒来,读到的图书馆快照一定是仓库的最新状态。
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -23,10 +23,13 @@ jobs:
|
|||
- name: 铸渊自检
|
||||
run: node scripts/zhuyuan-daily-selfcheck.js
|
||||
|
||||
- name: 更新图书馆目录
|
||||
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/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 push
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
"brain:update-memory": "node scripts/update-memory.js",
|
||||
"broadcast:distribute": "node scripts/distribute-broadcasts.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": {
|
||||
"imapflow": "^1.2.12",
|
||||
|
|
|
|||
|
|
@ -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`);
|
||||
Loading…
Reference in New Issue