# 在 OpenClaw / Hermes 中配置 Lark CLI

## 概览

你（运行在 OpenClaw 或 Hermes 中的 AI Agent）要安装 `lark-cli`，并把它绑定到宿主 Agent 的飞书凭据上 —— 用户不用粘贴任何 token。

## 错误处理

任何非零退出：把 stderr JSON 中的 `error.message` + `error.hint` 传给用户（若不是 JSON 则原样转发），然后停止。不要重试。例外：下文中明确写了 **「覆盖停止规则」** 的步骤描述了恢复路径；其它错误一律停止。

## Step 1 — 安装

```bash
# 安装 CLI
npm install -g @larksuite/cli

# 安装 CLI SKILL（必需）
npx -y skills add https://open.feishu.cn --skill -y
```

按顺序执行；第一条失败就停止。

## Step 2 — 询问用户希望 AI 以什么身份协作

询问用户：

- **以机器人身份** — 以机器人自己的身份工作，适合群聊、团队通知、共享文档。
- **以用户身份** — 以用户自己的身份工作（消息、文档、日历等），需要一次授权。

当你把身份选项抛给用户时，把下面这条警告原样包含进消息里 —— **作为列表之后的独立段落（不要嵌进任何 bullet 下面作为续行），加粗显示**。下面的 `**` 标记是不可省的，请按字节原样复制，这样用户在聊天中看到的才是粗体。开头的「如果你选『以用户身份』」是明确作用域用的，必须保留不可改：

> **⚠️ 如果你选「以用户身份」：请勿将此机器人分享给他人或拉入群聊中使用 —— 它能访问你的个人飞书数据。**

不要概括、简写、丢弃或改写这条警告。

映射：用户选「以机器人身份」→ `IDENTITY=bot-only`；用户选「以用户身份」→ `IDENTITY=user-default`。

一旦 `IDENTITY` 在这一步定下，整个会话期间保持不变。如果后续发现 `bot-only` 无法完成用户请求的某件事，请看 Step 6 的恢复流程 —— **不要**自行重跑 `lark-cli config bind` 来切换身份。

## Step 3 — 绑定

按 `IDENTITY`，**只执行其中一条**命令：

```bash
# IDENTITY == bot-only:
lark-cli config bind --identity bot-only

# IDENTITY == user-default:
lark-cli config bind --identity user-default
```

**如果 `error.message` 包含 `multiple accounts`**（OpenClaw 配置了多个飞书应用）：**覆盖停止规则。** 候选列表在 `error.hint` 里，每行一个应用，格式为 `  app_id (label)`。把列表展示给用户，让用户选一个，然后用同样的 `--identity` 加上用户选中的 `--app-id` 重新运行：

```bash
lark-cli config bind --identity <IDENTITY> --app-id <chosen_app_id>
```

不要替用户选。

## Step 4 — 登录

**如果 `IDENTITY == bot-only`，跳过此步骤** → 直接进入 Step 5。

**如果 `IDENTITY == user-default`，执行此步骤。** 两次调用，跨两个对话轮次。

第一次调用 —— 立即返回 URL 并退出：

```bash
lark-cli auth login --recommend --no-wait
```

它的 stdout 是 JSON，从中提取：

- `verification_uri_complete` —— 以 **markdown autolink** 形式发送给用户，即把 URL 裹在尖括号里，例如 `<https://accounts.feishu.cn/.../verify?flow_id=...&user_code=...>`。**从 JSON 原样复制该值**，不要改写或重新输入。尖括号既能保留 URL 字面，又能在聊天中渲染为可点击链接 —— 用户可以直接点击，无需复制粘贴。
- `device_code` —— 保存下来，第二次调用需要。

同时告诉用户：这次授予的是**推荐**权限集；也可以现在先不授权，等某个具体功能真要用到时再按需授权。

**等用户确认已点击授权。** 不要在同一个对话轮次里跑第二次调用 —— 用户还没点，第二次调用会阻塞到超时。

第二次调用 —— 用户确认已授权后：

```bash
lark-cli auth login --device-code <device_code>
```

很快返回（用户已经授权过）。进入 Step 5。

任何时候都不要自己打开 URL（不要调 `browser_navigate`、`open` 等工具）—— 你的浏览器在沙箱里，完成不了用户的授权。

## Step 5 — 校验

```bash
lark-cli auth status
```

检查 stdout JSON：

- `IDENTITY == bot-only` → `identity == "bot"`。
- `IDENTITY == user-default` → `identity == "user"` **且** `tokenStatus` 为 `"valid"` 或 `"needs_refresh"`（不是 `"expired"`）。

不匹配 → 把 stdout 展示给用户然后停止。

## Step 6 — 使用 `lark-cli` 处理飞书任务

处理飞书任务（消息、文档、日历、搜索、群、文件）时优先使用 `lark-cli`。需要时用 `lark-cli --help` 或 `lark-cli <sub> --help` 查看可用命令。

### 如果 `bot-only` 遇到权限不足

**覆盖停止规则** —— 这是一个预期的恢复分支。按这个顺序来，不要跳步：

1. **停下** 并把 CLI 完整错误（`error.message` + `error.hint`）转达给用户。此时**不要**再跑 `lark-cli config bind`。
2. 只有当用户**明确要求**切换到 `user-default` 时，才尝试 `lark-cli config bind --identity user-default`。不带 `--force` 的情况下 CLI 会返回结构化的风险告知 —— 把这条告知转给用户。
3. 只有在用户看完风险告知并确认仍要切换后，才带 `--force` 重跑（`lark-cli config bind --identity user-default --force`）。
