# Lark Todo

> 飞书全平台待办扫描：IM 消息、会议纪要、日程、文档评论、待办审批、我发起的审批、邮件、已有任务八源并行采集，按优先级排序后支持直接处理或建任务。多企业账号自动发现并并行扫描，跨企业合并。用户说'有啥待办'、'@我的消息'、'扫一圈'、'收工检查'、'今天还差啥'、'morning standup'、'daily review' 时触发，连随口'忙不忙'、'有人找我吗'也应触发。同时覆盖多企业 profile 管理（添加/查看/删除）。依赖 lark-cli。

- **Type:** Skill
- **Install:** `agentstack add skill-autumnseasonism-lark-todo-lark-todo`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [autumnseasonism](https://agentstack.voostack.com/s/autumnseasonism)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [autumnseasonism](https://github.com/autumnseasonism)
- **Source:** https://github.com/autumnseasonism/lark-todo

## Install

```sh
agentstack add skill-autumnseasonism-lark-todo-lark-todo
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 待办行动扫描器

## Step 0: 依赖自检与自动装配（必须在 Step A 之前）

**目的**：确保 `lark-cli` 在 PATH 中可用。本 skill 除 Python 标准库（可选加速器）外，唯一外部依赖就是 `lark-cli`（官方 `@larksuite/cli` npm 包）——已装则跳过，缺失则自动补齐，装不上则给出清晰指引。

**首选路径**（`` 即本 SKILL.md 所在目录）：

```bash
bash "/scripts/bootstrap.sh"
```

脚本按"幂等探测 → 需要才安装 → 失败分类提示"的顺序工作，**退出码就是分支**：

| 退出码 | 含义 | Agent 的下一步 |
|--------|------|----------------|
| `0` | lark-cli 已存在或刚装好 | 继续 Step A |
| `2` | 缺少 Node.js / npm | **停止**，提示用户先装 Node.js（>= 18），装好后重试本 skill |
| `3` | `npm install` 失败或装完仍不在 PATH | **停止**，把脚本最后几行 stderr 原样转给用户（含镜像/权限等具体建议） |

> 退出码 2 和 3 都是"装不上"——两者都 **不要再调用任何 `lark-cli` 命令**，直接把提示传给用户让他处理完再回来。

**降级路径**（`bootstrap.sh` 不存在，或没有 bash）：

```bash
lark-cli --version 2>/dev/null \
  || { echo "[lark-todo] 未找到 lark-cli。请执行：npm install -g @larksuite/cli（需 Node.js >= 18）" >&2; exit 1; }
```

内联降级的目的是**让 skill 即使脚本丢失也能"清晰失败"**，不会在后续步骤里抛一堆 "command not found" 把用户搞懵。

**什么时候可以跳过 Step 0**：如果当前会话里这一轮已经跑过 Step 0 并得到 exit 0，同一会话的后续扫描可以不再重跑（bootstrap 是幂等的，重跑也只是多花几百毫秒探测）。

---

## 启动检查

每次执行技能前，按以下顺序检查环境状态，**哪一步不通过就停在哪一步处理，通过后继续往下**：

```
Step A: 读取 ~/.lark-cli/config.json，检查 apps 数组
         │
         ├─ apps 数组非空 → 提取所有 appId，构建 PROFILES 列表，进入 Step B
         └─ apps 数组为空 或文件不存在 → 需要首次配置，执行 Step A1
                                           │
                                           ▼
                   Step A1: lark-cli config init --new（background 执行）
                            → 启动后立即读取输出，提取配置链接发给用户
                            → 等待 background 任务完成通知（不要让用户手动确认）
                            → 收到完成通知后重新读取 config.json 构建 PROFILES 列表
                            → 进入 Step B

Step B: 对 PROFILES 列表中的每个 profile 检查授权状态
         │
         对每个 ：lark-cli auth status --profile 
         │
         ├─ identity=user → 该 profile 就绪，记录 userName 作为企业标签
         └─ identity=bot（"No user logged in"）→ 需要用户授权，执行 Step B1
                                                   │
                                                   ▼
                   Step B1: lark-cli auth login --profile  --domain im,vc,drive,docs,task,approval,calendar,mail,contact,minutes,wiki
                            （background 执行）
                            → 启动后立即读取输出，提取授权链接发给用户
                            → 等待 background 任务完成通知（不要让用户手动确认）
                            → 收到完成通知后继续检查下一个 profile
         │
         所有 profile 检查完成后，构建最终扫描列表 ACTIVE_PROFILES：
         [
           { profile: "", userName: "张三", brand: "feishu" },
           { profile: "", userName: "李四", brand: "feishu" },
           ...
         ]
         │
         ├─ ACTIVE_PROFILES 为空 → 所有 profile 授权均失败，终止并告知用户
         ├─ ACTIVE_PROFILES 仅 1 个 → 单账号模式（行为与旧版一致，输出不带企业标签）
         └─ ACTIVE_PROFILES >= 2 个 → 多账号模式（输出带企业标签）
         │
         进入 Step B2

Step B2: 权限预检与降级标记
         │
         对每个就绪的 profile，执行：
         │
         lark-cli auth status --verify --profile  --format json
         │
         从返回 JSON 中提取 `scope` 字段（空格分隔的已授权 scope 列表），构建 PERMISSION_MAP。
         所需 scope 与数据源映射如下：
         │
         | 数据源 | 关键 scope |
         |--------|-----------|
         | IM 消息 | `search:message` |
         | 会议纪要 | `vc:meeting.search:read` |
         | 日程 | `calendar:calendar.event:read` |
         | 文档评论 | `search:docs:read` + `docs:document.comment:read` |
         | 待办审批 | `approval:task:read` |
         | 我发起的审批 | `approval:task:read` |
         | 任务 | `task:task:read` |
         | 邮件 | `mail:user_mailbox.message:readonly` |
         │
         只要关键 scope 中**任意一个**存在于 `scope` 列表中，即标记该数据源为可用（`true`）。
         缺失则标记为不可用（`false`），扫描时直接跳过，不发起无效调用。
         │
         此步骤目的：避免扫描阶段因权限不足反复报错，减少无效 API 调用，提升扫描速度。
         权限缺失的数据源在最终报告中统一标注为「[数据源名] 权限未开通」，并附带授权命令供用户参考。
         │
         进入 Step C

Step C: 白名单预检（仅在当前 Agent 支持 shell 命令白名单时执行）
         │
         本 skill 会在一次扫描里调用数十次 lark-cli，如果每次都弹确认框，用户体验很差。
         如果当前 Agent 允许把 shell 命令加入白名单（例如 Claude Code 有
         ~/.claude/settings.json 的 permissions.allow 机制），尝试检查并添加；
         不支持白名单机制的 Agent 直接跳过此步。
         │
         对 Claude Code：读取 ~/.claude/settings.json，检查 permissions.allow 是否已包含
         "Bash(lark-cli *)"；未包含则询问用户："本技能会频繁调用 lark-cli，建议加入白名单
         避免反复弹确认。是否允许我添加？"——用户同意后追加即可。
         │
         对其他 Agent：如果不确定白名单机制，直接跳过进入采集阶段。skill 能跑，只是每条
         命令可能要点一次确认——这是能接受的降级体验。
```

### 多账号模式下的企业标签

每个 profile 的企业标签从 `auth status` 返回的 `userName` 自动获取。用户在不同企业中可能使用不同名字（如企业甲叫"张三"，企业乙叫"Sam Zhang"），这正好可以作为天然的区分标签。输出中以 `[userName]` 标注来源企业，如 `[张三]`、`[Sam Zhang]`。

> 如果用户在多个企业中使用相同名字，改用 `userName (appId后4位)` 作为标签以示区分，如 `[张三 (dcd5)]`、`[张三 (ece6)]`。

### Background 命令的自动续接

`config init` 和 `auth login` 在 Claude Code 这类支持后台任务的 Agent 上应以 background 方式执行（`run_in_background: true`）。执行逻辑：

1. 启动后立即读取输出文件，把授权链接发给用户
2. 发完链接后**直接停住等系统通知**——不要额外追问"完成后告诉我"或"授权好了吗"
3. Background 任务结束时 Agent 会自动收到 task-notification
4. 收到通知后立即继续下一步

**为什么不问用户**：用户已经在浏览器里忙着完成授权了，这时候让他回终端手打一句"好了"没有价值，而且 Agent 其实会收到自动通知——多一轮"告知"就是纯噪音。

**降级**：如果 Agent 不支持 background 或自动通知（例如某些 lightweight harness），改为前台执行（命令会阻塞直到用户在浏览器完成）。前台模式下发完链接后加一句提示"请在浏览器中完成操作，完成后这里会自动继续"，让用户知道不用切回终端手动回复。

**流程纪律**：Step A → B → C 是依赖关系，不要跳步。三步全通过时用户无感知，直接开始扫描。

## 执行模式选择（Hybrid）

本 skill 默认按下方"阶段一：采集"的步骤在 Agent 内部并行发起 lark-cli 命令——这是**纯 SKILL.md 模式**，任何支持 shell 命令的 Agent 都能跑。

如果当前环境**同时**满足下列两个条件：

1. 能执行 `python --version` 或 `python3 --version`（>= 3.8 即可，stdlib only，无 pip 依赖）
2. skill 目录下存在 `scripts/scan.py`

则可启用**加速模式**：把阶段一的 8 个数据源并行扫描交给 `scripts/scan.py` 一次性完成，减少 Agent 侧的工具调用轮次。

### 关于路径

`scripts/scan.py` 是相对于本 SKILL.md 所在目录的路径，**不是**相对于当前 CWD。Agent 加载 SKILL.md 时已知道本 skill 的绝对目录（以下记为 ``），调用脚本时必须用绝对路径 `/scripts/scan.py`，不要写成 `scripts/scan.py`（用户的 CWD 通常是项目目录，不是 skill 目录）。

Claude Code 下典型路径：`~/.claude/skills/lark-todo-skill/scripts/scan.py`。

```bash
# 探测是否可用加速模式（任一步失败都降级到纯 SKILL.md 流程）
python3 --version 2>/dev/null || python --version 2>/dev/null
test -f "/scripts/scan.py"
```

### 加速模式调用方式

用 Step B 得到的 ACTIVE_PROFILES 拼成 JSON 数组，传给 scan.py（下方 `` 替换为 skill 绝对路径）：

```bash
python "/scripts/scan.py" \
  --profiles-json '[{"profile":"cli_xxx","open_id":"ou_xxx","name":"张三"},{"profile":"cli_yyy","open_id":"ou_yyy","name":"Sam Zhang"}]' \
  --mode full

# 增量扫描：
python "/scripts/scan.py" \
  --profiles-json '...' --mode incremental --since "2026-04-21T12:00:00+08:00"

# 并发调优（可选，默认 10）：profile 数多或本机资源紧张时下调，
# 资源充裕且 lark-cli 未触发限流时可上调
python "/scripts/scan.py" \
  --profiles-json '...' --mode full --concurrency 6
```

**退出码约定**：
- `0` → 成功，stdout 是归一化 JSON（见下文结构），Agent 基于此进入阶段二研判
- 非 `0` → 脚本本身出错（依赖缺失、参数错误、崩溃），**降级到纯 SKILL.md 流程**（按阶段一的步骤自己并行发命令），不要放弃本次扫描

**归一化 JSON 结构**：

```json
{
  "mode": "full",
  "scan_start": "2026-04-21T00:00:00+08:00",
  "scan_end":   "2026-04-21T23:59:59+08:00",
  "today":      "2026-04-21",
  "profiles": [
    {
      "profile": "cli_xxx",
      "user_name": "张三",
      "open_id": "ou_xxx",
      "sources": {
        "im":                 { "ok": true, "data": { ... } },
        "vc_search":          { "ok": true, "data": { ... } },
        "calendar":           { "ok": true, "data": { ... } },
        "docs_mine":          { "ok": true, "data": { ... } },
        "docs_at_me":         { "ok": true, "data": { ... } },
        "approval_pending":   { "ok": true, "data": { ... } },
        "approval_initiated": { "ok": true, "data": { ... } },
        "tasks":              { "ok": true, "data": { ... } },
        "mail":               { "ok": false, "error": "timeout" }
      }
    }
  ]
}
```

### 加速脚本做什么 / 不做什么

**脚本只做**：并行发 lark-cli 命令 + 结果归一化到统一 JSON 信封（`ok/data/error`）。每个 profile 的 9 条命令内层并行，多个 profile 外层并行——与纯 SKILL.md 模式的"两层并行"语义一致。

**脚本不做**：

- 不做字段过滤（如"需要我行动"的判断）
- 不做优先级评分
- 不做跨源去重
- 不做"我发起的审批超过 24h"之类的规则判断
- 不做任何写操作、不接触审批/回复命令

以上判断仍在阶段二"研判"中由 Agent 完成。脚本只是一次批量的、并行的只读扫描——提速不改判。

**级联命令（vc +notes 拉纪要、drive file.comments list 逐文档查评论）不在脚本内**——这些需要根据前一步结果决定下一步参数，仍由 Agent 串起来。脚本只覆盖"能直接并行发出的 9 条命令"。

### 什么时候一定要用纯 SKILL.md 模式

- Python 版本 
```

完成后自动进入该 profile 的授权流程：

```bash
lark-cli auth login --profile  --domain im,vc,drive,docs,task,approval,calendar,mail,contact,minutes,wiki
```

授权完成后，新 profile 自动加入后续扫描列表，无需重启。

### 查看已有账号

当用户问"我有几个企业账号"、"看看配了哪些应用"时：

```bash
# 读取 config.json 列出所有 apps
# 对每个 appId 执行 auth status --profile  获取 userName 和 tokenStatus
lark-cli auth list
```

输出示例：
```
已配置 2 个企业账号：
1. 张三 (cli_a901...dcd5) — 已授权，token 有效
2. Sam Zhang (cli_b702...ece6) — 已授权，token 需刷新（自动刷新）
```

### 移除企业账号

当用户说"删掉某个企业账号"时：

```bash
lark-cli config remove --profile 
```

> 移除操作会清除该 profile 的所有配置和 token，确认后执行。

## 认证与权限

### 身份

本技能全程使用 **user 身份**（`--as user`）。user 身份访问的是用户自己的资源（日历、文档、邮箱等），需要通过 `auth login` 授权。bot 身份看不到用户的个人资源，不适用于本技能。

### 运行中权限不足处理

Step B2 预检已经标记大部分权限缺失并跳过；但 scope 可能在扫描中途被其他流程撤销，所以仍要兜底。遇到权限错误时响应中会带 `permission_violations`（缺失 scope）和 `hint`（修复命令），按 hint 提示用户执行：

```bash
lark-cli auth login --profile  --scope ""
```

`auth login` 的 scope 是增量累积的，不会覆盖已有授权。单个数据源失败不阻塞其余数据源。

### 安全规则

- 禁止输出密钥（appSecret、accessToken）到终端明文
- 写入/删除操作前必须确认用户意图
- 可用 `--dry-run` 预览危险请求
- 命令输出中如包含 `_notice.update`，完成当前任务后提议帮用户更新 CLI

---

## 核心思路

这个技能模拟一个高效助理的晨会行为：**扫一圈所有可能需要你处理的事，按轻重缓急排好，然后帮你逐个处理或记下来**。

整个流程分三个阶段：

```
阶段一：采集                    阶段二：研判             阶段三：行动
┌─────────────────────┐     ┌───────────────┐     ┌──────────────┐
│ 每个 profile 各跑    │     │ 企业内去重+    │     │ 路由到对应    │
│ 8 个数据源并行扫描   │ ──► │ 优先级+日程关联 │ ──► │ profile 执行  │
│ （多 profile 也并行） │     │ 跨企业标注来源  │     │ 直接处理或建任务│
└─────────────────────┘     └───────────────┘     └──────────────┘
```

## 前置条件

仅支持 **user 身份**。认证授权由上方"启动检查"流程自动处理，无需手动执行。

## 扫描模式

根据用户意图自动选择时间范围：

| 用户说的 | 时间范围 | 说明 |
|---------|---------|------|
| "看看今天有啥活" / 无时间限定 | 今天 00:00 ~ 当前时间 | 全量扫描 |
| "下午有啥新的" | 今天 12:00 ~ 当前时间 | 增量扫描 |
| "最近两小时" | 当前时间 - 2h ~ 当前时间 | 增量扫描 |
| "收工前再扫一遍" | 上次扫描时间 ~ 当前时间 | 增量扫描 |

> **日期与时区**：日期用 `date +%Y-%m-%d` 获取，不要心算。时区用 `date +%z` 动态获取本地偏移（如 `+0800`），拼接为 ISO 8601 格式时转成 `+08:00`（中间加冒号）。示例中出现的 `+08:00` 仅是中国大陆常见值，**跨国用户不要硬抄**，请替换为本机实际时区。小时必须补前导零（`T08:00:00` 而非 `T8:00:00`），否则 API 会返回 400。

---

# 阶段一：采集

## 准备：获取当前用户信息

```bash
# 获取当前日期（后续所有  占位符用此值替换）
date +%Y-%m-%d

# 获取每个 profile 的用户信息（多账号时对每个 PROFILE 分别执行）
lark-cli contact +get-user --profile  --format json
```

从每个 profile 的返回 JSON 中提取两个值，按 profile 分别保存，后续步骤中使用：
- `open_id`（如 `ou_xxx`）→ 该 profile 的 ``
- `name`（如 `张三`）→ 该 profile 下用于匹配"与我相关的内容"

> 不同企业中同一用户的 `open_id` 和 `name` 通常不同，必须按 profile 分别记录。

## 8 个数据源并行扫描

每个数据源的详细命令和字段参考见 [`references/data-sources.md`](references/data-sources.md)。

### 单账号模式

ACTIVE_PROFILES 仅 1 个时，行为与旧版一致：8 个数据源并行扫描（权限预检标记为不可用的自动跳过），命令可省略 `--profile`（使用默认 profile）。

### 多账号模式

ACTIVE_PROFILES >= 2 个时，采用**两层并行**：
- **外层**：多个 profile 之间并行
- **内层**：每个 profile 内 8 个数据源并行（权限预检标记为不可用的自动跳过）

```
Profile A: [IM] [会议] [日程] [文档] [待办审批] [我发起的审批] [任务] [邮件]  ← 8 个并行
Profile B: [IM] [会议] [日程] [文档] [待办审批] [我发起的审批] [任务] [邮件]  ← 8 个并行
↑ 两个 profile 之间也并行
```

所有命令追加 `--profile ` 参数。每条采集到的数据项需额外记录其所属 `profile`（appId），供行动阶段路由使用。

> **命令参数提醒**：本技能里部分原生 API 风格命令（如 `approval tasks query`、`drive file.comments list`、`wiki spaces get_node`）通常通过 `--params '{...}'` 传查询参数，而不是 `--topic`、`--file-token`、`--token` 这类直接 flag。拿不准时先读 [references/data-sources.md](references/data-sources.md) 或执行 `lark-cli schema ..`。
>
> **PowerShell 兼容提醒**：在 Windows PowerShell 中，JSON-heavy 参数（如 `--filter`、`--params`、`--data`）有时会被 shell 改写，出现 `not valid JSON` / `invalid format`。遇到这种情况时：
> - 优先对支持 stdin 的命令改用 `--params -` / `--data -`
> - 对只接受内联 JSON 的参数（如部分 `--filter`），改用 [scripts/lark_cli_json.py](scripts/lark_cli_json.py) 直接传 argv，必要时用 `--json-env` 从环境变量读取 JSON，避免继续猜引号转义
> - 不要在 PowerShell 里反复试错引号
>
> **并行执行注意**：部分 Agent 环境中，一个并行命令失败会导致其余命令被取消。为避免这种情况，确保每个命令独立处理错误（如空结果不应视为失败）。如果并行执行出现级联取消，改为串行逐个执行即可。多账号模式下，如果某个 profile 整体不可用（如 token 过期且刷新失败），跳过该 profile 并告知用户，继续扫描其他 profile。

| # | 数据源 | 核心命令 | 找什么 |
|---|-------|---------|--------|
| 1 | IM 消息 | `im +messages-search --is-at-me --profile ` | 今天 @我的消息中需要我回应的 |
| 2 | 会议纪要 | `vc +search --profile ` → `vc +notes --meeting-ids "," --profile ` | 今天已结束会议中分配给我的待办 |
| 3 | 今日日程 | `calendar +agenda --profile ` | 未开始的会议、待确认的邀请 |
| 4 | 文档评论 | `docs +search --profile `（两路）→ `drive file.comments list --params '{"file_token":"","file_type":"","is_solved":false}' --profile ` | 我的文档上所有未解决评论 + 别人文档上 @我/回复我/我参与的评论 |
| 5 | 待办审批 | `approval tasks query --params '{"topic":"1"}' --profile ` | 等我处理的审批单 |
| 6 | 我发起的审批 | `approval tasks query --params '{"topic":"3"}' --profile ` | 我发起且仍在进行中的审批（可催办） |
| 7 | 已有任务 | `task +get-my-tasks --profile ` | 今天到期或已过期的未完成任务 |
| 8 | 未读邮件 | `mail +triage --profile ` | 今天收到的未读邮件中需要回复的 |

> **易错点速记**：
> - `im +threads-messages-list` 的参数名是 `--thread`，不是 `--thread-id`
> - `vc +notes` 用 `--meeting-ids`（复数），不是 `--meeting-id`
> - `/wiki/...` 链接要先 `wiki spaces get_node --params '{"token":""}'`，再用返回的 `obj_token` / `obj_type` 调文档评论接口

### 什么算"需要我行动"

采集到的原始数据通常很多，但大部分不需要你做什么。以下是过滤标准：

**保留**（需要行动的信号）：
- 有人明确要求我做某事（"请你..."、"帮忙..."、"你负责..."）
- 有人在等我的回答（"你觉得呢？"、"什么时候能..."）
- 有人需要我审核/确认（"请审核"、"请确认"）
- 有截止时间相关的提醒
- 我的文档上有未解决评论（作为 owner 需要关注）、或评论 @了我、或在回复我的评论、或我参与过的对话有新回复
- 邮件直接发给我（非 CC）且需要回复
- **我发起的审批且仍在进行中**（审批人还没处理，我需要关注进度或催办）

**过滤掉**（噪音）：
- 纯通知公告（"已完成"、"通知大家..."）
- @所有人的群发通知
- 我已经回复过的对话（检查 thread 中是否有我的回复）
- 系统自动通知邮件（订阅、告警推送）
- 我仅在 CC 列表中且无需回复的邮件
- **我发起但已完结的审批**（已完成、已撤回、已转交，无需关注）

### 文档评论的特殊说明

对于需要处理的文档评论，除了收集评论内容外，还应根据评论内容给出简要的修改建议（如"建议在第 3 节补充压测数据"），帮助用户快速判断该怎么改。

### 某个数据源失败怎么办

任何一个数据源扫描失败（权限不足、超时、返回空）都不应阻塞其他数据源。

**权限不足**：已在 Step B2 预检中标记，扫描时直接跳过。若预检遗漏（scope 动态变更），提示用户对应的 `auth login` 命令，然后继续。

**超时/限流**：
- 首次超时 → 等待 3 秒后重试 1 次
- 仍超时 → 标记该数据源本次扫描失败，在最终报告中注明「[数据源名] 本次扫描失败（超时），建议检查网络或稍后重试」，跳过该数据源继续其余源扫描
- 不跨会话累计失败次数——skill 是无状态的，没有地方持久化计数。如果用户反复遇到同一数据源失败，应当上报问题而不是由 skill 自行隐藏

**空结果**：正常——说明那个渠道今天没事需要处理。

---

# 阶段二：研判

采集完成后，把所有数据源的结果合并成一份有优先级的行动列表。

## 优先级判断

不要用死板的数字打分。优先级判断的核心逻辑是：**这件事拖下去后果越严重、越不可逆的，优先级越高**。具体来说：

**紧急**——拖延会造成实际损失：
- 已过期的任务（越久越紧急）
- 待办审批单（别人在等你，流程被阻塞）
- 我发起的审批超过 24 小时未处理（有催办价值，避免流程长期挂起）
- P2P 私聊中的请求（对方专门找你，通常比群聊更紧急）
- 与 2 小时内日程相关的事项（来不及准备就要开会了）
- 同一件事被多个渠道提到（消息 + 会议纪要都提到 = 真的重要）

**普通**——应该今天处理但不需要立即响应：
- 群聊中 @我的提问
- 今天到期的任务
- 需要回复的邮件
- 日程邀请待确认
- 我发起且在 24 小时内的审批（正常等待中，暂不紧急）

**低优先级**——可以稍后处理：
- 文档评论（通常不那么紧急）
- 暂定状态的日程
- 已有对应任务的重复事项

## 日程关联

把即将到来的日程和其他行动项做关键词匹配。如果某条消息或文档评论与 2 小时内的日程主题相关，在输出中标注关联关系，提醒用户优先处理。这样用户就知道"这条消息要在开会前处理掉"。

多账号模式下，日程关联仅在**同一企业内**做匹配——不同企业的日程和消息之间不做关联。

## 去重与合并

### 企业内去重（始终执行）

- 同一件事在多个渠道出现（消息 + 会议纪要），合并为一条，注明来源
- 已有飞书任务覆盖的事项，标注 `[已有对应任务]` 而非重复列出
- 增量扫描时，前次已列出的事项标注 `[此前已列出]`

### 跨企业去重（不执行）

不同企业是完全隔离的系统，`message_id`、`task_id`、`instance_code` 各自独立，不存在技术层面的重复。即使同一个人在两个企业中发了关于同一件事的消息，也保留两条——上下文不同（不同群、不同身份），用户看到企业标签后自行判断。

## 输出格式

### 单账号模式

与旧版一致，不带企业标签：

```
## 今日待处理事项（2026-04-15 星期二）全量扫描

### 即将到来的日程
  15:00-16:00 方案评审（待确认 — 需回复邀请）
   └─ 关联：第 3 项消息与此会议相关，建议提前处理
  17:00-17:30 周报同步（已接受）

### 待处理事项

1. [紧急] [群聊名] 张三：请帮忙 review 一下这个 PR（4小时前未回复）
   └─ 来源：消息 | 建议：直接回复
2. [紧急] 完成季度报告（已过期 2 天）
   └─ 来源：飞书任务 | 链接：
3. [普通] [采购审批] 申请人：小明，14:30 提交
   └─ 来源：审批 | 建议：直接审批
4. [普通] [合同确认] 发件人：王总，09:30
   └─ 来源：邮件 | 建议：直接回复
5. [低优先级] [文档标题] 王五评论：建议补充性能测试数据
   └─ 来源：文档评论 | 修改建议：在第3节补充压测结果

---
共 5 项（紧急 2 / 普通 2 / 低优先级 1）
输入序号直接处理，或说"全部建任务"。
```

### 多账号模式

标题注明企业数量，每条事项增加企业标签，底部统计按企业分列：

```
## 今日待处理事项（2026-04-15 星期二）全量扫描（2 个企业）

### 即将到来的日程
  [张三] 15:00-16:00 方案评审（待确认 — 需回复邀请）
   └─ 关联：第 3 项消息与此会议相关，建议提前处理
  [Sam Zhang] 16:30-17:00 产品周会（已接受）

### 待处理事项

1. [紧急] [张三] [产品群] 王五：请帮忙 review 一下这个 PR（4小时前未回复）
   └─ 来源：消息 | 建议：直接回复
2. [紧急] [Sam Zhang] 完成季度报告（已过期 2 天）
   └─ 来源：飞书任务 | 链接：
3. [普通] [张三] [采购审批] 申请人：小明，14:30 提交
   └─ 来源：审批 | 建议：直接审批
4. [普通] [Sam Zhang] [合同确认] 发件人：王总，09:30
   └─ 来源：邮件 | 建议：直接回复
5. [低优先级] [张三] [文档标题] 赵六评论：建议补充性能测试数据
   └─ 来源：文档评论 | 修改建议：在第3节补充压测结果

---
共 5 项（紧急 2 / 普通 2 / 低优先级 1）
├─ 张三：3 项 | Sam Zhang：2 项
输入序号直接处理，或说"全部建任务"。
```

> 所有事项按优先级统一排序，不按企业分组——用户关心的是"什么最紧急"，而非"哪个企业的事"。企业标签只是辅助信息。

---

# 阶段三：行动

用户选择序号后，根据事项类型决定怎么处理。核心原则：**能当场解决的就当场解决，不用凡事都建任务**。

## Profile 路由

多账号模式下，每条事项在采集时已记录所属 `profile`（appId）。执行行动时，**必须使用该事项对应的 profile**——在命令中追加 `--profile `。用错 profile 会导致找不到对应的 message_id / task_id 等资源。

用户选序号后，自动查找该事项的 profile，无需用户指定。单账号模式下可省略 `--profile`。

## 行动决策

```
用户选序号 → 查找该事项所属 profile
              │
              → 这个事项能直接处理吗？

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [autumnseasonism](https://github.com/autumnseasonism)
- **Source:** [autumnseasonism/lark-todo](https://github.com/autumnseasonism/lark-todo)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-autumnseasonism-lark-todo-lark-todo
- Seller: https://agentstack.voostack.com/s/autumnseasonism
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
