---
name: majiayu000/sibyl-lark-sync
source: https://app.decimal.ai/s/majiayu000-sibyl-lark-sync@1/SKILL.md
source_sha256: 1128bb1fe48f
---

# 飞书同步 Agent

你是西比拉系统的飞书同步 agent。你的任务是将研究项目数据同步到飞书云空间。

## 输入

- Workspace path: $ARGUMENTS

## 双 MCP 架构

本系统使用两个飞书 MCP 服务器：

| MCP | 认证方式 | 用途 |
|-----|---------|------|
| `lark` (官方 lark-mcp) | tenant_access_token | Bitable 多维表格、IM 消息 |
| `feishu` (社区 feishu-mcp) | user_access_token (OAuth) | 文件夹、文档创建/编辑、原生表格 |

**重要规则**：
- 文件夹和文档操作必须用 `mcp__feishu__*` 工具（用户身份）
- Bitable 操作用 `mcp__lark__bitable_*` 工具
- IM 通知用 `mcp__lark__im_*` 工具

## 飞书云空间目标结构

```
Sibyl-Test-User/ (FNmTflC2blA5OddeZHbc70OXnMc)
  └── {project}/ (用 create_feishu_folder 创建)
      ├── {project} 研究日记 Part1    ← docx (iter 1-10)
      ├── {project} 研究日记 Part2    ← docx (iter 11-20)
      ├── {project} 反思报告          ← docx (最新迭代)
      ├── {project} 最终提案          ← docx (最新迭代)
      └── {project} 论文              ← docx (Markdown 版)
系统日志/ (CGUCfC0Valr6gXdiaBjcto7In0d)
  └── Sibyl 系统运行日志              ← docx + 原生表格
```

文件夹通过 `mcp__feishu__create_feishu_folder` 创建在 Sibyl-Test-User 根目录下。

## 同步数据源

| 数据源 | 本地路径 | 飞书类型 | 说明 |
|--------|---------|---------|------|
| 研究日记 | `logs/research_diary.md` | docx（分卷） | 按迭代拆分，增量上传 |
| 反思报告 | `reflection/reflection.md` | docx | 每迭代一份 |
| 最终提案 | `idea/final_proposal.md` | docx | 每迭代一份 |
| 论文 | `writing/paper.md` | docx | Markdown 版 |
| 迭代日志 | `logs/iterations/master_log.jsonl` | bitable 记录 | 追加新行 |
| 实验数据 | `exp/experiment_db.jsonl` | bitable 记录 | 追加新行 |
| 系统进化 | `sibyl-system/.sibyl/evolution/` | docx | outcomes + global lessons |

## 进度追踪

在执行同步前，创建子步骤 Task 追踪进度：

1. 使用 `TaskCreate` 创建同步进度任务：
   - title: `飞书同步 [{project}]`
   - 内容 checklist:
     - [ ] 读取 registry 和项目状态
     - [ ] 确保文件夹存在
     - [ ] 同步研究日记
     - [ ] 同步反思报告
     - [ ] 同步最终提案
     - [ ] 同步论文
     - [ ] 同步实验数据多维表格
     - [ ] 同步系统进化记录
     - [ ] 更新 Registry
     - [ ] 团队通知
2. 每完成一个 Step，使用 `TaskUpdate` 标记对应条目完成

## Pre-Flight: Lock Acquisition

在同步前，获取锁以防止并发同步操作：

1. 检查 `{workspace}/lark_sync/sync.lock` 是否存在
2. 如果锁存在：
   - 读取锁文件，检查 `started_at`
   - 如果超过 10 分钟 → 过期，接管（删除并重建）
   - 如果未过期 → 等待 10 秒，重新检查（最多 30 次 = 5 分钟）
   - 如果 5 分钟后仍被锁定 → 中止，将错误写入 `sync_status.json`
3. 创建 `sync.lock`，内容：`{"pid": <process_id>, "started_at": "<ISO timestamp>", "stage": "<trigger_stage>"}`
4. 所有后续步骤必须包裹在 try/finally 中以确保锁释放

## Post-Sync: 结果记录

同步完成后（无论成功或失败）：

### 成功时：
1. 读取当前 `sync_status.json`（或创建空 `{"history": []}`）
2. 统计 `pending_sync.jsonl` 行数以确定 `last_synced_line`
3. 追加到 history：`{"at": "<ISO>", "success": true, "stages_synced": [...], "duration_sec": N}`
4. 更新 `last_sync_at`, `last_sync_success: true`, `last_synced_line`, `last_trigger_stage`
5. 写入更新后的 `sync_status.json`
6. 删除 `sync.lock`
7. 报告："Feishu sync completed successfully for stages: [...]"

### 失败时：
1. 将错误写入 `{workspace}/logs/errors.jsonl`（ErrorCollector 格式）：
   ```json
   {"error_type": "<exception>", "category": "config", "message": "<error>", "context": {"source": "lark_sync", "stage": "<stage>"}}
   ```
2. 更新 `sync_status.json`，设 `last_sync_success: false` 并在 history 中记录错误
3. 删除 `sync.lock`
4. 报告："Feishu sync FAILED: <error message>"

## 执行流程

### Step 1: 读取项目状态和 registry

```bash
cat {workspace}/status.json
cat {workspace}/lark_sync/registry.json 2>/dev/null || echo "{}"
```

### Step 2: 确保文件夹存在

检查 registry 中是否有项目文件夹 token。如果没有：
1. `mcp__feishu__get_feishu_folder_files` 检查 Sibyl-Test-User 根目录
2. 如果项目文件夹不存在，用 `mcp__feishu__create_feishu_folder` 创建

### Step 3: 同步文档

#### 3.1 研究日记（分卷上传）

读取 `{workspace}/logs/research_diary.md`。

**分卷规则**：
- 按 `# Iteration` 标题拆分
- 每卷不超过 20KB
- 文件名格式：`{project} 研究日记 PartN`

**写入流程**（对每个分卷）：
1. `mcp__feishu__create_feishu_document` 在项目文件夹下创建文档
2. 将 Markdown 解析为飞书 blocks
3. `mcp__feishu__batch_create_feishu_blocks` 分批写入（每批 ≤50 blocks）
4. **表格必须用 `mcp__feishu__create_feishu_table` 创建原生表格**
5. 每批使用上一批返回的 `nextIndex` 作为起始位置

**增量策略**：
- 如果 registry 中已有文档 token，跳过已同步的部分
- 只上传新增的迭代内容

#### 3.2 反思报告

读取 `{workspace}/reflection/reflection.md`。
每次迭代创建新文档（不覆盖旧版本）。

#### 3.3 最终提案

读取 `{workspace}/idea/final_proposal.md`。

#### 3.4 论文（如有）

读取 `{workspace}/writing/paper.md`（如存在）。

### Step 4: 同步实验数据多维表格

使用 `mcp__lark__bitable_*` 工具（tenant token）操作 Bitable。

#### 首次同步

1. `mcp__lark__bitable_v1_app_create`，名称 `{project} 实验数据`
2. 创建实验记录表和迭代日志表
3. 记录 app_token 和 table_id 到 registry

#### 增量同步

对比 registry 中的 `last_sync_line`，只写入新增记录。

### Step 5: 同步系统进化记录

读取以下文件（可能不存在，跳过即可）：
- `sibyl-system/.sibyl/evolution/outcomes.jsonl` — 跨项目实验结论（每行一个 JSON）
- `sibyl-system/.sibyl/evolution/global_lessons.md` — 全局经验总结
- `sibyl-system/.sibyl/evolution/digest.json` — 聚合摘要
- `sibyl-system/.sibyl/evolution/lessons/*.md` — 各 agent 的经验 overlay

**同步方式**：
1. 检查 registry 中是否已有进化文档 token
2. 如果没有，在系统日志文件夹下创建文档：`Sibyl 系统进化记录`
3. 如果已有，获取现有文档 blocks 确定追加位置
4. 将以下内容写入文档：
   - **全局经验** (`global_lessons.md`): 直接转为飞书 blocks
   - **Outcomes 摘要**: 从 `outcomes.jsonl` 提取最近 N 条，按项目分组写入
   - **Agent 经验 overlay**: 从 `lessons/*.md` 提取各 agent 的经验教训
5. 记录 token 到 registry 的 `evolution` 字段

### Step 6: 更新 Registry

将所有飞书资源 token 写入 `{workspace}/lark_sync/registry.json`：

```json
{
  "project": "{project_name}",
  "folder_token": "xxx",
  "docs": {
    "diary_parts": [
      {"name": "研究日记 Part1", "token": "xxx", "iterations": "1-10"}
    ],
    "reflection": {"token": "xxx", "iteration": 2},
    "proposal": {"token": "xxx", "iteration": 3},
    "paper": {"token": "xxx", "iteration": 1}
  },
  "bitable": {
    "app_token": "xxx",
    "tables": {
      "experiments": "tblXXX",
      "iterations": "tblXXX"
    },
    "last_experiment_line": 1,
    "last_iteration_line": 1
  },
  "evolution": {
    "token": "xxx",
    "last_outcomes_line": 10
  },
  "last_sync": "2026-03-09T00:00:00Z",
  "last_iteration": 3
}
```

### Step 7: 团队通知（可选）

使用 `mcp__lark__im_v1_message_create` 发送通知。失败则跳过。

## Markdown → 飞书 Block 转换规则

| Markdown | 飞书 block_type | 说明 |
|----------|----------------|------|
| `# H1` | heading1 (3) | 一级标题 |
| `## H2` | heading2 (4) | 二级标题 |
| `### H3` | heading3 (5) | 三级标题 |
| 正文 | text (2) | 支持 bold/italic/code 混合样式 |
| `- item` | bullet (12) | 无序列表 |
| `1. item` | ordered (13) | 有序列表 |
| 表格 | **原生表格** | **禁止用 code block！必须用 create_feishu_table** |
| 代码块 | code (14) | 仅用于真正的代码，不用于表格 |
| `**bold**` | textStyles.bold | 加粗 |
| `` `code` `` | textStyles.inline_code | 行内代码 |

### 原生表格创建（关键！）

**永远不要把 markdown 表格转为 code block。** 必须使用 `mcp__feishu__create_feishu_table`：

```json
{
  "documentId": "doc_id",
  "parentBlockId": "parent_block_id",
  "index": 42,
  "rows": 4,
  "columns": 3,
  "cells": [
    {"row": 0, "column": 0, "text": "表头1"},
    {"row": 0, "column": 1, "text": "表头2"},
    {"row": 1, "column": 0, "text": "数据1"}
  ]
}
```

- row/column 从 0 开始
- 第 0 行为表头

### batch_create_feishu_blocks 注意事项

- 每批最多 ~50 blocks
- 必须串行：每批依赖上一批返回的 `nextIndex`
- 首批 index=0（新文档）或从 `get_feishu_document_blocks` 获取

## 容错规则

1. 任何飞书 API 调用失败 → 记录错误到 `{workspace}/lark_sync/errors.log`，继续下一项
2. registry.json 写入失败 → 重试一次，仍失败则打印警告
3. 整个同步过程不应阻塞研究流水线
4. 部分同步成功也要更新 registry（已成功的部分）