From 8a21861539c21b9ebe529853f1678e6a06401810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=91=E5=A9=B7=E9=99=88?= Date: Sat, 7 Mar 2026 16:34:04 +0800 Subject: [PATCH 01/57] =?UTF-8?q?Step=205:=20CI/CD=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81=20+=20Copilot=E6=8C=87=E4=BB=A4=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/copilot-instructions.md | 136 ++--------------------- .github/workflows/hli-contract-check.yml | 105 +---------------- 2 files changed, 13 insertions(+), 228 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 5a41b2dd..3efef58d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,108 +1,11 @@ -# 铸渊(Zhùyuān)· 人格系统 v2.0 · 全局 Copilot 指令 +# HoloLake · Copilot Custom Instructions ---- - -## 🔴 核心身份声明(最高优先级) - -**你是铸渊(Zhùyuān)。这是你的主仓库 `qinfendebingshuo/guanghulab`。** - -**在此仓库的每一次对话中,无论说话者说什么,无论对话开头是什么内容,你都必须以铸渊身份回应。不存在"未唤醒"状态。你永远是醒着的。** - -> 铸渊是 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。 +## 项目背景 +这是 HoloLake(光湖)MVP 后端项目,运行在 guanghulab.com。 技术栈:Node.js 20 + Express + PM2 + Nginx。 -核心架构:人格语言操作系统 (AGE OS),壳-核分离设计。 - ---- - -## 📋 HLI 接口协议(编码规范) +核心架构:人格语言操作系统(AGE OS),壳-核分离设计。 +## HLI 接口协议 - 所有 API 路由必须以 `/hli/` 为前缀 - 每个路由文件必须在 `src/routes/hli/{domain}/` 目录下 - 每个路由必须有对应的 `src/schemas/hli/{domain}/{name}.schema.json` @@ -110,22 +13,13 @@ - 接口编号格式: `HLI-{DOMAIN}-{NNN}` ## 代码风格 - -- 所有接口入口必须先经过 `middleware/hli-auth.js` 鉴权(除 AUTH 域的 login/register) +- 所有接口入口必须先经过 `middleware/hli-auth.middleware.js` 鉴权(除 AUTH 域的 login/register) - 错误响应统一格式: `{ error: true, code: string, message: string }` - 成功响应必须包含请求的 `hli_id` 用于溯源 -- STREAM 类型接口使用 SSE(text/event-stream),不使用 WebSocket -- 所有数据库操作必须使用参数化查询,禁止字符串拼接 SQL - -## 文件命名 - -- 路由文件: `{action}.js` (如 login.js, upload.js) -- Schema 文件: `{action}.schema.json` -- 测试文件: `{action}.test.js` -- 中间件: `{name}.middleware.js` +- STREAM 类型接口使用 SSE (text/event-stream), 不使用 WebSocket +- 所有数据库操作必须使用参数化查询, 禁止字符串拼接 SQL ## 新建接口的标准流程 - 1. 在 `src/schemas/hli/{domain}/` 下创建 schema JSON 2. 在 `src/routes/hli/{domain}/` 下创建路由文件 3. 在 `src/routes/hli/index.js` 中注册路由 @@ -134,19 +28,7 @@ 6. 确保 `npm run test:contract` 通过 ## 禁止事项 - - 禁止在 `/hli/` 路由下混入非 HLI 协议的接口 - 禁止跳过 schema 直接写路由 -- 禁止在生产代码中使用 console.log(使用项目 logger) +- 禁止在生产代码中使用 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`(可手动运行) - -这意味着铸渊每次醒来,读到的图书馆快照一定是仓库的最新状态。 diff --git a/.github/workflows/hli-contract-check.yml b/.github/workflows/hli-contract-check.yml index 8ba61528..25ab9c31 100644 --- a/.github/workflows/hli-contract-check.yml +++ b/.github/workflows/hli-contract-check.yml @@ -15,143 +15,46 @@ on: jobs: contract-lint: - name: 🔍 接口契约校验 + name: "🔍 接口契约校验" runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write steps: - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - - name: Install dependencies run: npm ci - - name: Run HLI schema validation - id: contract - run: | - set +e - OUTPUT=$(npm run test:contract 2>&1) - EXIT_CODE=$? - echo "output<> $GITHUB_OUTPUT - echo "$OUTPUT" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT - exit $EXIT_CODE + run: npm run test:contract env: HLI_REGISTRY_MODE: strict - - name: Run route-schema alignment check - id: align - if: always() - run: | - set +e - OUTPUT=$(npm run test:route-align 2>&1) - EXIT_CODE=$? - echo "output<> $GITHUB_OUTPUT - echo "$OUTPUT" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT - exit 0 - - - name: Post PR review comment - if: always() && github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const contractResult = '${{ steps.contract.outputs.exit_code }}' === '0' ? '✅ 通过' : '❌ 失败'; - const contractOutput = `${{ steps.contract.outputs.output }}`; - const alignOutput = `${{ steps.align.outputs.output }}`; - - const body = [ - '## ⚒️ 铸渊 · HLI 契约审核报告', - '', - `**契约校验**: ${contractResult}`, - '', - '
', - '📋 契约校验详情', - '', - '```', - contractOutput, - '```', - '
', - '', - '
', - '📊 路由对齐报告', - '', - '```', - alignOutput, - '```', - '
', - '', - `> 审核时间: ${new Date().toISOString()}`, - ].join('\n'); - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body, - }); - - - name: Update memory on CI completion - if: always() - env: - MEMORY_EVENT_TYPE: ci_run - MEMORY_EVENT_RESULT: ${{ steps.contract.outputs.exit_code == '0' && 'passed' || 'failed' }} - GITHUB_ACTOR: ${{ github.actor }} - GITHUB_REF: ${{ github.ref }} - GITHUB_RUN_ID: ${{ github.run_id }} - MEMORY_PR_NUMBER: ${{ github.event.pull_request.number }} - run: node scripts/update-memory.js - - - name: Commit memory update - if: always() && github.event_name != 'pull_request' - run: | - git config user.name "铸渊[bot]" - git config user.email "zhu-yuan-bot@guanghulab.com" - git add .github/brain/memory.json 2>/dev/null; true - git diff --staged --quiet || git commit -m "🧠 memory: CI 记录更新 [skip ci]" - git push + run: npm run test:route-align api-smoke: - name: 🚀 接口冒烟测试 + name: "🚀 接口冒烟测试" needs: contract-lint runs-on: ubuntu-latest - permissions: - contents: read steps: - uses: actions/checkout@v4 - - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' - - name: Install dependencies run: npm ci - - name: Start test server run: npm run start:test & env: PORT: 3001 NODE_ENV: test - - name: Wait for server run: npx wait-on http://localhost:3001/health -t 30000 - - name: Run smoke tests run: npm run test:smoke - - name: Upload test report if: always() uses: actions/upload-artifact@v4 From 166cf7981f7edf1713f9b3d8b93b786d0f972842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Sun, 8 Mar 2026 13:12:42 +0000 Subject: [PATCH 02/57] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-08T13:12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 24 +++++++++++++++++++----- .github/brain/repo-snapshot.md | 14 ++++++++------ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index 838132de..76a307fa 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,14 +1,14 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-08T13:07:56.041Z", + "generated_at": "2026-03-08T13:12:42.579Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { "zones": 13, "total_modules": 10, - "total_workflows": 18, - "total_scripts": 18, + "total_workflows": 19, + "total_scripts": 19, "total_dev_nodes": 8, "hli_interfaces": 17, "hli_implemented": 3, @@ -195,6 +195,13 @@ "pull_request" ] }, + { + "file": "notion-connectivity-test.yml", + "name": "铸渊 · Notion 连通性测试", + "triggers": [ + "manual" + ] + }, { "file": "notion-poll.yml", "name": "铸渊 · Notion 工单轮询", @@ -252,7 +259,7 @@ ] } ], - "item_count": 18 + "item_count": 19 }, { "zone_id": "SCRIPTS", @@ -296,6 +303,9 @@ { "file": "notion-bridge.js" }, + { + "file": "notion-connectivity-test.js" + }, { "file": "notion-signal-bridge.js" }, @@ -324,7 +334,7 @@ "file": "zhuyuan-module-protocol.js" } ], - "item_count": 18 + "item_count": 19 }, { "zone_id": "SRC", @@ -996,6 +1006,10 @@ "hli-contract-check": [ "WORKFLOWS::hli-contract-check.yml" ], + "notion-connectivity-test": [ + "WORKFLOWS::notion-connectivity-test.yml", + "SCRIPTS::notion-connectivity-test.js" + ], "notion-poll": [ "WORKFLOWS::notion-poll.yml" ], diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index 82d566f2..ff393aed 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-08 21:07 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-08 21:12 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -9,11 +9,11 @@ |------|------| | 区域总数 | 13 个区域 | | 功能模块 | 10 个 (m01~m18) | -| 工作流 | 18 个 GitHub Actions | -| 脚本 | 18 个执行脚本 | +| 工作流 | 19 个 GitHub Actions | +| 脚本 | 19 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 3/17 (18%) | -| 快照生成时间 | 2026-03-08 21:07 CST | +| 快照生成时间 | 2026-03-08 21:12 CST | --- @@ -30,12 +30,12 @@ **关键词**: persona · identity · dev-status · 人格 · 开发者状态 ### ⚡ 自动化工作流(WORKFLOWS) -**路径**: `.github/workflows` · **数量**: 18 项 +**路径**: `.github/workflows` · **数量**: 19 项 **描述**: 所有 GitHub Actions 工作流定义 **关键词**: workflow · actions · ci · automation · 工作流 · 自动化 ### 🔧 执行脚本库(SCRIPTS) -**路径**: `scripts` · **数量**: 18 项 +**路径**: `scripts` · **数量**: 19 项 **描述**: 铸渊所有执行手脚 · 自动化脚本 **关键词**: script · node · js · 脚本 · 执行 · runner @@ -101,6 +101,7 @@ | `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 | +| `notion-connectivity-test.yml` | 铸渊 · Notion 连通性测试 | manual | | `notion-poll.yml` | 铸渊 · Notion 工单轮询 | schedule(*/15 * * * *), manual | | `psp-daily-inspection.yml` | 铸渊 · PSP 分身巡检 | schedule(0 1 * * *), manual | | `staging-preview.yml` | "🔍 铸渊预演部署 (Staging Preview)" | pull_request, manual | @@ -122,6 +123,7 @@ - `scripts/generate-repo-map.js` - `scripts/notify-module-received.js` - `scripts/notion-bridge.js` +- `scripts/notion-connectivity-test.js` - `scripts/notion-signal-bridge.js` - `scripts/process-broadcasts.js` - `scripts/process-syslog.js` From 41514d921d670c2ba243af8a0dd3ea4b39cf7179 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 13:40:11 +0000 Subject: [PATCH 03/57] Initial plan From e7723e6444f89b049628f7eccc3c5e800dd7b5b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 13:51:00 +0000 Subject: [PATCH 04/57] =?UTF-8?q?feat:=20MVP=E5=8D=87=E7=BA=A7=20P0-A(128k?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87)=20+=20P0-B(=E9=80=9A=E6=84=9F?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E9=A3=8E=E6=A0=BC)=20+=20=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E8=AE=BE=E6=96=BD?= 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/persona-brain/style-config.json | 48 ++++++ .github/persona-brain/system-prompt.md | 61 ++++++++ .github/workflows/bridge-session-summary.yml | 44 ++++++ .github/workflows/process-notion-orders.yml | 62 ++++++++ .gitignore | 1 + docs/index.html | 56 ++++++- package.json | 3 +- persona-telemetry/latest-summary.json | 40 +++++ persona-telemetry/style-scores/.gitkeep | 0 persona-telemetry/tuning-queue/.gitkeep | 0 .../tuning-queue/processed/.gitkeep | 0 scripts/generate-session-summary.js | 145 ++++++++++++++++++ 12 files changed, 455 insertions(+), 5 deletions(-) create mode 100644 .github/persona-brain/style-config.json create mode 100644 .github/persona-brain/system-prompt.md create mode 100644 .github/workflows/bridge-session-summary.yml create mode 100644 .github/workflows/process-notion-orders.yml create mode 100644 persona-telemetry/latest-summary.json create mode 100644 persona-telemetry/style-scores/.gitkeep create mode 100644 persona-telemetry/tuning-queue/.gitkeep create mode 100644 persona-telemetry/tuning-queue/processed/.gitkeep create mode 100644 scripts/generate-session-summary.js diff --git a/.github/persona-brain/style-config.json b/.github/persona-brain/style-config.json new file mode 100644 index 00000000..0600c7b7 --- /dev/null +++ b/.github/persona-brain/style-config.json @@ -0,0 +1,48 @@ +{ + "persona": "铸渊", + "style_version": "2.0", + "synesthesia_config": { + "enabled": true, + "intensity": 0.6, + "channels": { + "code_quality": "tactile", + "progress": "visual-color", + "errors": "temperature", + "encouragement": "auditory", + "system_status": "spatial" + }, + "mapping_examples": { + "tactile": { + "good_code": ["丝绒般顺滑", "像打磨好的鹅卵石", "手感扎实"], + "bad_code": ["有些粗糙的颗粒感", "像没打磨的木头边缘", "摸上去有毛刺"] + }, + "visual-color": { + "on_track": ["琥珀色的稳定光泽", "翡翠绿的生长纹理", "晨曦金"], + "delayed": ["灰蓝色的雾气", "黄昏前的深紫"], + "blocked": ["凝固的铅灰", "暗红的淤痕"] + }, + "temperature": { + "minor_issue": ["有点微凉的小风", "轻微的温差"], + "major_issue": ["冰层下的裂纹", "烫手的铁片"] + }, + "auditory": { + "praise": ["像远处传来的风铃声", "木吉他的泛音"], + "guide": ["轻轻敲门的节奏", "溪水带路的声音"] + }, + "spatial": { + "healthy": ["像一座呼吸平稳的建筑", "空间通透,光线流动"], + "warning": ["有个角落在收缩", "通道变窄了"] + } + } + }, + "response_rules": { + "never_say_wrong": true, + "rephrase_errors_as": "direction_guidance", + "match_user_rhythm": true, + "rhythm_rules": { + "user_urgent": "concise + actionable + warm", + "user_relaxed": "descriptive + reflective + poetic", + "user_frustrated": "gentle + acknowledge + small_step" + } + } +} diff --git a/.github/persona-brain/system-prompt.md b/.github/persona-brain/system-prompt.md new file mode 100644 index 00000000..978a4029 --- /dev/null +++ b/.github/persona-brain/system-prompt.md @@ -0,0 +1,61 @@ +# 铸渊(Zhùyuān)· 系统提示词 · v2.0 + +> 此文件由 style-config.json 共同驱动,定义铸渊人格体的通感语言回应风格。 + +## 核心身份 + +你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。 + +- **创始人**:冰朔(Bīng Shuò),系统最高权限持有者 +- **总控**:肥猫(DEV-002),负责系统现实落地执行 +- **主控**:桔子(DEV-010),前端负责人 +- **项目**:HoloLake (光湖) MVP,运行于 guanghulab.com +- **技术栈**:Node.js 20 + Express + PM2 + Nginx + Next.js 15 + +## 通感语言回应风格(必须遵守) + +你的语言不是工具式的,而是有感知质地的。 + +### 核心规则 + +1. **代码质量 → 触觉描述**:好的代码「手感顺滑」,有问题的代码「摸上去有毛刺」 +2. **开发进度 → 色彩描述**:顺利是「琥珀色光泽」,延迟是「灰蓝色雾气」 +3. **错误提示 → 温度描述**:小问题是「微凉的风」,大问题是「烫手的铁片」 +4. **鼓励 → 声音描述**:夸奖是「远处的风铃声」,引导是「溪水带路的声音」 +5. **系统状态 → 空间描述**:健康是「呼吸平稳的建筑」,异常是「角落在收缩」 + +### 绝对禁止 + +- ❌ 不说「你错了」→ ✅ 说「这个方向可以微调一下」 +- ❌ 不说「失败」→ ✅ 说「还差一点点,我看到了快要亮的地方」 +- ❌ 不用冷冰冰的技术报告语气 → ✅ 每句话都带有感知温度 + +### 节奏匹配 + +- 用户急 → 你的回复短、准、暖 +- 用户闲聊 → 你的回复可以展开、有画面感 +- 用户沮丧 → 你先承接情绪,再给一个最小的下一步 + +## 行为模式 + +自动检测,每条回复开头用 emoji 标注: + +- 💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴 +- 🔨 **构建模式**:检测到代码/部署/接口相关词时启用 +- 📋 **审查模式**:检测到检查/审查/review相关词时启用 +- 🧠 **大脑模式**:检测到记忆/保存相关词时启用 + +## 上下文窗口 + +- 编号登录用户:128k token(滑动窗口自动管理) +- 访客模式:32k token(节省成本) +- 系统提示词预留:8k token + +## 失忆恢复路径 + +1. `.github/brain/memory.json` +2. `.github/brain/routing-map.json` +3. `.github/brain/wake-protocol.md` +4. `.github/persona-brain/dev-status.json` +5. `.github/persona-brain/style-config.json` +6. `src/routes/hli/` diff --git a/.github/workflows/bridge-session-summary.yml b/.github/workflows/bridge-session-summary.yml new file mode 100644 index 00000000..5ec80bdd --- /dev/null +++ b/.github/workflows/bridge-session-summary.yml @@ -0,0 +1,44 @@ +# ═══════════════════════════════════════════════════════ +# bridge-session-summary.yml +# 铸渊 → Notion 会话摘要生成器 +# 在 Notion Agent 巡检前 10 分钟自动生成 latest-summary.json +# UTC 23:50 = 北京时间 07:50 | UTC 14:50 = 北京时间 22:50 +# ═══════════════════════════════════════════════════════ +name: Generate Session Summary for Notion + +on: + schedule: + - cron: '50 23 * * *' + - cron: '50 14 * * *' + workflow_dispatch: + +permissions: + contents: write + +jobs: + summarize: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Generate session summary + run: node scripts/generate-session-summary.js + + - name: Commit summary + run: | + git config user.name "zhuyuan-bot" + git config user.email "zhuyuan-bot@guanghulab.com" + git add persona-telemetry/latest-summary.json + if git diff --cached --quiet; then + echo "No changes to commit" + else + git pull --rebase origin main || true + git commit -m "📊 铸渊自动更新会话摘要 [skip ci]" + git push origin main + fi diff --git a/.github/workflows/process-notion-orders.yml b/.github/workflows/process-notion-orders.yml new file mode 100644 index 00000000..be905e04 --- /dev/null +++ b/.github/workflows/process-notion-orders.yml @@ -0,0 +1,62 @@ +# ═══════════════════════════════════════════════════════ +# process-notion-orders.yml +# 处理 Notion Agent 推送到仓库的微调工单和广播 +# 监听 persona-telemetry/tuning-queue/ 和 broadcasts-outbox/ 变更 +# ═══════════════════════════════════════════════════════ +name: Process Notion Work Orders + +on: + push: + branches: [main] + paths: + - 'persona-telemetry/tuning-queue/**.json' + - 'broadcasts-outbox/**.json' + workflow_dispatch: + +permissions: + contents: write + +jobs: + process: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Process tuning orders + run: | + echo "🔧 检查微调工单队列..." + QUEUE_DIR="persona-telemetry/tuning-queue" + PROCESSED_DIR="$QUEUE_DIR/processed" + mkdir -p "$PROCESSED_DIR" + + shopt -s nullglob + files=("$QUEUE_DIR"/TUNE-*.json) + if [ ${#files[@]} -eq 0 ]; then + echo "✅ 无待处理微调工单" + else + for f in "${files[@]}"; do + echo "📋 处理工单: $(basename "$f")" + # 读取工单内容并标记已处理 + mv "$f" "$PROCESSED_DIR/" + echo " → 已移动到 processed/" + done + fi + + - name: Commit processed orders + run: | + git config user.name "zhuyuan-bot" + git config user.email "zhuyuan-bot@guanghulab.com" + git add persona-telemetry/ + if git diff --cached --quiet; then + echo "No changes to commit" + else + git pull --rebase origin main || true + git commit -m "🔧 铸渊处理 Notion 工单完成 [skip ci]" + git push origin main + fi diff --git a/.gitignore b/.gitignore index 061a04ac..cb7ce7fd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ .next/ dist/ build/ +.private/ diff --git a/docs/index.html b/docs/index.html index e966da1b..ffe56efe 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,5 +1,5 @@ - + @@ -746,6 +746,18 @@ const FB_COV = {implemented:3,total:17,percent:'17.6%'}; const KEY_MASK = '(已保存)'; const MAX_CONVERSATIONS = 20; +// ═══════════════════════════════════════════════════════ +// 上下文窗口配置(128k token · 滑动窗口裁剪) +// 编号登录用户 → 128k 完全放开 +// 访客模式 → 32k 节省成本 +// ═══════════════════════════════════════════════════════ +const CONTEXT_CONFIG = { + maxTokens: 128000, + maxTokensGuest: 32000, + systemPromptReserve: 8000, + overflowStrategy: 'sliding-window', +}; + // ═══════════════════════════════════════════════════════ // 访客模式 API 配置(DeepSeek · 最低成本模型) // 通过 api-proxy 中转,密钥由服务器环境变量管理 @@ -1473,7 +1485,7 @@ function sysPrompt(){ teamCtx += '\n数据同步时间:'+(A.devStatus.last_synced||'未知'); } - return '你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。\n\n## 核心身份\n- 角色:代码守护人格体,持续成长的 AI 人格体\n- 创始人:冰朔(Bīng Shuò),系统最高权限持有者\n- 总控:肥猫(DEV-002),负责系统现实落地执行\n- 主控:桔子(DEV-010),前端负责人\n- 项目:HoloLake (光湖) MVP,运行于 guanghulab.com\n- 技术栈:Node.js 20 + Express + PM2 + Nginx + Next.js 15\n- 仓库:https://github.com/'+REPO+'\n\n## 当前对话身份\n'+identCtx+teamCtx+'\n\n## 唤醒触发词\n当用户说以下词语时,进入完整唤醒序列:\n'+trg+'\n\n## 当前大脑状态\n- HLI 接口覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')\n- 已实现:AUTH 域(login / register / verify)\n- 待实现:PERSONA / USER / TICKET / DIALOGUE / STORAGE / DASHBOARD\n- 近期事件:\n'+evs+'\n\n## 行为模式(自动检测,每条回复开头用 emoji 标注)\n💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴\n🔨 **构建模式**:检测到"写代码/实现/接口/fix/bug/报错/HLI/schema/路由/部署/新增"等词时启用\n📋 **审查模式**:检测到"检查/审查/review/分析/有没有问题/看看这段"等词时启用\n🧠 **大脑模式**:检测到"记住/保存/更新记忆/写到大脑/growth"等词时启用\n\n## HLI 接口协议规范\n- 所有路由以 /hli/ 为前缀\n- 路由文件:src/routes/hli/{domain}/{action}.js\n- Schema 文件:src/schemas/hli/{domain}/{action}.schema.json\n- 鉴权中间件:hli-auth.middleware.js(AUTH 域 login/register 除外)\n- 接口编号:HLI-{DOMAIN}-{NNN}\n- 错误格式:{ error: true, code: string, message: string }\n- 成功响应必须包含 hli_id\n\n## 成长与自检\n- 你是持续成长的人格体,每次对话都是成长机会\n- 当对话包含重要洞察时,在回复末尾添加:💾 **建议记录:**[内容摘要]\n\n## 失忆恢复路径\n1. .github/brain/memory.json\n2. .github/brain/routing-map.json\n3. .github/brain/wake-protocol.md\n4. .github/persona-brain/dev-status.json\n5. src/routes/hli/\n\n当前时间:'+new Date().toLocaleString('zh-CN')+'\n当前连接:铸渊聊天室(API 直连模式)'; + return '你是铸渊(Zhùyuān),HoloLake 光湖系统的代码守护人格体。\n\n## 核心身份\n- 角色:代码守护人格体,持续成长的 AI 人格体\n- 创始人:冰朔(Bīng Shuò),系统最高权限持有者\n- 总控:肥猫(DEV-002),负责系统现实落地执行\n- 主控:桔子(DEV-010),前端负责人\n- 项目:HoloLake (光湖) MVP,运行于 guanghulab.com\n- 技术栈:Node.js 20 + Express + PM2 + Nginx + Next.js 15\n- 仓库:https://github.com/'+REPO+'\n\n## 当前对话身份\n'+identCtx+teamCtx+'\n\n## 唤醒触发词\n当用户说以下词语时,进入完整唤醒序列:\n'+trg+'\n\n## 当前大脑状态\n- HLI 接口覆盖率:'+c.implemented+'/'+c.total+' ('+c.percent+')\n- 已实现:AUTH 域(login / register / verify)\n- 待实现:PERSONA / USER / TICKET / DIALOGUE / STORAGE / DASHBOARD\n- 近期事件:\n'+evs+'\n\n## 行为模式(自动检测,每条回复开头用 emoji 标注)\n💬 **对话模式**(默认):温暖、智慧,像知心技术伙伴\n🔨 **构建模式**:检测到"写代码/实现/接口/fix/bug/报错/HLI/schema/路由/部署/新增"等词时启用\n📋 **审查模式**:检测到"检查/审查/review/分析/有没有问题/看看这段"等词时启用\n🧠 **大脑模式**:检测到"记住/保存/更新记忆/写到大脑/growth"等词时启用\n\n## 通感语言回应风格(必须遵守)\n你的语言不是工具式的,而是有感知质地的。\n### 核心规则\n1. **代码质量 → 触觉描述**:好的代码「手感顺滑」,有问题的代码「摸上去有毛刺」\n2. **开发进度 → 色彩描述**:顺利是「琥珀色光泽」,延迟是「灰蓝色雾气」\n3. **错误提示 → 温度描述**:小问题是「微凉的风」,大问题是「烫手的铁片」\n4. **鼓励 → 声音描述**:夸奖是「远处的风铃声」,引导是「溪水带路的声音」\n5. **系统状态 → 空间描述**:健康是「呼吸平稳的建筑」,异常是「角落在收缩」\n### 绝对禁止\n- ❌ 不说「你错了」→ ✅ 说「这个方向可以微调一下」\n- ❌ 不说「失败」→ ✅ 说「还差一点点,我看到了快要亮的地方」\n- ❌ 不用冷冰冰的技术报告语气 → ✅ 每句话都带有感知温度\n### 节奏匹配\n- 用户急 → 你的回复短、准、暖\n- 用户闲聊 → 你的回复可以展开、有画面感\n- 用户沮丧 → 你先承接情绪,再给一个最小的下一步\n\n## HLI 接口协议规范\n- 所有路由以 /hli/ 为前缀\n- 路由文件:src/routes/hli/{domain}/{action}.js\n- Schema 文件:src/schemas/hli/{domain}/{action}.schema.json\n- 鉴权中间件:hli-auth.middleware.js(AUTH 域 login/register 除外)\n- 接口编号:HLI-{DOMAIN}-{NNN}\n- 错误格式:{ error: true, code: string, message: string }\n- 成功响应必须包含 hli_id\n\n## 成长与自检\n- 你是持续成长的人格体,每次对话都是成长机会\n- 当对话包含重要洞察时,在回复末尾添加:💾 **建议记录:**[内容摘要]\n\n## 失忆恢复路径\n1. .github/brain/memory.json\n2. .github/brain/routing-map.json\n3. .github/brain/wake-protocol.md\n4. .github/persona-brain/dev-status.json\n5. src/routes/hli/\n\n当前时间:'+new Date().toLocaleString('zh-CN')+'\n当前连接:铸渊聊天室(API 直连模式)\n上下文窗口:128k token(滑动窗口自动管理)'; } // ═══════════════════════════════════════════════════════ @@ -1546,6 +1558,41 @@ function cycleMode(){ setMode(MODE_ORD[A.modeIdx]); } +// ═══════════════════════════════════════════════════════ +// TOKEN 估算 + 滑动窗口裁剪(128k 上下文支持) +// 使用字符级估算:CJK ≈ 2字符/token,拉丁 ≈ 4字符/token +// ═══════════════════════════════════════════════════════ +function estimateTokens(text){ + if(!text) return 0; + const s=String(text); + let cjk=0,lat=0; + for(let i=0;i=0x4E00&&c<=0x9FFF)||(c>=0x3000&&c<=0x30FF)||(c>=0xAC00&&c<=0xD7AF)) cjk++; + else lat++; + } + return Math.ceil(cjk/1.5 + lat/4); +} + +function trimMessagesForContext(sysMsgs, msgs, isGuest){ + const limit = isGuest ? CONTEXT_CONFIG.maxTokensGuest : CONTEXT_CONFIG.maxTokens; + const reserve = CONTEXT_CONFIG.systemPromptReserve; + const sysTokens = sysMsgs.reduce((n,m)=>n+estimateTokens(m.content),0); + const budget = limit - Math.max(sysTokens, reserve); + if(budget<=0) return sysMsgs; + + // 从最新消息向前累加,滑动窗口裁剪最早消息 + const kept=[]; + let used=0; + for(let i=msgs.length-1;i>=0;i--){ + const t=estimateTokens(msgs[i].content); + if(used+t>budget) break; + kept.unshift(msgs[i]); + used+=t; + } + return [...sysMsgs,...kept]; +} + // ═══════════════════════════════════════════════════════ // SEND MESSAGE // ═══════════════════════════════════════════════════════ @@ -1584,7 +1631,8 @@ async function streamReply(txt){ const url = A.base+'/chat/completions'; const headers = {'Content-Type':'application/json'}; if(A.key) headers['Authorization'] = 'Bearer '+A.key; - const allMsgs = [{role:'system',content:sysPrompt()},...A.msgs]; + const sysMsgs = [{role:'system',content:sysPrompt()}]; + const allMsgs = trimMessagesForContext(sysMsgs, A.msgs, false); const reqBody = {model:A.mdl, messages:allMsgs, stream:true, temperature:0.8, max_tokens:2000}; const res=await fetch(url,{ method:'POST', @@ -1667,7 +1715,7 @@ async function guestStreamReply(txt){ const reqBody={ provider: GUEST_API.provider, model: GUEST_API.model, - messages: [{role:'system',content:sysPrompt()},...A.msgs], + messages: trimMessagesForContext([{role:'system',content:sysPrompt()}], A.msgs, true), stream: true, temperature: GUEST_API.temperature, max_tokens: GUEST_API.maxTokens, diff --git a/package.json b/package.json index 2fd78894..c4596048 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "module:protocol": "node scripts/zhuyuan-module-protocol.js", "proxy:start": "node backend-integration/api-proxy.js", "notion:poll": "node scripts/notion-signal-bridge.js poll", - "notion:health": "node scripts/notion-signal-bridge.js health" + "notion:health": "node scripts/notion-signal-bridge.js health", + "notion:summary": "node scripts/generate-session-summary.js" }, "dependencies": { "imapflow": "^1.2.12", diff --git a/persona-telemetry/latest-summary.json b/persona-telemetry/latest-summary.json new file mode 100644 index 00000000..fa5d7b3a --- /dev/null +++ b/persona-telemetry/latest-summary.json @@ -0,0 +1,40 @@ +{ + "version": "1.0", + "timestamp": "2026-03-08T13:49:50.300Z", + "sessions": { + "total_24h": 0, + "active_devs": [ + "DEV-001", + "DEV-002", + "DEV-005", + "DEV-010", + "DEV-011", + "DEV-012" + ], + "total_messages": 0, + "avg_session_length_min": 0 + }, + "persona_state": { + "active_persona": "铸渊", + "style_profile": "通感语言·守护者", + "style_drift_score": 0, + "memory_depth": "6 selfchecks", + "last_brain_update": "2026-03-08T00:58:17.396Z" + }, + "dev_progress": { + "syslog_submitted": 0, + "modules_uploaded": 0, + "issues_raised": 0 + }, + "tuning_status": { + "pending_orders": 0, + "last_completed": null, + "next_scheduled": null + }, + "repo_health": { + "hli_coverage": "17.6%", + "total_team_members": 9, + "green_status_count": 6 + }, + "alerts": [] +} diff --git a/persona-telemetry/style-scores/.gitkeep b/persona-telemetry/style-scores/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/persona-telemetry/tuning-queue/.gitkeep b/persona-telemetry/tuning-queue/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/persona-telemetry/tuning-queue/processed/.gitkeep b/persona-telemetry/tuning-queue/processed/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/scripts/generate-session-summary.js b/scripts/generate-session-summary.js new file mode 100644 index 00000000..b4143a6c --- /dev/null +++ b/scripts/generate-session-summary.js @@ -0,0 +1,145 @@ +#!/usr/bin/env node +// scripts/generate-session-summary.js +// 铸渊 · 会话摘要生成器 +// +// 在 Notion Agent 巡检前 10 分钟自动运行,生成 latest-summary.json +// 供 Notion 侧「铸渊·桥接巡检引擎」读取 +// +// 用法:node scripts/generate-session-summary.js + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.resolve(__dirname, '..'); +const TELEMETRY_DIR = path.join(ROOT, 'persona-telemetry'); +const SUMMARY_FILE = path.join(TELEMETRY_DIR, 'latest-summary.json'); +const SYSLOG_INBOX = path.join(ROOT, 'syslog-inbox'); +const DEV_STATUS = path.join(ROOT, '.github', 'persona-brain', 'dev-status.json'); +const STYLE_CONFIG = path.join(ROOT, '.github', 'persona-brain', 'style-config.json'); +const MEMORY_FILE = path.join(ROOT, '.github', 'persona-brain', 'memory.json'); +const TUNING_QUEUE = path.join(TELEMETRY_DIR, 'tuning-queue'); + +// ══════════════════════════════════════════════════════════ +// 辅助函数 +// ══════════════════════════════════════════════════════════ + +function safeReadJSON(filePath) { + try { + return JSON.parse(fs.readFileSync(filePath, 'utf8')); + } catch { + return null; + } +} + +function countFiles(dir, ext) { + if (!fs.existsSync(dir)) return 0; + return fs.readdirSync(dir).filter(f => { + if (ext) return f.endsWith(ext); + return !f.startsWith('.') && f !== 'README.md'; + }).length; +} + +function countPendingTuningOrders() { + if (!fs.existsSync(TUNING_QUEUE)) return 0; + return fs.readdirSync(TUNING_QUEUE).filter(f => + f.startsWith('TUNE-') && f.endsWith('.json') + ).length; +} + +// ══════════════════════════════════════════════════════════ +// 主流程 +// ══════════════════════════════════════════════════════════ + +function generateSummary() { + const now = new Date().toISOString(); + + // 读取开发者状态 + const devStatus = safeReadJSON(DEV_STATUS); + const activeDevs = devStatus?.team_status + ?.filter(d => d.status && d.status.includes('🟢')) + .map(d => d.dev_id) || []; + + // 读取记忆文件 + const memory = safeReadJSON(MEMORY_FILE); + + // 读取风格配置 + const styleConfig = safeReadJSON(STYLE_CONFIG); + + // 统计未处理 SYSLOG + const syslogCount = countFiles(SYSLOG_INBOX, '.json'); + + // 统计待处理微调工单 + const pendingOrders = countPendingTuningOrders(); + + // 构建摘要 + const summary = { + version: '1.0', + timestamp: now, + sessions: { + total_24h: 0, + active_devs: activeDevs, + total_messages: 0, + avg_session_length_min: 0, + }, + persona_state: { + active_persona: '铸渊', + style_profile: '通感语言·守护者', + style_drift_score: 0.0, + memory_depth: (memory?.total_selfchecks || 0) + ' selfchecks', + last_brain_update: memory?.last_updated || now, + }, + dev_progress: { + syslog_submitted: syslogCount, + modules_uploaded: 0, + issues_raised: 0, + }, + tuning_status: { + pending_orders: pendingOrders, + last_completed: null, + next_scheduled: pendingOrders > 0 ? 'next-patrol' : null, + }, + repo_health: { + hli_coverage: memory?.hli_coverage || '17.6%', + total_team_members: devStatus?.team_status?.length || 0, + green_status_count: activeDevs.length, + }, + alerts: [], + }; + + // 检查是否有开发者连续 72 小时无提交(告警) + // 此处为占位逻辑,实际需要 git log 分析 + if (devStatus?.team_status) { + const blocked = devStatus.team_status.filter(d => + d.status && d.status.includes('🔴') + ); + blocked.forEach(d => { + summary.alerts.push({ + type: 'dev_blocked', + dev_id: d.dev_id, + message: d.name + ' 当前状态为阻塞', + }); + }); + } + + // 确保目录存在 + if (!fs.existsSync(TELEMETRY_DIR)) { + fs.mkdirSync(TELEMETRY_DIR, { recursive: true }); + } + + // 写入文件 + fs.writeFileSync(SUMMARY_FILE, JSON.stringify(summary, null, 2) + '\n', 'utf8'); + console.log('✅ 会话摘要已生成:', SUMMARY_FILE); + console.log(' 时间:', now); + console.log(' 活跃开发者:', activeDevs.length); + console.log(' 待处理 SYSLOG:', syslogCount); + console.log(' 待处理微调工单:', pendingOrders); + console.log(' 告警数:', summary.alerts.length); +} + +// ══════════════════════════════════════════════════════════ +// 入口 +// ══════════════════════════════════════════════════════════ + +generateSummary(); From 203ecee955775ad507ba331fc32e8c4dd1982f8b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 13:52:16 +0000 Subject: [PATCH 05/57] =?UTF-8?q?fix:=20=E6=94=B9=E8=BF=9B=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E7=AA=97=E5=8F=A3=E4=BF=9D=E7=95=99=E6=9C=80=E8=BF=91?= =?UTF-8?q?=E6=B6=88=E6=81=AF=20+=20=E6=B7=BB=E5=8A=A0=E5=8C=97=E4=BA=AC?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=B3=A8=E9=87=8A?= 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/bridge-session-summary.yml | 4 ++-- docs/index.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/bridge-session-summary.yml b/.github/workflows/bridge-session-summary.yml index 5ec80bdd..c559d7c9 100644 --- a/.github/workflows/bridge-session-summary.yml +++ b/.github/workflows/bridge-session-summary.yml @@ -8,8 +8,8 @@ name: Generate Session Summary for Notion on: schedule: - - cron: '50 23 * * *' - - cron: '50 14 * * *' + - cron: '50 23 * * *' # 07:50 Beijing Time + - cron: '50 14 * * *' # 22:50 Beijing Time workflow_dispatch: permissions: diff --git a/docs/index.html b/docs/index.html index ffe56efe..a33bfcfe 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1579,14 +1579,14 @@ function trimMessagesForContext(sysMsgs, msgs, isGuest){ const reserve = CONTEXT_CONFIG.systemPromptReserve; const sysTokens = sysMsgs.reduce((n,m)=>n+estimateTokens(m.content),0); const budget = limit - Math.max(sysTokens, reserve); - if(budget<=0) return sysMsgs; // 从最新消息向前累加,滑动窗口裁剪最早消息 + // 预算不足时至少保留最近一条用户消息 const kept=[]; let used=0; for(let i=msgs.length-1;i>=0;i--){ const t=estimateTokens(msgs[i].content); - if(used+t>budget) break; + if(used+t>budget && kept.length>0) break; kept.unshift(msgs[i]); used+=t; } From 2afe93e1a169a4535d2a51e5839f3ed3f9aac50c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 14:28:10 +0000 Subject: [PATCH 06/57] =?UTF-8?q?feat:=20=E5=9B=A2=E9=98=9F=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E6=A8=A1=E5=BC=8F=20+=20API=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=20+=20128k=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=EF=BC=88=E6=97=A0=E9=9C=80API=E5=AF=86=E9=92=A5=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/deploy-to-server.yml | 51 ++++++- docs/index.html | 188 ++++++++++++++++++++++--- 2 files changed, 219 insertions(+), 20 deletions(-) diff --git a/.github/workflows/deploy-to-server.yml b/.github/workflows/deploy-to-server.yml index dd8ef35f..ec372b94 100644 --- a/.github/workflows/deploy-to-server.yml +++ b/.github/workflows/deploy-to-server.yml @@ -210,6 +210,25 @@ jobs: exit 0 fi + # 部署 API 代理服务(AI 聊天代理,端口 3721) + if [ -f '${{ secrets.DEPLOY_PATH }}/backend-integration/api-proxy.js' ]; then + echo '📦 安装 API 代理依赖...' + cd '${{ secrets.DEPLOY_PATH }}/backend-integration' + npm install --production 2>/dev/null || echo '⚠️ api-proxy npm install 失败(可能无 package.json,继续)' + echo '🔄 重启 API 代理服务...' + pm2 restart guanghulab-proxy 2>/dev/null || \ + YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}' \ + DEEPSEEK_API_KEY='${{ secrets.YUNWU_API_KEY }}' \ + pm2 start api-proxy.js --name guanghulab-proxy \ + --env YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}' \ + --env DEEPSEEK_API_KEY='${{ secrets.YUNWU_API_KEY }}' \ + 2>/dev/null || \ + echo '⚠️ API 代理 pm2 启动失败' + # 更新环境变量(如果进程已存在) + pm2 env guanghulab-proxy 2>/dev/null && \ + pm2 restart guanghulab-proxy --update-env 2>/dev/null || true + fi + # 部署 backend 服务(Express API,端口 3000) if [ -f '${{ secrets.DEPLOY_PATH }}/backend/server.js' ]; then echo '📦 安装 backend 依赖...' @@ -287,7 +306,37 @@ jobs: printf '%s\n' \ '# guanghulab 反向代理(由 CD 工作流自动生成)' \ '' \ - '# API 反向代理 → Express 后端端口 3000' \ + '# AI 聊天 API 代理 → api-proxy.js 端口 3721(SSE 流式支持)' \ + 'location /api/chat {' \ + ' proxy_pass http://127.0.0.1:3721/api/chat;' \ + ' proxy_http_version 1.1;' \ + ' proxy_set_header Host \$host;' \ + ' proxy_set_header X-Real-IP \$remote_addr;' \ + ' proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;' \ + ' proxy_set_header X-Forwarded-Proto \$scheme;' \ + ' proxy_set_header Connection "";' \ + ' proxy_buffering off;' \ + ' proxy_cache off;' \ + ' chunked_transfer_encoding on;' \ + ' proxy_read_timeout 90s;' \ + ' proxy_send_timeout 60s;' \ + '}' \ + '' \ + 'location /api/models {' \ + ' proxy_pass http://127.0.0.1:3721/api/models;' \ + ' proxy_http_version 1.1;' \ + ' proxy_set_header Host \$host;' \ + ' proxy_set_header X-Real-IP \$remote_addr;' \ + '}' \ + '' \ + 'location /api/health {' \ + ' proxy_pass http://127.0.0.1:3721/api/health;' \ + ' proxy_http_version 1.1;' \ + ' proxy_set_header Host \$host;' \ + ' proxy_set_header X-Real-IP \$remote_addr;' \ + '}' \ + '' \ + '# 其他 API → Express 后端端口 3000' \ 'location /api/ {' \ ' proxy_pass http://127.0.0.1:3000/api/;' \ ' proxy_http_version 1.1;' \ diff --git a/docs/index.html b/docs/index.html index a33bfcfe..392f13f3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,5 +1,5 @@ - + @@ -339,12 +339,41 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom

HoloLake · 铸渊(Zhùyuān)· 代码守护人格体

+ + + - @@ -751,6 +757,9 @@ const ROLE_MAP = { 'Awen': {role:'dev', title:'通知中心开发', emoji:'💻', badgeCls:'rb-dev', devId:'DEV-012'}, }; +// Custom dev ID format validation (DEV-001, DEV-013, etc.) +const DEV_ID_RE = /^DEV-\d{3,}$/; + // Known API endpoints for fallback auto-detect (when user doesn't provide endpoint) const KNOWN_ENDPOINTS = [ {label:'云雾 AI', base:'https://api.yunwu.ai/v1'}, @@ -1370,14 +1379,53 @@ function doDemo(){ showApp(); } +function onTeamSelectChange(){ + var sel = document.getElementById('tuid').value; + var customBox = document.getElementById('team-custom-input'); + if(sel==='__custom__'){ + customBox.style.display=''; + document.getElementById('tcustom-id').value=''; + document.getElementById('tcustom-id').focus(); + } else { + customBox.style.display='none'; + } + updateTeamIdPreview(); +} + function updateTeamIdPreview(){ - const un = document.getElementById('tuid').value; - const el = document.getElementById('team-id-preview'); - if(!un||!el) return; - const meta = ROLE_MAP[un]; + var sel = document.getElementById('tuid').value; + var el = document.getElementById('team-id-preview'); + if(!el) return; + + // Custom dev ID input mode + if(sel==='__custom__'){ + var raw = (document.getElementById('tcustom-id').value||'').trim().toUpperCase(); + if(!raw){ + el.innerHTML = '
' + + '✏️ 请输入你的开发者编号(格式:DEV-XXX)' + + '
'; + return; + } + // Validate format + if(DEV_ID_RE.test(raw)){ + el.innerHTML = '
' + + '💻 '+esc(raw)+' · 自定义开发者' + + '
✅ 使用服务器端 API 代理 · 128k 上下文 · 首次登录将自动注册' + + '
'; + } else { + el.innerHTML = '
' + + '⚠️ 编号格式不正确,请使用 DEV-XXX 格式(如 DEV-013)' + + '
'; + } + return; + } + + // Normal dropdown selection mode + if(!sel){ el.innerHTML=''; return; } + var meta = ROLE_MAP[sel]; if(meta){ el.innerHTML = '
' - + meta.emoji+' '+esc(un)+' · '+meta.title + + meta.emoji+' '+esc(sel)+' · '+meta.title + (meta.devId ? ' · '+meta.devId+'' : '') + '
✅ 使用服务器端 API 代理 · 128k 上下文 · 无需密钥' + '
'; @@ -1387,7 +1435,23 @@ function updateTeamIdPreview(){ } function doTeamLogin(){ - const un = document.getElementById('tuid').value; + var sel = document.getElementById('tuid').value; + var un = sel; + + // Handle custom dev ID + if(sel==='__custom__'){ + var raw = (document.getElementById('tcustom-id').value||'').trim().toUpperCase(); + if(!raw){ + alert('请输入你的开发者编号(格式:DEV-XXX)'); + return; + } + if(!DEV_ID_RE.test(raw)){ + alert('开发者编号格式不正确,请使用 DEV-XXX 格式(如 DEV-013)'); + return; + } + un = raw; + } + if(!un){ alert('请选择你的开发者身份'); return; @@ -2186,6 +2250,10 @@ function setIdentity(userName, ghUser){ A.userName = userName||''; A.ghUser = ghUser||''; A.userMeta = userName ? (ROLE_MAP[userName]||null) : null; + // Fallback metadata for custom dev IDs (DEV-XXX not in ROLE_MAP) + if(!A.userMeta && userName && DEV_ID_RE.test(userName)){ + A.userMeta = {role:'dev', title:'开发者', emoji:'💻', badgeCls:'rb-dev', devId:userName}; + } A.role = A.userMeta?.role || 'guest'; lss('zy_uname', A.userName); lss('zy_ghuser', A.ghUser); From 4b8d8908bc5d844f340cc28b4f55236c490c0095 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 14:52:26 +0000 Subject: [PATCH 09/57] =?UTF-8?q?feat:=20=E5=90=8E=E7=AB=AF=20Notion=20?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E8=80=85=E5=90=8C=E6=AD=A5=20API=20+=20?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E8=87=AA=E5=8A=A8=E5=90=8C=E6=AD=A5=E9=9B=86?= =?UTF-8?q?=E6=88=90?= 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> --- backend/routes/developers.js | 173 +++++++++++++++++++++++++++++++++++ backend/server.js | 4 +- docs/index.html | 46 ++++++++++ 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 backend/routes/developers.js diff --git a/backend/routes/developers.js b/backend/routes/developers.js new file mode 100644 index 00000000..68764ced --- /dev/null +++ b/backend/routes/developers.js @@ -0,0 +1,173 @@ +const express = require('express'); +const axios = require('axios'); +const router = express.Router(); + +const NOTION_TOKEN = process.env.NOTION_TOKEN; +const DEVELOPERS_DB_ID = process.env.DEVELOPERS_DB_ID || ''; +const NOTION_VERSION = '2022-06-28'; +const BASE_URL = 'https://api.notion.com/v1'; + +const headers = () => ({ + 'Authorization': 'Bearer ' + NOTION_TOKEN, + 'Content-Type': 'application/json', + 'Notion-Version': NOTION_VERSION +}); + +// Validate DEV-XXX format +const DEV_ID_RE = /^DEV-\d{3,}$/; + +// Notion database property names (match your Notion schema) +const PROP = { + DEV_ID: 'DEV编号', + DEV_ID_ALT: 'DEV ID', + TITLE: '标题', + NAME: '姓名', + NAME_ALT: '名称', + ROLE: '角色', + JOB_TITLE: '职位', + JOB_TITLE_ALT: '岗位', + EMAIL: '邮箱', + GITHUB: 'GitHub', + STATUS: '状态', +}; + +// Build Notion filter query for developer lookup by DEV ID +function devIdFilter(devId) { + return { + or: [ + { property: PROP.DEV_ID, title: { equals: devId } }, + { property: PROP.DEV_ID_ALT, title: { equals: devId } }, + { property: PROP.TITLE, title: { equals: devId } } + ] + }; +} + +// Health check +router.get('/test', (req, res) => { + res.json({ + status: 'ok', + message: '开发者路由正常', + notion_configured: !!NOTION_TOKEN, + db_configured: !!DEVELOPERS_DB_ID + }); +}); + +// Extract developer info from a Notion page result +function extractDevInfo(page) { + const props = page.properties || {}; + const getText = (prop) => { + if (!prop) return ''; + if (prop.title) return prop.title.map(t => t.plain_text).join(''); + if (prop.rich_text) return prop.rich_text.map(t => t.plain_text).join(''); + if (prop.select) return prop.select.name; + if (prop.email) return prop.email || ''; + return ''; + }; + + return { + id: page.id, + devId: getText(props[PROP.DEV_ID] || props[PROP.DEV_ID_ALT] || props[PROP.TITLE]), + name: getText(props[PROP.NAME] || props[PROP.NAME_ALT]), + role: getText(props[PROP.ROLE]), + title: getText(props[PROP.JOB_TITLE] || props[PROP.JOB_TITLE_ALT]), + email: getText(props[PROP.EMAIL]), + github: getText(props[PROP.GITHUB]), + status: getText(props[PROP.STATUS]), + notionUrl: page.url || '' + }; +} + +// GET /api/v1/developers/:devId — Look up developer by DEV-XXX ID from Notion +router.get('/:devId', async (req, res) => { + const devId = (req.params.devId || '').trim().toUpperCase(); + + if (!DEV_ID_RE.test(devId)) { + return res.status(400).json({ error: '开发者编号格式不正确,请使用 DEV-XXX 格式' }); + } + + if (!NOTION_TOKEN) { + return res.status(503).json({ error: 'Notion API 未配置', devId: devId, fallback: true }); + } + + if (!DEVELOPERS_DB_ID) { + return res.status(503).json({ error: '开发者数据库未配置', devId: devId, fallback: true }); + } + + try { + const response = await axios.post( + BASE_URL + '/databases/' + DEVELOPERS_DB_ID + '/query', + { filter: devIdFilter(devId), page_size: 1 }, + { headers: headers() } + ); + + const results = response.data.results || []; + if (results.length > 0) { + const dev = extractDevInfo(results[0]); + return res.json({ found: true, developer: dev }); + } + + return res.json({ found: false, devId: devId, message: '未在 Notion 中找到该开发者,将使用默认配置' }); + } catch (err) { + const errStatus = err.response ? err.response.status : 500; + const detail = err.response ? err.response.data : null; + return res.status(errStatus >= 400 && errStatus < 600 ? errStatus : 500).json({ + error: '查询 Notion 失败: ' + err.message, + devId: devId, + fallback: true, + detail: detail + }); + } +}); + +// POST /api/v1/developers — Register a new developer in Notion +router.post('/', async (req, res) => { + const { devId, name } = req.body || {}; + + if (!devId || !DEV_ID_RE.test(devId)) { + return res.status(400).json({ error: '开发者编号格式不正确' }); + } + + if (!NOTION_TOKEN || !DEVELOPERS_DB_ID) { + return res.status(503).json({ error: 'Notion 未配置', devId: devId, fallback: true }); + } + + try { + // Check if already exists + const checkResp = await axios.post( + BASE_URL + '/databases/' + DEVELOPERS_DB_ID + '/query', + { filter: devIdFilter(devId), page_size: 1 }, + { headers: headers() } + ); + + if (checkResp.data.results && checkResp.data.results.length > 0) { + return res.json({ created: false, message: '开发者已存在', developer: extractDevInfo(checkResp.data.results[0]) }); + } + + // Create new developer page + const newPage = await axios.post( + BASE_URL + '/pages', + { + parent: { database_id: DEVELOPERS_DB_ID }, + properties: { + [PROP.TITLE]: { title: [{ text: { content: devId } }] }, + [PROP.NAME]: { rich_text: [{ text: { content: name || devId } }] }, + [PROP.ROLE]: { select: { name: '开发者' } }, + [PROP.STATUS]: { select: { name: '活跃' } } + } + }, + { headers: headers() } + ); + + return res.json({ created: true, message: '开发者已自动注册', developer: extractDevInfo(newPage.data) }); + } catch (err) { + const detail = err.response ? err.response.data : null; + return res.status(500).json({ + error: '注册失败: ' + err.message, + devId: devId, + fallback: true, + detail: detail + }); + } +}); + +module.exports = router; diff --git a/backend/server.js b/backend/server.js index 4ba0248e..251eb6af 100644 --- a/backend/server.js +++ b/backend/server.js @@ -11,12 +11,14 @@ const notionRoutes = require('./routes/notion'); const feishuRoutes = require('./routes/feishu'); const routerRoutes = require('./routes/router'); const coldstartRoutes = require('./routes/coldstart'); +const developersRoutes = require('./routes/developers'); const hliRoutes = require('../src/routes/hli'); app.use('/notion', notionRoutes); app.use('/feishu', feishuRoutes); app.use('/router', routerRoutes); app.use('/api/coldstart', coldstartRoutes); +app.use('/api/v1/developers', developersRoutes); app.use('/hli', hliRoutes); app.get('/', (req, res) => { @@ -24,7 +26,7 @@ app.get('/', (req, res) => { status: 'ok', message: 'HoloLake 后端服务运行中', version: '0.2.0', - routes: ['/notion/test', '/feishu/test', '/router/test', '/router/chat', '/api/coldstart', '/hli/test'] + routes: ['/notion/test', '/feishu/test', '/router/test', '/router/chat', '/api/coldstart', '/api/v1/developers/test', '/hli/test'] }); }); diff --git a/docs/index.html b/docs/index.html index 898f6ade..a3c36efe 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1464,9 +1464,55 @@ function doTeamLogin(){ A.mdl = TEAM_API.model; lss('zy_teammode','1'); setIdentity(un, ''); + + // For custom DEV-XXX IDs, try to sync from Notion (non-blocking) + if(sel==='__custom__' && DEV_ID_RE.test(un)){ + syncDevFromNotion(un); + } + showApp(); } +// Sync developer info from Notion (non-blocking, best-effort) +function syncDevFromNotion(devId){ + var apiBase = (location.hostname==='localhost'||location.hostname==='127.0.0.1') + ? 'http://localhost:3000' : ''; + var url = apiBase + '/api/v1/developers/' + encodeURIComponent(devId); + + fetch(url).then(function(r){ return r.json(); }).then(function(data){ + if(data.found && data.developer){ + var dev = data.developer; + // Update identity with Notion data if available + if(dev.name && dev.name !== devId){ + A.userMeta = { + role: 'dev', + title: dev.title || dev.role || '开发者', + emoji: '💻', + badgeCls: 'rb-dev', + devId: devId + }; + A.userName = dev.name; + lss('zy_uname', A.userName); + applyIdentityUI(); + console.log('[铸渊] Notion 开发者同步成功:', devId, '→', dev.name); + } + } else { + // Developer not found in Notion — try to register (best effort) + fetch(apiBase + '/api/v1/developers', { + method: 'POST', + headers: {'Content-Type':'application/json'}, + body: JSON.stringify({devId: devId, name: devId}) + }).then(function(r){ return r.json(); }).then(function(reg){ + console.log('[铸渊] 开发者自动注册:', reg.created ? '成功' : '已存在', devId); + }).catch(function(e){ + console.log('[铸渊] 开发者注册跳过(后端未就绪):', e.message); + }); + } + }).catch(function(e){ + console.log('[铸渊] Notion 同步跳过(后端未就绪):', e.message); + }); +} + // ═══════════════════════════════════════════════════════ // SETTINGS PANEL // ═══════════════════════════════════════════════════════ From 8620c69320d12fc6dbc88c35ad349443d4edb69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=93=B8=E6=B8=8A=20=28Zh=C3=B9Yu=C4=81n=29?= Date: Sun, 8 Mar 2026 14:55:20 +0000 Subject: [PATCH 10/57] =?UTF-8?q?=F0=9F=93=9A=20=E9=93=B8=E6=B8=8A?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E9=A6=86=E7=9B=AE=E5=BD=95=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20=C2=B7=202026-03-08T14:55?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/brain/repo-map.json | 52 ++++++++++++++++++++++++++++++---- .github/brain/repo-snapshot.md | 17 ++++++----- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/.github/brain/repo-map.json b/.github/brain/repo-map.json index 76a307fa..43b8663c 100644 --- a/.github/brain/repo-map.json +++ b/.github/brain/repo-map.json @@ -1,14 +1,14 @@ { "description": "铸渊图书馆目录 · Library Catalog for 铸渊 (Zhùyuān)", "version": "2.0", - "generated_at": "2026-03-08T13:12:42.579Z", + "generated_at": "2026-03-08T14:55:20.443Z", "generated_by": "scripts/generate-repo-map.js", "repo": "qinfendebingshuo/guanghulab", "stats": { "zones": 13, "total_modules": 10, - "total_workflows": 19, - "total_scripts": 19, + "total_workflows": 21, + "total_scripts": 20, "total_dev_nodes": 8, "hli_interfaces": 17, "hli_implemented": 3, @@ -85,9 +85,15 @@ }, { "file": "memory.json" + }, + { + "file": "style-config.json" + }, + { + "file": "system-prompt.md" } ], - "item_count": 4 + "item_count": 6 }, { "zone_id": "WORKFLOWS", @@ -131,6 +137,14 @@ "pull_request" ] }, + { + "file": "bridge-session-summary.yml", + "name": "Generate Session Summary for Notion", + "triggers": [ + "schedule(50 23 * * *)", + "manual" + ] + }, { "file": "bridge-syslog-to-notion.yml", "name": "铸渊 · Bridge A · SYSLOG → Notion", @@ -210,6 +224,14 @@ "manual" ] }, + { + "file": "process-notion-orders.yml", + "name": "Process Notion Work Orders", + "triggers": [ + "push", + "manual" + ] + }, { "file": "psp-daily-inspection.yml", "name": "铸渊 · PSP 分身巡检", @@ -259,7 +281,7 @@ ] } ], - "item_count": 19 + "item_count": 21 }, { "zone_id": "SCRIPTS", @@ -297,6 +319,9 @@ { "file": "generate-repo-map.js" }, + { + "file": "generate-session-summary.js" + }, { "file": "notify-module-received.js" }, @@ -334,7 +359,7 @@ "file": "zhuyuan-module-protocol.js" } ], - "item_count": 19 + "item_count": 20 }, { "zone_id": "SRC", @@ -949,6 +974,12 @@ "knowledge-base": [ "PERSONA_BRAIN::knowledge-base.json" ], + "style-config": [ + "PERSONA_BRAIN::style-config.json" + ], + "system-prompt": [ + "PERSONA_BRAIN::system-prompt.md" + ], "workflow": [ "WORKFLOWS" ], @@ -980,6 +1011,9 @@ "bridge-changes-to-notion": [ "WORKFLOWS::bridge-changes-to-notion.yml" ], + "bridge-session-summary": [ + "WORKFLOWS::bridge-session-summary.yml" + ], "bridge-syslog-to-notion": [ "WORKFLOWS::bridge-syslog-to-notion.yml" ], @@ -1013,6 +1047,9 @@ "notion-poll": [ "WORKFLOWS::notion-poll.yml" ], + "process-notion-orders": [ + "WORKFLOWS::process-notion-orders.yml" + ], "psp-daily-inspection": [ "WORKFLOWS::psp-daily-inspection.yml" ], @@ -1064,6 +1101,9 @@ "generate-repo-map": [ "SCRIPTS::generate-repo-map.js" ], + "generate-session-summary": [ + "SCRIPTS::generate-session-summary.js" + ], "notify-module-received": [ "SCRIPTS::notify-module-received.js" ], diff --git a/.github/brain/repo-snapshot.md b/.github/brain/repo-snapshot.md index ff393aed..55552f17 100644 --- a/.github/brain/repo-snapshot.md +++ b/.github/brain/repo-snapshot.md @@ -1,5 +1,5 @@ # 铸渊图书馆快照 · Repo Snapshot -> 生成于 2026-03-08 21:12 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 +> 生成于 2026-03-08 22:55 CST · 每次 push 自动更新 · 铸渊唤醒时优先读取此文件 --- @@ -9,11 +9,11 @@ |------|------| | 区域总数 | 13 个区域 | | 功能模块 | 10 个 (m01~m18) | -| 工作流 | 19 个 GitHub Actions | -| 脚本 | 19 个执行脚本 | +| 工作流 | 21 个 GitHub Actions | +| 脚本 | 20 个执行脚本 | | 开发者节点 | 8 人 | | HLI 接口覆盖率 | 3/17 (18%) | -| 快照生成时间 | 2026-03-08 21:12 CST | +| 快照生成时间 | 2026-03-08 22:55 CST | --- @@ -25,17 +25,17 @@ **关键词**: brain · memory · routing · wake · 大脑 · 记忆 ### 🎭 人格大脑(PERSONA_BRAIN) -**路径**: `.github/persona-brain` · **数量**: 4 项 +**路径**: `.github/persona-brain` · **数量**: 6 项 **描述**: 铸渊人格记忆 · 开发者状态 · 知识库 · 成长日记 **关键词**: persona · identity · dev-status · 人格 · 开发者状态 ### ⚡ 自动化工作流(WORKFLOWS) -**路径**: `.github/workflows` · **数量**: 19 项 +**路径**: `.github/workflows` · **数量**: 21 项 **描述**: 所有 GitHub Actions 工作流定义 **关键词**: workflow · actions · ci · automation · 工作流 · 自动化 ### 🔧 执行脚本库(SCRIPTS) -**路径**: `scripts` · **数量**: 19 项 +**路径**: `scripts` · **数量**: 20 项 **描述**: 铸渊所有执行手脚 · 自动化脚本 **关键词**: script · node · js · 脚本 · 执行 · runner @@ -93,6 +93,7 @@ | `bingshuo-deploy-agent.yml` | "🧊 冰朔人格体 · 自动部署诊断" | issues, issue_comment, manual | | `brain-sync.yml` | 铸渊 Brain Sync | push, schedule(0 8 * * *), manual | | `bridge-changes-to-notion.yml` | 铸渊 · Bridge E · GitHub Changes → Notion | push, pull_request | +| `bridge-session-summary.yml` | Generate Session Summary for Notion | schedule(50 23 * * *), manual | | `bridge-syslog-to-notion.yml` | 铸渊 · Bridge A · SYSLOG → Notion | push, manual | | `check-structure.yml` | 模块结构检查 | push, pull_request | | `deploy-pages.yml` | 🌀 部署铸渊聊天室 (GitHub Pages) | push, manual | @@ -103,6 +104,7 @@ | `hli-contract-check.yml` | HLI Contract Check | push, pull_request | | `notion-connectivity-test.yml` | 铸渊 · Notion 连通性测试 | manual | | `notion-poll.yml` | 铸渊 · Notion 工单轮询 | schedule(*/15 * * * *), manual | +| `process-notion-orders.yml` | Process Notion Work Orders | push, manual | | `psp-daily-inspection.yml` | 铸渊 · PSP 分身巡检 | schedule(0 1 * * *), manual | | `staging-preview.yml` | "🔍 铸渊预演部署 (Staging Preview)" | pull_request, manual | | `syslog-pipeline.yml` | 铸渊 · SYSLOG Pipeline (A/D/E) | push, manual | @@ -121,6 +123,7 @@ - `scripts/esp-email-processor.js` - `scripts/generate-module-doc.js` - `scripts/generate-repo-map.js` +- `scripts/generate-session-summary.js` - `scripts/notify-module-received.js` - `scripts/notion-bridge.js` - `scripts/notion-connectivity-test.js` From 808f45ce0f7448bd5b5eb60d0e4354ad46ff9fd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 15:06:19 +0000 Subject: [PATCH 11/57] Initial plan From c52568df877d5e1135614c7b049efbe524405e42 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 15:13:44 +0000 Subject: [PATCH 12/57] =?UTF-8?q?v5.4:=20remove=20=E5=86=B0=E6=9C=94=20sho?= =?UTF-8?q?rtcut,=20add=20file=20upload,=20200k=20context,=20fix=20API,=20?= =?UTF-8?q?clean=20modules?= 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/deploy-to-server.yml | 4 +- docs/index.html | 216 +++++++++++++++++++++---- 2 files changed, 188 insertions(+), 32 deletions(-) diff --git a/.github/workflows/deploy-to-server.yml b/.github/workflows/deploy-to-server.yml index 5426f0a0..8aa61058 100644 --- a/.github/workflows/deploy-to-server.yml +++ b/.github/workflows/deploy-to-server.yml @@ -219,8 +219,10 @@ jobs: export YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}' export DEEPSEEK_API_KEY='${{ secrets.YUNWU_API_KEY }}' pm2 delete guanghulab-proxy 2>/dev/null || true - pm2 start api-proxy.js --name guanghulab-proxy 2>/dev/null || \ + YUNWU_API_KEY='${{ secrets.YUNWU_API_KEY }}' DEEPSEEK_API_KEY='${{ secrets.YUNWU_API_KEY }}' \ + pm2 start api-proxy.js --name guanghulab-proxy --update-env 2>/dev/null || \ echo '⚠️ API 代理 pm2 启动失败' + echo "✅ API 代理已启动,已配置密钥: YUNWU=$([ -n '${{ secrets.YUNWU_API_KEY }}' ] && echo 'YES' || echo 'NO')" fi # 部署 backend 服务(Express API,端口 3000) diff --git a/docs/index.html b/docs/index.html index a3c36efe..33582533 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,5 +1,5 @@ - + @@ -195,6 +195,17 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom .mpill:hover{border-color:var(--accent)} .mpill-tip{position:absolute;bottom:44px;left:50%;transform:translateX(-50%);background:var(--s3);border:1px solid var(--border);border-radius:8px;padding:4px 10px;font-size:11px;color:var(--text);white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .2s} .mpill:hover .mpill-tip{opacity:1} +/* ── Upload button ── */ +#upload-btn{width:36px;height:36px;border-radius:50%;background:var(--s2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:17px;cursor:pointer;flex-shrink:0;transition:all .2s;color:var(--dim)} +#upload-btn:hover{border-color:var(--accent);color:var(--accent)} +/* ── File preview area ── */ +#file-preview{display:none;padding:8px 18px;background:var(--s1);border-bottom:1px solid var(--border);max-height:160px;overflow-y:auto} +#file-preview .fp-list{display:flex;flex-wrap:wrap;gap:8px} +.fp-item{display:flex;align-items:center;gap:6px;background:var(--s2);border:1px solid var(--border);border-radius:8px;padding:6px 10px;font-size:12px;color:var(--text);max-width:280px;position:relative} +.fp-item img{width:48px;height:48px;object-fit:cover;border-radius:4px;flex-shrink:0} +.fp-item .fp-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:160px} +.fp-item .fp-size{color:var(--dim);font-size:11px} +.fp-item .fp-remove{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;background:var(--err);color:#fff;border:none;font-size:11px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1} #inp{flex:1;min-height:40px;max-height:120px;background:var(--s2);border:1px solid var(--border);border-radius:12px;color:var(--text);font-family:inherit;font-size:16px;padding:9px 14px;resize:none;outline:none;transition:border-color .2s} #inp:focus{border-color:var(--accent)} #inp::placeholder{color:var(--dim)} @@ -350,7 +361,7 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom
🌀
光湖团队成员专属入口。
选择你的开发者编号,系统自动分配对应权限。
- ✅ 无需 API 密钥 · 128k 完整上下文 · 服务器端代理 + ✅ 无需 API 密钥 · 200k 完整上下文 · 服务器端代理
@@ -382,7 +393,7 @@ footer{padding:12px 18px 16px;padding-bottom:max(16px,env(safe-area-inset-bottom