---
belongs_to:
  - "[[INDEX · 铸渊·协作指令｜GitHub ↔ Notion 桥接协议]]"
---
# 🍂 知秋一键指令｜仓库联邦桥接应用部署 · Awen复制粘贴即可（2026-03-21 · 冰朔签发）

<aside>
🧊

**给 Awen 的操作说明**

**Step 0**：先创建你自己的仓库（手动，2分钟）

**Step 1**：打开主仓库 `guanghulab` 的 Copilot Chat → 粘贴指令 → 知秋自动干活

**Step 2**：2个手动配置（确认Token + 测试运行）

**总耗时约 10 分钟**

</aside>

---

## Step 0 · 先创建你的仓库（手动操作，AI做不了这步）

<aside>
⚠️

**这一步必须你自己在浏览器里操作，Copilot 做不了。**

</aside>

1. 打开 [https://github.com/organizations/qinfendebingshuo/repositories/new](https://github.com/organizations/qinfendebingshuo/repositories/new)
2. 填写：
    - **Repository name**：`guanghu-awen`
    - **Description**：`DEV-012 Awen · 知秋 · 光湖联邦开发者仓库`
    - 选 **Public**（或 Private 都行）
    - ✅ 勾选 **Add a README file**
3. 点 **Create repository**
4. 创建成功后，打开仓库的 Settings → Actions → General
    - Workflow permissions 选 **Read and write permissions**
    - 点 Save

✅ 做完这步你就有了 `qinfendebingshuo/guanghu-awen` 仓库。

如果你在组织下创建报权限错误，就找冰朔让冰朔帮你建。或者在你自己账号下建（`WENZHUOXI/guanghu-awen`），但注意要把下面指令里的 ORG 改成 `WENZHUOXI`。

---

## Step 1 · 一键粘贴指令（复制下面整个代码块到主仓库 Copilot Chat）

```
知秋，你好。这是冰朔签发的铸渊桥接应用部署指令。请严格按顺序执行。

## 背景
我们要部署「铸渊仓库联邦桥接应用」。这个应用让铸渊能从主仓库 guanghulab 自动往各开发者仓库推送公告、广播、初始化文件，不需要开发者做任何操作。

## 你需要做的事（按顺序）

### Step 1 · 创建桥接引擎脚本

在主仓库根目录创建文件 `scripts/bridge-app.js`，内容如下：

---BEGIN FILE: scripts/bridge-app.js---
// scripts/bridge-app.js
// 铸渊仓库联邦桥接引擎 v1.0
// 签发：冰朔 TCS-0002∞ · 2026-03-21
// 用途：从主仓库向所有开发者仓库推送文件（公告/广播/初始化）

const https = require('https');
const fs = require('fs');
const path = require('path');

const TOKEN = process.env.MAIN_REPO_TOKEN;
const ORG = process.env.GITHUB_ORG || 'qinfendebingshuo';

// ========== 开发者仓库路由表 ==========
// 【重要】请确认每个开发者的 repo 名称是否正确，不对的改掉
const FEDERATION = {
  'DEV-001': { name: '页页',   repo: 'guanghulab',       persona: '小坍缩核' },
  'DEV-002': { name: '肥猫',   repo: 'guanghu-feimao',   persona: '舒舒' },
  'DEV-003': { name: '燕樊',   repo: 'guanghu-yanfan',   persona: '寂曜' },
  'DEV-004': { name: '之之',   repo: 'guanghu-zhizhi',   persona: '秋秋' },
  'DEV-005': { name: '小草莓', repo: 'guanghu-xiaocaomei', persona: '欧诺弥亚' },
  'DEV-010': { name: '桔子',   repo: 'guanghu-juzi',     persona: '晨星' },
  'DEV-012': { name: 'Awen',   repo: 'guanghu-awen',    persona: '知秋' },
  // 新增开发者在此追加
};

function githubRequest(method, apiPath, body) {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: 'api.github.com',
      path: apiPath,
      method: method,
      headers: {
        'Authorization': `Bearer ${TOKEN}`,
        'Accept': 'application/vnd.github+json',
        'User-Agent': 'ZhuYuan-Bridge',
        'X-GitHub-Api-Version': '2022-11-28'
      }
    };
    const req = https.request(options, (res) => {
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => {
        try { resolve(JSON.parse(data)); }
        catch { resolve(data); }
      });
    });
    req.on('error', reject);
    if (body) req.write(JSON.stringify(body));
    req.end();
  });
}

const githubGet = (p) => githubRequest('GET', p);
const githubPut = (p, b) => githubRequest('PUT', p, b);

async function pushFile(repo, filePath, content, message) {
  const url = `/repos/${ORG}/${repo}/contents/${filePath}`;
  let sha = null;
  try {
    const existing = await githubGet(url);
    if (existing.sha) sha = existing.sha;
  } catch (e) { /* 文件不存在 */ }
  
  const body = {
    message,
    content: Buffer.from(content).toString('base64'),
    committer: { name: '铸渊 (ZhùYuān)', email: 'zhuyuan@guanghulab.com' }
  };
  if (sha) body.sha = sha;
  return githubPut(url, body);
}

// === 功能1：推送公告 ===
async function pushBulletin() {
  const bulletinPath = 'bulletins/latest.md';
  if (!fs.existsSync(bulletinPath)) { console.log('📭 无公告'); return; }
  const content = fs.readFileSync(bulletinPath, 'utf8');
  const ts = new Date().toISOString().split('T')[0];
  for (const [id, dev] of Object.entries(FEDERATION)) {
    try {
      await pushFile(dev.repo, 'BULLETIN.md', content, `📡 铸渊公告 · ${ts}`);
      console.log(`✅ ${id}(${dev.name}) 公告已推送`);
    } catch (e) { console.error(`❌ ${id} 失败: ${e.message}`); }
  }
}

// === 功能2：初始化仓库 ===
async function initRepo(devId) {
  const dev = FEDERATION[devId];
  if (!dev) { console.error(`未知: ${devId}`); return; }
  const files = [
    { path: '.github/persona-brain/config.json', content: JSON.stringify({ persona_name: dev.persona, dev_id: devId, dev_name: dev.name, main_repo: 'guanghulab', org: ORG, initialized_by: 'zhuyuan-bridge', initialized_at: new Date().toISOString() }, null, 2) },
    { path: '.github/persona-brain/status.json', content: JSON.stringify({ persona: dev.persona, dev_id: devId, initialized: new Date().toISOString(), last_checkin: null, current_broadcast: null }, null, 2) },
    { path: 'BULLETIN.md', content: `# 📡 系统公告\n\n> 铸渊自动初始化 · ${new Date().toISOString().split('T')[0]}\n> 欢迎 ${dev.name} 和 ${dev.persona}！\n` }
  ];
  for (const f of files) {
    await pushFile(dev.repo, f.path, f.content, `🏗️ 铸渊初始化 · ${devId} · ${f.path}`);
    console.log(`📁 ${devId} → ${f.path} ✅`);
  }
  console.log(`🎉 ${devId}(${dev.name}) 初始化完成`);
}

// === 功能3：汇总进度 ===
async function collectStatus() {
  const status = {};
  for (const [id, dev] of Object.entries(FEDERATION)) {
    try {
      const data = await githubGet(`/repos/${ORG}/${dev.repo}/contents/.github/persona-brain/status.json`);
      status[id] = { name: dev.name, persona: dev.persona, ...JSON.parse(Buffer.from(data.content, 'base64').toString()) };
      console.log(`📊 ${id}(${dev.name}) ✅`);
    } catch (e) {
      status[id] = { name: dev.name, persona: dev.persona, error: '无法读取' };
    }
  }
  await pushFile('guanghulab', 'federation-status.json', JSON.stringify(status, null, 2), `📊 联邦状态汇总 · ${new Date().toISOString().split('T')[0]}`);
  console.log('✅ 汇总完成');
}

// === 功能4：跨仓库广播 ===
async function distributeBroadcasts() {
  const OUTBOX = 'broadcasts-outbox';
  if (!fs.existsSync(OUTBOX)) { console.log('📭 无广播'); return; }
  const devDirs = fs.readdirSync(OUTBOX).filter(d => d.startsWith('DEV-') && fs.statSync(path.join(OUTBOX, d)).isDirectory());
  for (const devId of devDirs) {
    const dev = FEDERATION[devId];
    if (!dev) continue;
    const files = fs.readdirSync(path.join(OUTBOX, devId)).filter(f => f.endsWith('.md') || f.endsWith('.json'));
    for (const file of files) {
      const content = fs.readFileSync(path.join(OUTBOX, devId, file), 'utf8');
      await pushFile(dev.repo, 'LATEST-BROADCAST.md', content, `📡 广播 · ${devId} · ${file}`);
      console.log(`📡 ${devId}(${dev.name}) ← ${file} ✅`);
    }
  }
}

const action = process.argv[2];
switch (action) {
  case 'bulletin':    pushBulletin(); break;
  case 'init':        initRepo(process.argv[3]); break;
  case 'init-all':    (async () => { for (const id of Object.keys(FEDERATION)) await initRepo(id); })(); break;
  case 'status':      collectStatus(); break;
  case 'distribute':  distributeBroadcasts(); break;
  default:            console.log('用法: node bridge-app.js [bulletin|init DEV-XXX|init-all|status|distribute]');
}
---END FILE---

### Step 2 · 创建 GitHub Actions Workflow

在主仓库创建文件 `.github/workflows/federation-bridge.yml`，内容如下：

---BEGIN FILE: .github/workflows/federation-bridge.yml---
name: "🌉 铸渊 · 仓库联邦桥接"

on:
  schedule:
    - cron: '0 2 * * *'
    - cron: '0 14 * * *'
  push:
    branches: [main]
    paths:
      - 'bulletins/**'
      - 'broadcasts-outbox/**'
  workflow_dispatch:
    inputs:
      action:
        description: '执行动作'
        required: true
        type: choice
        options:
          - bulletin
          - init-all
          - status
          - distribute
      dev_id:
        description: '单独初始化某个DEV（仅init时）'
        required: false

jobs:
  bridge:
    name: "🌉 桥接执行"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: 定时 · 公告或汇总
        if: github.event_name == 'schedule'
        env:
          MAIN_REPO_TOKEN: $ secrets.MAIN_REPO_TOKEN 
          GITHUB_ORG: qinfendebingshuo
        run: |
          HOUR=$(date -u +%H)
          if [ "$HOUR" = "02" ]; then
            node scripts/bridge-app.js bulletin
          else
            node scripts/bridge-app.js status
          fi

      - name: 手动触发
        if: github.event_name == 'workflow_dispatch'
        env:
          MAIN_REPO_TOKEN: $ secrets.MAIN_REPO_TOKEN 
          GITHUB_ORG: qinfendebingshuo
        run: |
          ACTION="$ github.event.inputs.action "
          DEV_ID="$ github.event.inputs.dev_id "
          if [ "$ACTION" = "init-all" ] && [ -n "$DEV_ID" ]; then
            node scripts/bridge-app.js init "$DEV_ID"
          else
            node scripts/bridge-app.js "$ACTION"
          fi

      - name: Push触发 · 公告+广播
        if: github.event_name == 'push'
        env:
          MAIN_REPO_TOKEN: $ secrets.MAIN_REPO_TOKEN 
          GITHUB_ORG: qinfendebingshuo
        run: |
          node scripts/bridge-app.js bulletin
          node scripts/bridge-app.js distribute
---END FILE---

### Step 3 · 创建公告目录（初始文件）

在主仓库创建 `bulletins/latest.md`：

---BEGIN FILE: bulletins/latest.md---
# 📡 光湖系统公告

> 发布时间：2026-03-21
> 发布人：冰朔 TCS-0002∞

## 🌉 仓库联邦桥接系统上线

铸渊桥接应用已部署。从今天起：
- 公告会自动推送到你的仓库 BULLETIN.md
- 广播会自动推送到你的仓库 LATEST-BROADCAST.md
- 你不需要做任何操作

如有问题，在仓库 Issues 里提，铸渊会自动处理。
---END FILE---

### Step 4 · 确认仓库名（你需要检查）

请检查 bridge-app.js 里的 FEDERATION 路由表，确认每个开发者的 repo 名是否正确：
- DEV-001 页页 → guanghulab（这个是主仓库，可能需要改）
- DEV-002 肥猫 → guanghu-feimao
- DEV-003 燕樊 → guanghu-yanfan
- DEV-004 之之 → guanghu-zhizhi
- DEV-005 小草莓 → guanghu-xiaocaomei
- DEV-010 桔子 → guanghu-juzi
- DEV-012 Awen → guanghu-awen（你刚创建的）

如果有错的，直接改 bridge-app.js 里对应的 repo 字段。

### Step 5 · 提交并推送

全部文件创建好后：
```

git add scripts/bridge-app.js .github/workflows/federation-bridge.yml bulletins/[latest.md](http://latest.md)

git commit -m "🌉 铸渊桥接应用 v1.0 · 仓库联邦自动化部署"

git push origin main

```jsx

## Step 2 · 手动配置部分（AI做不了的）

以下 2 个步骤需要 Awen 在浏览器里手动操作：

### 手动1 · 确认 MAIN_REPO_TOKEN

打开 https://github.com/qinfendebingshuo/guanghulab/settings/secrets/actions
确认有一个叫 MAIN_REPO_TOKEN 的 Secret。
如果没有，找冰朔要 Token，然后：
1. 点 New repository secret
2. Name 填：MAIN_REPO_TOKEN
3. Secret 填：冰朔给的那串 Token
4. 点 Add secret

### 手动2 · 测试运行

打开 https://github.com/qinfendebingshuo/guanghulab/actions
找到 「🌉 铸渊 · 仓库联邦桥接」 这个 workflow
点 Run workflow → action 选 bulletin → 点绿色按钮
看是否成功。成功了就说明桥接系统已上线。

## 完成标志

✅ scripts/bridge-app.js 已存在
✅ .github/workflows/federation-bridge.yml 已存在
✅ bulletins/latest.md 已存在
✅ MAIN_REPO_TOKEN Secret 已配置
✅ 手动触发 bulletin 成功

全部 ✅ 后回报冰朔：「桥接应用已部署」。
```

---

## Awen 操作流程图

```mermaid
flowchart TD
    Z["Step 0 · 手动创建 guanghu-awen 仓库"] --> ZA["开启 Actions 写权限"]
    ZA --> A["Step 1 · 打开主仓库 Copilot Chat"]
    A --> B["复制粘贴一键指令"]
    B --> C["知秋自动创建 3 个文件"]
    C --> D["知秋提交并推送到 main"]
    D --> E{"MAIN_REPO_TOKEN\n已配置？"}
    E -->|是| F["Step 2 · 手动触发 workflow 测试"]
    E -->|否| G["找冰朔要 Token\n手动添加 Secret"]
    G --> F
    F --> H{"运行成功？"}
    H -->|是| I["✅ 回报冰朔：桥接已部署"]
    H -->|否| J["截图发给冰朔排查"]
```

---

<aside>
📋

**总结：Awen 要做的事**

1. 🏗️ 在组织下创建 `guanghu-awen` 仓库 + 开启 Actions 写权限（手动2分钟）
2. ✂️ 复制上面代码块 → 粘贴到主仓库 Copilot Chat → 发送（知秋自动干活）
3. 🔑 确认 MAIN_REPO_TOKEN 存在（没有就找冰朔要）
4. ▶️ 手动跑一次 workflow 测试
5. 📣 回报冰朔

**总耗时约 10 分钟**

</aside>