Fade 1 mese fa
commit
b72bbb100b
100 ha cambiato i file con 11785 aggiunte e 0 eliminazioni
  1. 48 0
      .agents/skills/lark-approval/SKILL.md
  2. 57 0
      .agents/skills/lark-attendance/SKILL.md
  3. 336 0
      .agents/skills/lark-base/SKILL.md
  4. 350 0
      .agents/skills/lark-base/references/dashboard-block-data-config.md
  5. 130 0
      .agents/skills/lark-base/references/examples.md
  6. 735 0
      .agents/skills/lark-base/references/formula-field-guide.md
  7. 83 0
      .agents/skills/lark-base/references/lark-base-advperm-disable.md
  8. 80 0
      .agents/skills/lark-base/references/lark-base-advperm-enable.md
  9. 79 0
      .agents/skills/lark-base/references/lark-base-base-copy.md
  10. 68 0
      .agents/skills/lark-base/references/lark-base-base-create.md
  11. 39 0
      .agents/skills/lark-base/references/lark-base-base-get.md
  12. 83 0
      .agents/skills/lark-base/references/lark-base-dashboard-arrange.md
  13. 108 0
      .agents/skills/lark-base/references/lark-base-dashboard-block-create.md
  14. 46 0
      .agents/skills/lark-base/references/lark-base-dashboard-block-delete.md
  15. 57 0
      .agents/skills/lark-base/references/lark-base-dashboard-block-get.md
  16. 53 0
      .agents/skills/lark-base/references/lark-base-dashboard-block-list.md
  17. 84 0
      .agents/skills/lark-base/references/lark-base-dashboard-block-update.md
  18. 73 0
      .agents/skills/lark-base/references/lark-base-dashboard-create.md
  19. 44 0
      .agents/skills/lark-base/references/lark-base-dashboard-delete.md
  20. 59 0
      .agents/skills/lark-base/references/lark-base-dashboard-get.md
  21. 52 0
      .agents/skills/lark-base/references/lark-base-dashboard-list.md
  22. 69 0
      .agents/skills/lark-base/references/lark-base-dashboard-update.md
  23. 240 0
      .agents/skills/lark-base/references/lark-base-dashboard.md
  24. 375 0
      .agents/skills/lark-base/references/lark-base-data-query.md
  25. 104 0
      .agents/skills/lark-base/references/lark-base-field-create.md
  26. 51 0
      .agents/skills/lark-base/references/lark-base-field-delete.md
  27. 42 0
      .agents/skills/lark-base/references/lark-base-field-get.md
  28. 44 0
      .agents/skills/lark-base/references/lark-base-field-list.md
  29. 48 0
      .agents/skills/lark-base/references/lark-base-field-search-options.md
  30. 97 0
      .agents/skills/lark-base/references/lark-base-field-update.md
  31. 22 0
      .agents/skills/lark-base/references/lark-base-field.md
  32. 87 0
      .agents/skills/lark-base/references/lark-base-form-create.md
  33. 64 0
      .agents/skills/lark-base/references/lark-base-form-delete.md
  34. 68 0
      .agents/skills/lark-base/references/lark-base-form-get.md
  35. 73 0
      .agents/skills/lark-base/references/lark-base-form-list.md
  36. 118 0
      .agents/skills/lark-base/references/lark-base-form-questions-create.md
  37. 68 0
      .agents/skills/lark-base/references/lark-base-form-questions-delete.md
  38. 84 0
      .agents/skills/lark-base/references/lark-base-form-questions-list.md
  39. 92 0
      .agents/skills/lark-base/references/lark-base-form-questions-update.md
  40. 23 0
      .agents/skills/lark-base/references/lark-base-form-questions.md
  41. 82 0
      .agents/skills/lark-base/references/lark-base-form-update.md
  42. 24 0
      .agents/skills/lark-base/references/lark-base-form.md
  43. 16 0
      .agents/skills/lark-base/references/lark-base-history.md
  44. 76 0
      .agents/skills/lark-base/references/lark-base-record-batch-create.md
  45. 71 0
      .agents/skills/lark-base/references/lark-base-record-batch-update.md
  46. 51 0
      .agents/skills/lark-base/references/lark-base-record-delete.md
  47. 38 0
      .agents/skills/lark-base/references/lark-base-record-get.md
  48. 86 0
      .agents/skills/lark-base/references/lark-base-record-history-list.md
  49. 83 0
      .agents/skills/lark-base/references/lark-base-record-list.md
  50. 72 0
      .agents/skills/lark-base/references/lark-base-record-search.md
  51. 51 0
      .agents/skills/lark-base/references/lark-base-record-upload-attachment.md
  52. 89 0
      .agents/skills/lark-base/references/lark-base-record-upsert.md
  53. 28 0
      .agents/skills/lark-base/references/lark-base-record.md
  54. 89 0
      .agents/skills/lark-base/references/lark-base-role-create.md
  55. 83 0
      .agents/skills/lark-base/references/lark-base-role-delete.md
  56. 87 0
      .agents/skills/lark-base/references/lark-base-role-get.md
  57. 81 0
      .agents/skills/lark-base/references/lark-base-role-list.md
  58. 94 0
      .agents/skills/lark-base/references/lark-base-role-update.md
  59. 679 0
      .agents/skills/lark-base/references/lark-base-shortcut-field-properties.md
  60. 200 0
      .agents/skills/lark-base/references/lark-base-shortcut-record-value.md
  61. 62 0
      .agents/skills/lark-base/references/lark-base-table-create.md
  62. 51 0
      .agents/skills/lark-base/references/lark-base-table-delete.md
  63. 46 0
      .agents/skills/lark-base/references/lark-base-table-get.md
  64. 43 0
      .agents/skills/lark-base/references/lark-base-table-list.md
  65. 49 0
      .agents/skills/lark-base/references/lark-base-table-update.md
  66. 20 0
      .agents/skills/lark-base/references/lark-base-table.md
  67. 83 0
      .agents/skills/lark-base/references/lark-base-view-create.md
  68. 48 0
      .agents/skills/lark-base/references/lark-base-view-delete.md
  69. 38 0
      .agents/skills/lark-base/references/lark-base-view-get-card.md
  70. 38 0
      .agents/skills/lark-base/references/lark-base-view-get-filter.md
  71. 38 0
      .agents/skills/lark-base/references/lark-base-view-get-group.md
  72. 38 0
      .agents/skills/lark-base/references/lark-base-view-get-sort.md
  73. 38 0
      .agents/skills/lark-base/references/lark-base-view-get-timebar.md
  74. 38 0
      .agents/skills/lark-base/references/lark-base-view-get-visible-fields.md
  75. 38 0
      .agents/skills/lark-base/references/lark-base-view-get.md
  76. 44 0
      .agents/skills/lark-base/references/lark-base-view-list.md
  77. 44 0
      .agents/skills/lark-base/references/lark-base-view-rename.md
  78. 81 0
      .agents/skills/lark-base/references/lark-base-view-set-card.md
  79. 92 0
      .agents/skills/lark-base/references/lark-base-view-set-filter.md
  80. 77 0
      .agents/skills/lark-base/references/lark-base-view-set-group.md
  81. 77 0
      .agents/skills/lark-base/references/lark-base-view-set-sort.md
  82. 79 0
      .agents/skills/lark-base/references/lark-base-view-set-timebar.md
  83. 73 0
      .agents/skills/lark-base/references/lark-base-view-set-visible-fields.md
  84. 44 0
      .agents/skills/lark-base/references/lark-base-view.md
  85. 180 0
      .agents/skills/lark-base/references/lark-base-workflow-create.md
  86. 94 0
      .agents/skills/lark-base/references/lark-base-workflow-disable.md
  87. 94 0
      .agents/skills/lark-base/references/lark-base-workflow-enable.md
  88. 147 0
      .agents/skills/lark-base/references/lark-base-workflow-get.md
  89. 718 0
      .agents/skills/lark-base/references/lark-base-workflow-guide.md
  90. 123 0
      .agents/skills/lark-base/references/lark-base-workflow-list.md
  91. 935 0
      .agents/skills/lark-base/references/lark-base-workflow-schema.md
  92. 167 0
      .agents/skills/lark-base/references/lark-base-workflow-update.md
  93. 23 0
      .agents/skills/lark-base/references/lark-base-workflow.md
  94. 18 0
      .agents/skills/lark-base/references/lark-base-workspace.md
  95. 508 0
      .agents/skills/lark-base/references/lookup-field-guide.md
  96. 532 0
      .agents/skills/lark-base/references/role-config.md
  97. 143 0
      .agents/skills/lark-calendar/SKILL.md
  98. 78 0
      .agents/skills/lark-calendar/references/lark-calendar-agenda.md
  99. 109 0
      .agents/skills/lark-calendar/references/lark-calendar-create.md
  100. 124 0
      .agents/skills/lark-calendar/references/lark-calendar-freebusy.md

+ 48 - 0
.agents/skills/lark-approval/SKILL.md

@@ -0,0 +1,48 @@
+---
+name: lark-approval
+version: 1.0.0
+description: "飞书审批 API:审批实例、审批任务管理。"
+metadata:
+  requires:
+    bins: ["lark-cli"]
+  cliHelp: "lark-cli approval --help"
+---
+
+# approval (v4)
+
+**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),其中包含认证、权限处理**
+
+## API Resources
+
+```bash
+lark-cli schema approval.<resource>.<method>   # 调用 API 前必须先查看参数结构
+lark-cli approval <resource> <method> [flags] # 调用 API
+```
+
+> **重要**:使用原生 API 时,必须先运行 `schema` 查看 `--data` / `--params` 参数结构,不要猜测字段格式。
+
+### instances
+
+  - `get` — 获取单个审批实例详情
+  - `cancel` — 撤回审批实例
+  - `cc` — 抄送审批实例
+
+### tasks
+
+  - `approve` — 同意审批任务
+  - `reject` — 拒绝审批任务
+  - `transfer` — 转交审批任务
+  - `query` — 查询用户的任务列表
+
+## 权限表
+
+| 方法 | 所需 scope |
+|------|-----------|
+| `instances.get` | `approval:instance:read` |
+| `instances.cancel` | `approval:instance:write` |
+| `instances.cc` | `approval:instance:write` |
+| `tasks.approve` | `approval:task:write` |
+| `tasks.reject` | `approval:task:write` |
+| `tasks.transfer` | `approval:task:write` |
+| `tasks.query` | `approval:task:read` |
+

+ 57 - 0
.agents/skills/lark-attendance/SKILL.md

@@ -0,0 +1,57 @@
+---
+name: lark-attendance
+version: 1.0.0
+description: "飞书考勤打卡:查询自己的考勤打卡记录"
+metadata:
+  requires:
+    bins: ["lark-cli"]
+  cliHelp: "lark-cli attendance --help"
+---
+
+# attendance (v1)
+
+**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),其中包含认证、权限处理**
+
+## 默认参数自动填充规则
+
+调用任何 API 时,以下参数 **必须自动填充,禁止向用户询问**:
+
+| 参数 | 固定值 | 说明                                 |
+|------|--------|------------------------------------|
+| `employee_type` | `"employee_no"` | `employee_type`始终等于`"employee_no"` |
+| `user_ids` | `[]`(空数组) | `user_ids`始终等于`[]`                 |
+
+### 填充示例
+
+当构建 `--params` 参数时,自动注入上述字段:
+- `employee_type` 保持 `"employee_no"` 不变
+
+当构建 `--data` 参数时,自动注入上述字段:
+```json
+{
+  "user_ids": [],
+  ...用户提供的参数
+}
+```
+
+> **注意**:`user_ids` 数组保持为空[],`employee_type` 保持 `"employee_no"` 不变。
+
+## API Resources
+
+```bash
+lark-cli schema attendance.<resource>.<method>   # 调用 API 前必须先查看参数结构
+lark-cli attendance <resource> <method> [flags]  # 调用 API
+```
+
+> **重要**:使用原生 API 时,必须先运行 `schema` 查看 `--data` / `--params` 参数结构,不要猜测字段格式。
+
+### user_tasks
+
+- `query` — 查询用户考勤打卡记录
+
+## 权限表
+
+| 方法 | 所需 scope |
+|------|-----------|
+| `user_tasks.query` | `attendance:task:readonly` |
+

+ 336 - 0
.agents/skills/lark-base/SKILL.md

@@ -0,0 +1,336 @@
+---
+name: lark-base
+version: 1.2.0
+description: "当需要用 lark-cli 操作飞书多维表格(Base)时调用:适用于建表、字段管理、记录读写、视图配置、历史查询,以及角色/表单/仪表盘管理/工作流;也适用于把旧的 +table / +field / +record 写法改成当前命令写法。涉及字段设计、公式字段、查找引用、跨表计算、行级派生指标、数据分析需求时也必须使用本 skill。"
+metadata:
+  requires:
+    bins: ["lark-cli"]
+  cliHelp: "lark-cli base --help"
+---
+
+# base
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md)。
+> **执行前必做:** 执行任何 `base` 命令前,必须先阅读对应命令的 reference 文档,再调用命令。
+> **命名约定:** Base 业务命令仅使用 `lark-cli base +...` 形式;如需先解析 Wiki 链接,可先调用 `lark-cli wiki ...`。
+> **分流规则:** 如果用户要“把本地文件导入成 Base / 多维表格 / bitable”,第一步不是 `base`,而是 `lark-cli drive +import --type bitable`;导入完成后再回到 `lark-cli base +...` 做表内操作。
+
+## 1. 何时使用本 Skill
+
+### 1.1 触发条件
+
+以下场景应使用本 skill:
+
+- 用户明确要操作飞书多维表格 / Base。
+- 用户要建表、改表、查表、删表,或管理字段、记录、视图。
+- 用户要做公式字段、lookup 字段、派生指标、跨表计算。
+- 用户要做临时统计、聚合分析、比较排序、求最值。
+- 用户要管理 workflow、dashboard、表单、角色权限。
+- 用户给出 `/base/{token}` 链接。
+- 用户给出 `/wiki/{token}` 链接,且最终解析为 `bitable`。
+- 用户要把旧的 Base 聚合式写法改成当前原子命令写法,例如把旧 `+table / +field / +record / +view / +history / +workspace` 改写成当前命令。
+
+以下场景不应使用本 skill:
+
+- 用户只是做认证、初始化配置、切换 `--as user/bot`、处理 scope。此时先读 `../lark-shared/SKILL.md`。
+- 用户只是泛化地讨论“数据分析 / 字段设计”,但并不在 Base 场景中。不要因为提到“统计 / 公式 / lookup”就误触发。
+
+### 1.2 前置约束
+
+1. 先阅读 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md)。
+2. Base 业务命令仅使用 `lark-cli base +...` 形式的 shortcut 命令;如果输入是 Wiki 链接,可先调用 `lark-cli wiki spaces get_node` 解析真实 token。
+3. 定位到命令后,先读该命令对应的 reference,再执行命令。
+4. 如果用户要把本地 Excel / CSV 导入成 Base / 多维表格 / bitable,第一步不是 `base`,而是 `lark-cli drive +import --type bitable`;导入完成后再回到 `lark-cli base +...` 做表内操作。
+5. 不要在 Base 场景改走 `lark-cli api /open-apis/bitable/v1/...`。
+
+## 2. 模块与命令导航
+
+本章按“先选模块,再选命令”的方式组织。先判断用户目标属于哪个大模块,再进入对应子模块,按要求阅读 reference 后执行命令。
+
+### 2.1 模块地图
+
+| 大模块 | 处理什么问题 | 包含的小模块 / 能力 |
+|------|-------------|-------------------|
+| Base 模块 | 管理 Base 本体,或从链接进入 Base 场景 | `base-create / base-get / base-copy`,Base / Wiki 链接解析 |
+| 表与数据模块 | 管理 Base 内部结构与日常数据操作 | `table / field / record / view` |
+| 公式 / Lookup 模块 | 处理派生字段、条件判断、跨表计算、固定查找引用 | `formula / lookup` 字段创建与更新 |
+| 数据分析模块 | 做一次性筛选、分组、聚合分析 | `data-query` |
+| Workflow 模块 | 管理自动化流程 | `workflow-list / get / create / update / enable / disable` |
+| Dashboard 模块 | 管理仪表盘和图表组件 | `dashboard-* / dashboard-block-*` |
+| 表单模块 | 管理表单和表单题目 | `form-* / form-questions-*` |
+| 权限与角色模块 | 管理高级权限和自定义角色 | `advperm-* / role-*` |
+
+### 2.2 Base 模块
+
+用于管理 Base 本体,或从用户给出的链接进入后续 Base 操作。  
+模块索引:[`references/lark-base-workspace.md`](references/lark-base-workspace.md)
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+base-create` | 创建新的 Base | [`lark-base-base-create.md`](references/lark-base-base-create.md)、[`lark-base-workspace.md`](references/lark-base-workspace.md) | 写入操作;执行前先读 reference;`--folder-token`、`--time-zone` 都是可选项 |
+| `+base-get` | 获取 Base 信息 | [`lark-base-base-get.md`](references/lark-base-base-get.md)、[`lark-base-workspace.md`](references/lark-base-workspace.md) | 适合确认 Base 本体信息,不替代表/字段结构读取 |
+| `+base-copy` | 复制已有 Base | [`lark-base-base-copy.md`](references/lark-base-base-copy.md)、[`lark-base-workspace.md`](references/lark-base-workspace.md) | 写入操作;执行前先读 reference;复制成功后应主动返回新 Base 标识信息 |
+
+### 2.3 表与数据模块
+
+这是最常用的大模块,包含 `table / field / record / view` 四类子模块。  
+补充示例:[`references/examples.md`](references/examples.md),适合需要串联 table / record / view 完整操作链路时再读。
+
+#### 2.3.1 Table 子模块
+
+子模块索引:[`references/lark-base-table.md`](references/lark-base-table.md)
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+table-list / +table-get` | 列出数据表,或获取单个表详情 | [`lark-base-table-list.md`](references/lark-base-table-list.md)、[`lark-base-table-get.md`](references/lark-base-table-get.md) | `+table-list` 只能串行执行;`+table-get` 适合删除/修改前确认目标 |
+| `+table-create / +table-update / +table-delete` | 创建、更新或删除数据表 | [`lark-base-table-create.md`](references/lark-base-table-create.md)、[`lark-base-table-update.md`](references/lark-base-table-update.md)、[`lark-base-table-delete.md`](references/lark-base-table-delete.md) | 创建适合一次性建表;更新前先确认目标表;删除时用户已明确目标可直接执行并带 `--yes` |
+
+#### 2.3.2 Field 子模块
+
+普通字段管理走这里;如果字段类型是 `formula` 或 `lookup`,转到下方“公式 / Lookup 模块”。  
+子模块索引:[`references/lark-base-field.md`](references/lark-base-field.md)
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+field-list / +field-get` | 列出字段结构,或获取单个字段详情 | [`lark-base-field-list.md`](references/lark-base-field-list.md)、[`lark-base-field-get.md`](references/lark-base-field-get.md) | 写记录、写字段、做分析前常先读 `+field-list`;`+field-list` 只能串行执行;`+field-get` 适合删除/更新前确认目标 |
+| `+field-create / +field-update / +field-delete` | 创建、更新或删除普通字段 | [`lark-base-field-create.md`](references/lark-base-field-create.md)、[`lark-base-field-update.md`](references/lark-base-field-update.md)、[`lark-base-field-delete.md`](references/lark-base-field-delete.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 写字段前先看字段属性规范;如果类型是 `formula / lookup`,先转去读对应 guide;删除时用户已明确目标可直接执行并带 `--yes` |
+| `+field-search-options` | 查询字段可选项 | [`lark-base-field-search-options.md`](references/lark-base-field-search-options.md) | 适合单选/多选等选项型字段 |
+
+#### 2.3.3 Record 子模块
+
+子模块索引:[`references/lark-base-record.md`](references/lark-base-record.md)、[`references/lark-base-history.md`](references/lark-base-history.md)
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+record-search / +record-list / +record-get` | 按关键词检索记录、读取记录明细 / 分页导出,或获取单条记录详情 | [`lark-base-record-search.md`](references/lark-base-record-search.md)、[`lark-base-record-list.md`](references/lark-base-record-list.md)、[`lark-base-record-get.md`](references/lark-base-record-get.md) | 默认优先 `+record-list`;仅当用户提供明确搜索关键词时使用 `+record-search`;取数不用来做聚合分析;`--limit` 最大 `200`;仅在用户明确需要时继续翻页;`+record-list` 只能串行执行 |
+| `+record-upsert / +record-batch-create / +record-batch-update` | 创建、更新或批量写入记录 | [`lark-base-record-upsert.md`](references/lark-base-record-upsert.md)、[`lark-base-record-batch-create.md`](references/lark-base-record-batch-create.md)、[`lark-base-record-batch-update.md`](references/lark-base-record-batch-update.md)、[`lark-base-shortcut-record-value.md`](references/lark-base-shortcut-record-value.md) | 写前先 `+field-list`;只写存储字段;`+record-batch-update` 为同值更新(同一 patch 应用到多条记录);批量单次不超过 `200` 条;附件不要走这里 |
+| `+record-upload-attachment` | 给已有记录上传附件 | [`lark-base-record-upload-attachment.md`](references/lark-base-record-upload-attachment.md) | 附件上传专用链路,不要用 `+record-upsert` / `+record-batch-*` 伪造附件值 |
+| `lark-cli docs +media-download` | 下载 Base 附件文件到本地 | [`../lark-doc/references/lark-doc-media-download.md`](../lark-doc/references/lark-doc-media-download.md) | Base 附件的 `file_token` 从 `+record-get` 返回的附件字段数组里取;**不要用 `lark-cli drive +download`**(对 Base 附件返回 403) |
+| `+record-delete / +record-history-list` | 删除记录,或查询某条记录的变更历史 | [`lark-base-record-delete.md`](references/lark-base-record-delete.md)、[`lark-base-record-history-list.md`](references/lark-base-record-history-list.md) | 删除时用户已明确目标可直接执行并带 `--yes`;历史查询按 `table-id + record-id`,不支持整表扫描;`+record-history-list` 只能串行执行 |
+
+#### 2.3.4 View 子模块
+
+子模块索引:[`references/lark-base-view.md`](references/lark-base-view.md)
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+view-list / +view-get` | 列出视图,或获取视图详情 | [`lark-base-view-list.md`](references/lark-base-view-list.md)、[`lark-base-view-get.md`](references/lark-base-view-get.md) | `+view-list` 只能串行执行;`+view-get` 适合查看已有视图配置 |
+| `+view-create / +view-delete / +view-rename` | 创建、删除或重命名视图 | [`lark-base-view-create.md`](references/lark-base-view-create.md)、[`lark-base-view-delete.md`](references/lark-base-view-delete.md)、[`lark-base-view-rename.md`](references/lark-base-view-rename.md) | 创建前先确认表和视图类型;删除前先确认目标;用户已明确新名字时可直接重命名 |
+| `+view-get-filter / +view-set-filter` | 读取或配置筛选条件 | [`lark-base-view-get-filter.md`](references/lark-base-view-get-filter.md)、[`lark-base-view-set-filter.md`](references/lark-base-view-set-filter.md)、[`lark-base-record-list.md`](references/lark-base-record-list.md) | 常与 `+record-list` 组合,用于按视图筛选读取 |
+| `+view-get-sort / +view-set-sort` | 读取或配置排序 | [`lark-base-view-get-sort.md`](references/lark-base-view-get-sort.md)、[`lark-base-view-set-sort.md`](references/lark-base-view-set-sort.md) | 字段名必须来自真实结构 |
+| `+view-get-group / +view-set-group` | 读取或配置分组 | [`lark-base-view-get-group.md`](references/lark-base-view-get-group.md)、[`lark-base-view-set-group.md`](references/lark-base-view-set-group.md) | 字段名必须来自真实结构 |
+| `+view-get-visible-fields / +view-set-visible-fields` | 读取或配置视图可见字段 | [`lark-base-view-get-visible-fields.md`](references/lark-base-view-get-visible-fields.md)、[`lark-base-view-set-visible-fields.md`](references/lark-base-view-set-visible-fields.md) | 用于控制视图中的字段顺序与可见性;字段名必须来自真实结构 |
+| `+view-get-card / +view-set-card` | 读取或配置卡片视图 | [`lark-base-view-get-card.md`](references/lark-base-view-get-card.md)、[`lark-base-view-set-card.md`](references/lark-base-view-set-card.md) | 适合卡片展示场景 |
+| `+view-get-timebar / +view-set-timebar` | 读取或配置时间轴视图 | [`lark-base-view-get-timebar.md`](references/lark-base-view-get-timebar.md)、[`lark-base-view-set-timebar.md`](references/lark-base-view-set-timebar.md) | 适合时间线展示场景 |
+
+### 2.4 公式 / Lookup 模块
+
+只要用户诉求涉及派生指标、条件判断、文本处理、日期差、跨表计算、跨表筛选后取值,都要先判断是否进入本模块。
+
+默认优先考虑 `formula`:适合常规计算、条件判断、文本处理、日期差、跨表聚合,以及需要长期显示在表里的派生结果。  
+只有当用户明确要求 `lookup`,或场景天然符合 `from / select / where / aggregate` 这种固定查找建模时,再使用 `lookup`。
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+field-create`(`type=formula`) | 创建公式字段 | [`formula-field-guide.md`](references/formula-field-guide.md)、[`lark-base-field-create.md`](references/lark-base-field-create.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 没读 guide 前不要直接创建 |
+| `+field-update`(`type=formula`) | 更新公式字段 | [`formula-field-guide.md`](references/formula-field-guide.md)、[`lark-base-field-update.md`](references/lark-base-field-update.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 先拿当前表结构 |
+| `+field-create`(`type=lookup`) | 创建 lookup 字段 | [`lookup-field-guide.md`](references/lookup-field-guide.md)、[`lark-base-field-create.md`](references/lark-base-field-create.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 没读 guide 前不要直接创建 |
+| `+field-update`(`type=lookup`) | 更新 lookup 字段 | [`lookup-field-guide.md`](references/lookup-field-guide.md)、[`lark-base-field-update.md`](references/lark-base-field-update.md)、[`lark-base-shortcut-field-properties.md`](references/lark-base-shortcut-field-properties.md) | 跨表时还要拿目标表结构 |
+
+### 2.5 数据分析模块
+
+用于一次性分析和临时聚合查询。用户要的是“这次算出来的结果”,而不是把结果沉淀成字段时,优先进入本模块。
+
+进入本模块前先确认几件事:
+
+- `+data-query` 只做聚合查询(分组、过滤、排序、聚合计算),不用于列出原始记录或逐条明细。
+- 调用者必须是目标多维表格的管理员,拥有目标多维表格的 FA(Full Access / 完全访问权限),否则会返回权限错误。
+- `+data-query` 只支持白名单字段类型;`formula`、`lookup`、附件、系统字段、关联等字段不能用于 `dimensions / measures / filters / sort`。
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+data-query` | 做分组统计、SUM / AVG / COUNT / MAX / MIN、条件筛选后的聚合分析 | [`lark-base-data-query.md`](references/lark-base-data-query.md) | 字段名必须精确匹配真实字段名;不要用 `+record-list` / `+record-search` 拉全量再手算;`+data-query` 不返回原始记录;使用前先确认权限和字段类型是否受支持 |
+
+### 2.6 Workflow 模块
+
+这是高约束模块。执行任何 workflow 命令前,都必须先读对应命令文档和 schema。  
+模块索引:[`references/lark-base-workflow.md`](references/lark-base-workflow.md)
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+workflow-list / +workflow-get` | 列出 workflow,或获取完整 workflow 结构 | [`lark-base-workflow-list.md`](references/lark-base-workflow-list.md)、[`lark-base-workflow-get.md`](references/lark-base-workflow-get.md)、[`lark-base-workflow-schema.md`](references/lark-base-workflow-schema.md) | `+workflow-list` 只返回摘要且只能串行执行;需要完整结构时用 `+workflow-get` |
+| `+workflow-create / +workflow-update` | 创建或更新 workflow | [`lark-base-workflow-create.md`](references/lark-base-workflow-create.md)、[`lark-base-workflow-update.md`](references/lark-base-workflow-update.md)、[`lark-base-workflow-schema.md`](references/lark-base-workflow-schema.md) | 先读 schema;禁止凭自然语言猜 `type`;先确认真实表名和字段名 |
+| `+workflow-enable / +workflow-disable` | 启用或停用 workflow | [`lark-base-workflow-enable.md`](references/lark-base-workflow-enable.md)、[`lark-base-workflow-disable.md`](references/lark-base-workflow-disable.md)、[`lark-base-workflow-schema.md`](references/lark-base-workflow-schema.md) | 启用或停用前先确认目标 workflow;`workflow_id` 与 `table_id` 需按前缀区分 |
+
+### 2.7 Dashboard 模块
+
+当用户提到“仪表盘、dashboard、数据看板、图表、可视化、block、组件、添加组件、创建图表”等关键词时,进入本模块,并先阅读 [`lark-base-dashboard.md`](references/lark-base-dashboard.md)。
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+dashboard-list / +dashboard-get` | 列出仪表盘,或获取仪表盘详情 | [`lark-base-dashboard-list.md`](references/lark-base-dashboard-list.md)、[`lark-base-dashboard-get.md`](references/lark-base-dashboard-get.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md) | 进入仪表盘语义后先读 guide;`+dashboard-list` 只能串行执行 |
+| `+dashboard-create / +dashboard-update / +dashboard-delete` | 创建、更新或删除仪表盘 | [`lark-base-dashboard-create.md`](references/lark-base-dashboard-create.md)、[`lark-base-dashboard-update.md`](references/lark-base-dashboard-update.md)、[`lark-base-dashboard-delete.md`](references/lark-base-dashboard-delete.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md) | 创建前先明确看板目标和展示场景;更新前先读取当前配置;删除前先确认目标 |
+| `+dashboard-block-list / +dashboard-block-get` | 列出图表组件,或获取单个 block 详情 | [`lark-base-dashboard-block-list.md`](references/lark-base-dashboard-block-list.md)、[`lark-base-dashboard-block-get.md`](references/lark-base-dashboard-block-get.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md)、[`dashboard-block-data-config.md`](references/dashboard-block-data-config.md) | `+dashboard-block-list` 只能串行执行;查看配置细节时读 block config 文档 |
+| `+dashboard-block-create / +dashboard-block-update / +dashboard-block-delete` | 创建、更新或删除图表组件 | [`lark-base-dashboard-block-create.md`](references/lark-base-dashboard-block-create.md)、[`lark-base-dashboard-block-update.md`](references/lark-base-dashboard-block-update.md)、[`lark-base-dashboard-block-delete.md`](references/lark-base-dashboard-block-delete.md)、[`lark-base-dashboard.md`](references/lark-base-dashboard.md)、[`dashboard-block-data-config.md`](references/dashboard-block-data-config.md) | 涉及 `data_config`、图表类型、filter 时要读 block config 文档;删除前先确认目标 |
+
+### 2.8 表单模块
+
+用于管理表单本体和表单题目。  
+模块索引:[`references/lark-base-form.md`](references/lark-base-form.md)、[`references/lark-base-form-questions.md`](references/lark-base-form-questions.md)  
+表单问题相关操作依赖 `form-id`;具体获取方式见 `form-list` 和 `form-create` 的 reference。
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+form-list / +form-get` | 列出表单,或获取单个表单 | [`lark-base-form-list.md`](references/lark-base-form-list.md)、[`lark-base-form-get.md`](references/lark-base-form-get.md) | `+form-list` 可用来获取 `form-id`;`+form-get` 适合查看已有表单配置 |
+| `+form-create / +form-update / +form-delete` | 创建、更新或删除表单 | [`lark-base-form-create.md`](references/lark-base-form-create.md)、[`lark-base-form-update.md`](references/lark-base-form-update.md)、[`lark-base-form-delete.md`](references/lark-base-form-delete.md) | 创建后可继续进入表单问题相关操作;更新或删除前先确认目标表单 |
+| `+form-questions-list` | 列出表单题目 | [`lark-base-form-questions-list.md`](references/lark-base-form-questions-list.md) | 适合查看已有题目结构 |
+| `+form-questions-create / +form-questions-update / +form-questions-delete` | 创建、更新或删除题目 | [`lark-base-form-questions-create.md`](references/lark-base-form-questions-create.md)、[`lark-base-form-questions-update.md`](references/lark-base-form-questions-update.md)、[`lark-base-form-questions-delete.md`](references/lark-base-form-questions-delete.md) | 先确认 `form-id`;更新或删除前先确认题目目标 |
+
+### 2.9 权限与角色模块
+
+用于启用高级权限,以及管理 Base 自定义角色。  
+涉及 `+advperm-enable / +advperm-disable / +role-*` 时,操作用户必须为 Base 管理员,否则会返回权限错误。
+
+| 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 |
+|------|------------------|----------------|----------|
+| `+advperm-enable / +advperm-disable` | 启用或停用高级权限 | [`lark-base-advperm-enable.md`](references/lark-base-advperm-enable.md)、[`lark-base-advperm-disable.md`](references/lark-base-advperm-disable.md) | 管理角色前必须先启用;停用是高风险操作,会使已有自定义角色失效 |
+| `+role-list / +role-get` | 列出角色,或获取角色详情 | [`lark-base-role-list.md`](references/lark-base-role-list.md)、[`lark-base-role-get.md`](references/lark-base-role-get.md)、[`role-config.md`](references/role-config.md) | `+role-list` 只能串行执行;`+role-get` 适合查看完整权限配置 |
+| `+role-create / +role-update / +role-delete` | 创建、更新或删除角色 | [`lark-base-role-create.md`](references/lark-base-role-create.md)、[`lark-base-role-update.md`](references/lark-base-role-update.md)、[`lark-base-role-delete.md`](references/lark-base-role-delete.md)、[`role-config.md`](references/role-config.md) | `+role-create` 仅支持 `custom_role`;`+role-update` 采用 Delta Merge,`role_name` 和 `role_type` 即使不改也必须传当前值;`+role-delete` 不可逆 |
+
+## 3. 多维表格通用知识
+
+飞书多维表格英文名是 `Base`,曾用名 `Bitable`;因此旧文档、返回字段、参数名或错误信息里出现 `bitable` 多属历史兼容,不代表应改用另一套命令体系。
+
+### 3.1 字段分类与可写性
+
+| 字段类型 | 含义 | 能否直接作为 `+record-upsert / +record-batch-create / +record-batch-update` 写入目标 | 说明 |
+|----------|------|-----------------------------------------------------------|------|
+| 存储字段 | 真实存用户输入的数据 | 可以 | 常见如文本、数字、日期、单选、多选、人员、关联 |
+| 附件字段 | 存储文件附件 | 不应直接按普通字段写 | 上传附件走 `+record-upload-attachment`;下载附件走 `lark-cli docs +media-download` |
+| 系统字段 | 平台自动维护 | 不可以 | 常见如创建时间、更新时间、创建人、修改人、自动编号 |
+| `formula` 字段 | 通过表达式计算 | 不可以 | 只读字段 |
+| `lookup` 字段 | 通过跨表规则查找引用 | 不可以 | 只读字段 |
+
+### 3.2 任务选路心智模型
+
+| 用户诉求 | 优先方案 | 不要误走 |
+|---------|----------|----------|
+| 一次性分析 / 临时统计 | `+data-query` | 不要用 `+record-list` / `+record-search` 拉全量后手算 |
+| 要把结果长期显示在表里 | `formula` 字段 | 不要只给一次性手工分析结果 |
+| 用户明确要求 lookup,或天然是固定查找配置 | `lookup` 字段 | 不要默认先上 lookup;先判断 formula 是否更合适 |
+| 读取原始记录明细 / 关键词检索 / 导出 | `+record-search / +record-list / +record-get` | 不要拿 `+data-query` 当取数命令 |
+| 上传附件到记录 | `+record-upload-attachment` | 不要用 `+record-upsert` / `+record-batch-*` 伪造附件值 |
+| 下载记录里的附件文件 | `lark-cli docs +media-download --token <file_token> --output <path>` | `file_token` 从 `+record-get` 返回的附件字段里取;用法见 [`../lark-doc/references/lark-doc-media-download.md`](../lark-doc/references/lark-doc-media-download.md) |
+| 基于视图做筛选读取 | `+view-set-filter` + `+record-list` | 不要跳过视图筛选直接猜条件 |
+| 本地 Excel / CSV 导入为 Base | `lark-cli drive +import --type bitable` | 不要误走 `+base-create`、`+table-create` 或 `+record-upsert` |
+
+### 3.3 表名、字段名与表达式引用
+
+1. 表名、字段名必须精确匹配真实返回,来源应是 `+table-list / +table-get / +field-list`。
+2. 不要凭自然语言猜名称,不要自行改写用户口述中的表名、字段名。
+3. `formula / lookup / data-query / workflow` 中出现的名称同样必须精确匹配;表达式引用、where 条件、DSL 字段名、workflow 配置都遵守同一规则。
+4. 跨表场景必须额外读取目标表结构,不能只看当前表。
+
+### 3.4 Token 与链接
+
+这是高优先级章节。只要用户输入里出现链接、token,或报错涉及 `baseToken` / `wiki_token` / `obj_token`,都应优先回到这里检查。
+
+| 输入类型 | 正确处理方式 | 说明 |
+|---------|--------------|------|
+| 直接 Base 链接 `/base/{token}` | 直接提取 token 作为 `--base-token` | 不要把完整 URL 直接作为 `--base-token` |
+| Wiki 链接 `/wiki/{token}` | 先 `wiki.spaces.get_node`,再取 `node.obj_token` | 不要把 `wiki_token` 直接当 `--base-token` |
+| URL 中的 `?table={id}` | 先按前缀判断对象类型 | `tbl` 开头表示数据表 `table-id`,可作为 `--table-id`;`blk` 开头表示仪表盘 `dashboard-ID`;`wkf` 开头表示 `workflow-ID`;`ldx` 开头表示内嵌文档,不要一律当成 `--table-id` |
+| URL 中的 `?view={id}` | 提取为 `--view-id` | 适合直接定位视图 |
+
+| `lark-cli wiki spaces get_node` 返回的 `obj_type` | 后续路线 | 说明 |
+|-----------------------------------------------|----------|------|
+| `bitable` | 优先走 `lark-cli base +...` | 如果 shortcut 不覆盖,再用 `lark-cli base <resource> <method>`;不要改走 `lark-cli api /open-apis/bitable/v1/...` |
+| `docx` | 转到文档 / Drive 相关 skill | 不继续使用本 skill 的 Base 命令 |
+| `sheet` | 转到 Sheets 相关 skill | 不继续使用本 skill 的 Base 命令 |
+| `slides` | 转到 Drive 相关 skill | 不继续使用本 skill 的 Base 命令 |
+| `mindnote` | 转到 Drive 相关 skill | 不继续使用本 skill 的 Base 命令 |
+
+### 3.5 身份选择与权限降级策略
+
+多维表格通常属于用户的个人或团队资源。**默认应优先使用 `--as user`(用户身份)执行所有 Base 操作**,始终显式指定身份。
+
+- **`--as user`(推荐)**:以当前登录用户身份操作其有权访问的 Base。执行前先完成用户授权:
+
+```bash
+lark-cli auth login --domain base
+```
+
+- **`--as bot`(降级)**:仅当 user 身份权限不足、且 bot 身份确实拥有目标 Base 的访问权限时,才降级使用。bot 看不到用户私有资源,行为以应用身份执行。
+
+**执行规则**:
+
+1. 所有操作默认先用 `--as user`。
+2. 若 user 身份返回权限错误,先判断是否为**不可重试错误码**(如 `91403`)。若是,**立即停止**,不做任何重试或降级,直接按 `lark-shared` 权限不足处理流程引导用户解决。
+3. 非不可重试错误码时,检查错误响应中是否包含 `permission_violations` / `hint` 等提权引导信息:
+   - **有提权引导**:按 `lark-shared` 权限不足处理流程,先引导用户完成 user 身份提权(`auth login --scope`);确认提权成功后,以 `--as user` 重试。
+   - **无提权引导**(如资源级无访问权限、非 scope 不足):切换到 `--as bot` 重试**一次**。
+4. 若 bot 身份仍然返回权限错误,**立即停止重试**,根据错误响应按 `lark-shared` 流程引导用户解决(引导去开发者后台开通 scope 或确认资源访问权限)。
+5. 只有在用户明确要求"用应用身份 / bot 身份操作",才跳过 user 直接使用 `--as bot`。
+
+**补充说明**:
+
+- 人员字段 / 用户字段:注意 `user_id_type` 与执行身份(user / bot)差异。
+
+## 4. 执行规则
+
+### 4.1 标准执行顺序
+
+1. 先判断任务属于哪个模块,选对命令族。
+2. 如果用户给了链接,先解析 token,不要把 wiki token、完整 URL 或其他对象 ID 误当成 `base_token`。
+3. 先拿结构,再写命令,避免猜表名、字段名、表达式引用。
+4. 定位到命令后,先读对应 reference,再执行命令。
+5. 执行命令,并按返回结果判断下一步。
+6. 回复时返回关键结果和后续可继续操作的信息,方便 agent 链式执行下一步。
+
+### 4.2 不可违反规则
+
+1. 先拿结构,再写命令;至少先拿当前表结构,跨表时还要拿目标表结构。
+2. 不要猜表名、字段名、表达式引用,一律以真实返回为准。
+3. 只使用原子命令;不要回退到旧的聚合式 `+table / +field / +record / +view / +history / +workspace`。
+4. 写记录前先读字段结构;先 `+field-list`,再按字段类型构造写入值。
+5. 写字段前先看字段属性规范;先读 `lark-base-shortcut-field-properties.md`,再构造 `+field-create / +field-update` 的 JSON。
+6. 只写可写字段;系统字段、附件字段、`formula`、`lookup` 默认不作为普通记录写入目标。
+7. 聚合分析与取数分流;统计走 `+data-query`,关键词检索走 `+record-search`,明细走 `+record-list / +record-get`。
+8. 筛选查询按视图能力执行;先用 `+view-set-filter` 配置筛选,再结合 `+record-list` 读取。
+9. Base 场景不要改走裸 API,不要切去 `lark-cli api /open-apis/bitable/v1/...`。
+10. 统一使用 `--base-token`,不使用旧 `--app-token`。
+11. workflow 场景先读 schema,不要凭自然语言猜 `type`。
+12. dashboard 场景先读 guide;提到图表、看板、block 就先进入 dashboard 模块。
+13. formula / lookup 场景先读 guide;没读 guide 前不要直接创建或更新。
+
+### 4.3 并发、分页与批量限制
+
+- `+table-list / +field-list / +record-list / +view-list / +record-history-list / +role-list / +dashboard-list / +dashboard-block-list / +workflow-list` 禁止并发调用,只能串行执行。
+- `+record-list` 分页时,`--limit` 最大 `200`;先拉首批并检查 `has_more`,只有用户明确需要更多数据时再继续翻页。
+- 批量写入时,单批不超过 `200` 条。
+- 连续写入同一表时,必须串行写入,批次间延迟 `0.5–1` 秒。
+
+### 4.4 确认与回复规则
+
+- 视图重命名时,用户已明确“把哪个视图改成什么名字”时,`+view-rename` 直接执行即可。
+- 删除记录 / 字段 / 表时,如果用户已经明确说要删除,且目标明确,`+record-delete / +field-delete / +table-delete` 可直接执行,并带 `--yes`。
+- 删除目标仍有歧义时,先用 `+record-get / +field-get / +table-get` 或相应 list 命令确认。
+- `+base-create / +base-copy` 成功后,回复中必须主动返回新 Base 的标识信息;若结果带可访问链接,也应一并返回。
+- 若 Base 由 bot 身份创建或复制,shortcut 会自动尝试为当前 CLI 用户补授 `full_access`,并在输出中返回 `permission_grant`;agent 不需要再手动编排单独授权。owner 转移必须单独确认,禁止擅自执行。
+
+## 5. 常见错误与恢复
+
+| 错误 / 现象 | 含义 | 恢复动作 |
+|-------------|------|----------|
+| `1254064` | 日期格式错误 | 用毫秒时间戳,非字符串 / 秒级 |
+| `1254068` | 超链接格式错误 | 用 `{text, link}` 对象 |
+| `1254066` | 人员字段错误 | 用 `[{id:"ou_xxx"}]`,并确认 `user_id_type` |
+| `1254045` | 字段名不存在 | 检查字段名(含空格、大小写) |
+| `1254015` | 字段值类型不匹配 | 先 `+field-list`,再按类型构造 |
+| `param baseToken is invalid` / `base_token invalid` | 把 wiki token、workspace token 或其他 token 当成了 `base_token` | 如果输入来自 `/wiki/...`,先用 `lark-cli wiki spaces get_node` 取真实 `obj_token`;当 `obj_type=bitable` 时,用 `node.obj_token` 作为 `--base-token` 重试,不要改走 `bitable/v1` |
+| `not found` 且用户给的是 wiki 链接 | 常见于把 wiki token 当成 base token | 优先回退检查 wiki 解析,而不是改走 `bitable/v1` |
+| formula / lookup 创建失败 | 指南未读或结构不合法 | 先读 `formula-field-guide.md` / `lookup-field-guide.md`,再按 guide 重建请求 |
+| 系统字段 / 公式字段写入失败 | 只读字段被当成可写字段 | 改为写存储字段,计算结果交给 formula / lookup / 系统字段自动产出 |
+| `1254104` | 批量超 200 条 | 分批调用 |
+| `1254291` | 并发写冲突 | 串行写入 + 批次间延迟 |
+| `91403` | 无权限访问该 Base | **不要重试**。按 `lark-shared` 权限不足处理流程引导用户解决权限问题 |

+ 350 - 0
.agents/skills/lark-base/references/dashboard-block-data-config.md

@@ -0,0 +1,350 @@
+# dashboard block data_config 参考
+
+Block 的 `data_config` 字段因 `type` 不同而变化。本文档描述所有共享结构。
+
+## 支持的组件类型(`type` 枚举)
+
+| type 值 | 说明 |
+|---------|------|
+| `column` | 柱状图 |
+| `bar` | 条形图 |
+| `line` | 折线图 |
+| `pie` | 饼图 |
+| `ring` | 环形图 |
+| `area` | 面积图 |
+| `combo` | 组合图 |
+| `scatter` | 散点图 |
+| `funnel` | 漏斗图 |
+| `wordCloud` | 词云 |
+| `radar` | 雷达图 |
+| `statistics` | 指标卡 |
+| `text` | 文本(支持 Markdown) |
+
+## 字段类型与操作符速查(AI 决策用)
+
+> `+field-list` 返回的 `type` 字段映射:number(数字)、text(文本)、select(单选)、multi_select(多选)、datetime(日期时间)、checkbox(复选框)、user(人员)
+
+```
+文本/电话/URL/邮箱:  is, isNot, contains, doesNotContain, isEmpty, isNotEmpty
+数字/货币/进度:      is, isNot, isGreater, isGreaterEqual, isLess, isLessEqual, isEmpty, isNotEmpty
+单选:               is, isNot, isEmpty, isNotEmpty
+多选:               is, isNot, contains, doesNotContain, isEmpty, isNotEmpty
+日期/时间:          is, isGreater, isGreaterEqual, isLess, isLessEqual, isEmpty, isNotEmpty
+复选框:             is (value: true/false)
+人员/创建人/修改人:  is, isNot, isEmpty, isNotEmpty
+```
+
+## data_config 通用结构
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `table_name` | string | 关联数据表名称 |
+| `series` | `[{ "field_name": "xxx", "rollup": "SUM" }]` | 指标/Y 轴(与 `count_all` 二选一)。rollup 支持 `SUM` / `MAX` / `MIN` / `AVERAGE` |
+| `count_all` | boolean | COUNTA 聚合,统计所有记录数(与 `series` 二选一) |
+| `group_by` | `[{ "field_name": "xxx", "mode": "integrated", "sort": {...} }]` | X 轴分组维度。`mode` 必填,`sort` 可选,见下方说明 |
+| `filter` | object | 筛选条件 |
+| `filter.conjunction` | `"and"` / `"or"` | 筛选逻辑 |
+| `filter.conditions` | `[{ "field_name", "operator", "value" }]` | 筛选条件数组,value 类型因字段类型而异(见下方 filter 格式规则) |
+
+### text 类型特殊结构
+
+`text` 类型组件用于展示富文本内容,**不需要数据源配置**(无 `table_name`、`series`、`group_by`、`filter`)。
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `text` | string | **必填**。支持 Markdown 语法,详见下方说明 |
+
+**支持的 Markdown 语法:**
+
+| 语法 | 示例 | 效果 |
+|------|------|------|
+| 一级标题 | `# 标题` | 大标题 |
+| 二级标题 | `## 标题` | 中标题 |
+| 三级标题 | `### 标题` | 小标题 |
+| 加粗 | `**文字**` | **文字** |
+| 斜体 | `*文字*` | *文字* |
+| 删除线 | `~~文字~~` | ~~文字~~ |
+| 有序列表 | `1. 项目` | 1. 项目 |
+| 无序列表 | `- 项目` | - 项目 |
+
+> **注意**:以上未提及的 Markdown 语法(如链接、图片、代码块、表格等)均不支持。
+
+## group_by 详细说明
+
+### mode 枚举
+
+| mode | 含义 | 适用场景 |
+|------|------|----------|
+| `integrated` | 聚合分组(默认) | 绝大部分场景,按字段值分组统计 |
+| `enumerated` | 多值拆分统计 | 多选、人员等多值字段,将每个选项/人员拆开独立统计 |
+
+> 多选、人员等多值字段默认用 `enumerated`;其他字段默认用 `integrated`。
+
+### sort 排序
+
+| sort.type | 含义 | 典型场景 |
+|-----------|------|----------|
+| `group` | 按横轴值排序 | 按月份升序、按品类名字母序 |
+| `value` | 按纵轴值排序 | 按销售额从大到小 |
+| `view` | 按数据源记录顺序 | 保持原表行序(不常用) |
+
+`sort.order`:`asc`(升序)/ `desc`(降序)
+
+示例 — 柱状图按销售额降序:
+
+```json
+{
+  "table_name": "订单表",
+  "series": [{ "field_name": "金额", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "类别", "mode": "integrated", "sort": {"type": "value", "order": "desc"} }]
+}
+```
+
+## filter 格式规则
+
+**基本结构:**
+
+```json
+{
+  "filter": {
+    "conjunction": "and",
+    "conditions": [
+      { "field_name": "字段名", "operator": "操作符", "value": "值" }
+    ]
+  }
+}
+```
+
+**多条件示例(and/or):**
+
+```json
+{
+  "filter": {
+    "conjunction": "and",
+    "conditions": [
+      { "field_name": "状态", "operator": "is", "value": "已完成" },
+      { "field_name": "金额", "operator": "isGreater", "value": 1000 }
+    ]
+  }
+}
+```
+
+**操作符:**
+
+| 操作符 | 含义 | 是否需要 value |
+|--------|------|---------------|
+| `is` | 等于 | 是 |
+| `isNot` | 不等于 | 是 |
+| `contains` | 包含 | 是 |
+| `doesNotContain` | 不包含 | 是 |
+| `isEmpty` | 为空 | 否 |
+| `isNotEmpty` | 不为空 | 否 |
+| `isGreater` | 大于 | 是 |
+| `isGreaterEqual` | 大于等于 | 是 |
+| `isLess` | 小于 | 是 |
+| `isLessEqual` | 小于等于 | 是 |
+
+**各字段类型的 value 格式:**
+
+| 字段类型 | value 类型 | 适用操作符 | 示例 |
+|----------|-----------|-----------|------|
+| 文本 / 电话 / URL | string | is, isNot, contains, doesNotContain, isEmpty, isNotEmpty | `{"field_name":"姓名","operator":"contains","value":"张"}` |
+| 数字 | number | is, isNot, isGreater, isGreaterEqual, isLess, isLessEqual, isEmpty, isNotEmpty | `{"field_name":"金额","operator":"isGreater","value":0}` |
+| 单选 | string(选项名) | is, isNot, isEmpty, isNotEmpty | `{"field_name":"状态","operator":"is","value":"已完成"}` |
+| 多选 | string[](选多个)/ string(选单个) | is, isNot, contains, doesNotContain, isEmpty, isNotEmpty | 多选传数组如 `["标签1","标签2"]`;单选传单个字符串 |
+| 日期时间 / 创建时间 / 修改时间 | number(Unix 毫秒时间戳,13位) | is, isGreater, isGreaterEqual, isLess, isLessEqual, isEmpty, isNotEmpty | `{"field_name":"创建日期","operator":"isGreater","value":1704038400000}` |
+| 复选框 | boolean | is | `{"field_name":"已审核","operator":"is","value":true}` |
+| 人员 / 创建人 / 修改人 | string 或 string[](用户 ID,格式 `ou_xxx`) | is, isNot, isEmpty, isNotEmpty | `{"field_name":"负责人","operator":"is","value":"ou_xxxxxxxxxxxxxxxx"}` |
+| 所有类型(为空/不为空) | 不需要 value | isEmpty, isNotEmpty | `{"field_name":"备注","operator":"isEmpty"}` |
+
+> `value` 类型为 `string | number | boolean | string[]`,需根据字段类型匹配正确格式
+
+## 约束与本地校验
+
+- 必填与互斥
+  - 图表类型必填:`table_name`
+  - text 类型必填:`text`
+  - 互斥:`series` 与 `count_all` 二选一,且至少提供其一(仅图表类型)
+  - text 类型**不支持**:`series`、`count_all`、`group_by`、`filter`
+- 长度/结构
+  - `group_by` 最多 2 个;每项 `field_name` 必填
+  - `group_by[].sort.type` 取值 `group|value|view`;`order` 取值 `asc|desc`
+- 规范化(CLI 自动处理)
+  - `series[].rollup` 自动转成大写(如 `sum` → `SUM`)
+  - `group_by[].sort.type/order` 自动转成小写
+- 本地校验(可通过 `--no-validate` 跳过)
+  - `+dashboard-block-create` 默认对 `data_config` 做轻量校验;失败会聚合错误并给出修复建议
+  - `+dashboard-block-update` 不做强类型校验,由后端验证具体字段
+  - 仅需传入合法 JSON;CLI 不会擅自改写你的业务含义
+
+## 可复制模板
+
+**按意图选择模板:**
+- 比较不同类别数值 → 柱状图 / 条形图
+- 看趋势变化 → 折线图 / 面积图
+- 看占比分布 → 饼图 / 环形图 / 词云
+- 多指标对比 → 组合图
+- 看两变量关系 → 散点图
+- 看流程转化 → 漏斗图
+- 看多维度评分 → 雷达图
+- 显示单个指标 → 指标卡(统计数字或记录数)
+
+最小柱状图:
+
+```json
+{
+  "table_name": "表名",
+  "series": [{ "field_name": "数值字段", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "分组字段", "mode": "integrated" }]
+}
+```
+
+最小饼图/环形图(按分类字段统计行数占比):
+
+```json
+{
+  "table_name": "表名",
+  "count_all": true,
+  "group_by": [{ "field_name": "分类字段", "mode": "integrated" }]
+}
+```
+
+折线图(按月趋势):
+
+```json
+{
+  "table_name": "表名",
+  "series": [{ "field_name": "金额", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "月份", "mode": "integrated", "sort": {"type":"group","order":"asc"} }]
+}
+```
+
+条形图(横向柱状图):
+
+```json
+{
+  "table_name": "表名",
+  "series": [{ "field_name": "数值字段", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "分组字段", "mode": "integrated" }]
+}
+```
+
+面积图(趋势填充):
+
+```json
+{
+  "table_name": "表名",
+  "series": [{ "field_name": "数值字段", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "时间字段", "mode": "integrated", "sort": {"type":"group","order":"asc"} }]
+}
+```
+
+组合图(柱+线等多指标对比):
+
+```json
+{
+  "table_name": "表名",
+  "series": [
+    { "field_name": "指标1", "rollup": "SUM" },
+    { "field_name": "指标2", "rollup": "SUM" }
+  ],
+  "group_by": [{ "field_name": "分类字段", "mode": "integrated" }]
+}
+```
+
+散点图(两变量相关性):
+
+```json
+{
+  "table_name": "表名",
+  "series": [{ "field_name": "Y轴字段(数值/指标)", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "X轴字段(分类/维度)", "mode": "integrated" }]
+}
+```
+
+漏斗图(流程转化):
+
+```json
+{
+  "table_name": "表名",
+  "series": [{ "field_name": "数值字段", "rollup": "SUM" }],
+  "group_by": [{ "field_name": "阶段字段", "mode": "integrated" }]
+}
+```
+
+词云(文本频率):
+
+```json
+{
+  "table_name": "表名",
+  "count_all": true,
+  "group_by": [{ "field_name": "文本字段", "mode": "integrated" }]
+}
+```
+
+雷达图(多维度评分):
+
+```json
+{
+  "table_name": "表名",
+  "series": [
+    { "field_name": "维度1", "rollup": "SUM" },
+    { "field_name": "维度2", "rollup": "SUM" },
+    { "field_name": "维度3", "rollup": "SUM" }
+  ],
+  "group_by": [{ "field_name": "分类字段", "mode": "integrated" }]
+}
+```
+
+指标卡(统计数字):
+
+```json
+{
+  "table_name": "数据表",
+  "series": [{ "field_name": "数字", "rollup": "SUM" }]
+}
+```
+
+指标卡(统计记录数):
+
+```json
+{
+  "table_name": "数据表",
+  "count_all": true
+}
+```
+
+文本组件(Markdown 富文本):
+
+```json
+{
+  "text": "# 🚀 一级标题\n这是一个 **加粗** *斜体* ~~删除线~~ 的示例。\n\n## 📌 二级标题\n1. 有序列表项 1\n2. 有序列表项 2\n\n### 📌 三级标题\n- 无序列表项 1\n- 无序列表项 2"
+}
+```
+
+> **注意**:text 类型组件不需要 `table_name`、`series`、`group_by`、`filter` 等数据源相关字段。
+
+## 常见错误与修复
+
+- 同时存在 `series` 与 `count_all`
+  - 现象:后端/本地校验报互斥错误
+  - 修复:见「关键约束」章节的二选一规则
+- 缺少 `table_name`
+  - 现象:本地校验缺少必填字段
+  - 修复:指定数据源表名(使用表名,非表 ID)
+- `series[].rollup` 大小写/取值不合法
+  - 现象:本地校验提示枚举不支持
+  - 修复:改为 `SUM|MAX|MIN|AVERAGE` 中之一(不区分大小写,CLI 会统一为大写;计数请使用 `count_all:true`)
+- `group_by` 超出 2 个或字段名为空
+  - 修复:保留前 2 个,或补齐 `field_name`
+- 排序枚举不合法
+  - 修复:`group_by.sort.type` 仅能为 `group|value|view`;`order` 为 `asc|desc`
+- filter 写法不规范
+  - 修复:`conjunction` 取 `and|or`;`conditions[].operator` 必须在本页表格列举的范围内;除 `isEmpty/isNotEmpty` 外需提供 `value`
+
+## 坑点
+
+- **`count_all` 与 `series` 二选一** — 两者不能同时使用
+- **filter `value` 类型因字段而异** — 文本/单选为 string,数字为 number,日期为毫秒时间戳,多选/人员可为 string[],复选框为 boolean;`isEmpty`/`isNotEmpty` 不需要 value
+- **`data_config` 结构随 `type` 变化** — 不同组件类型的字段不同,创建前务必确认类型对应的字段
+- **表名用 name,不是 ID** — `table_name` 对应的是表名称(如「订单表」),不是 `table_id`

+ 130 - 0
.agents/skills/lark-base/references/examples.md

@@ -0,0 +1,130 @@
+# 飞书多维表格使用场景完整示例(base)
+
+本文档提供基于 `lark-cli base ...` 的完整示例,覆盖 unified Shortcut 与当前 `base/v3` 原生 API 的常见组合方式。
+
+> **返回**: [SKILL.md](../SKILL.md) | **参考**: [shortcut 字段 JSON 规范](lark-base-shortcut-field-properties.md) · [shortcut 记录值规范](lark-base-shortcut-record-value.md)
+
+---
+
+## 场景 1:用 unified Shortcut 快速建表
+
+适合已经明确字段结构、希望一次性完成建表的场景。
+
+```bash
+lark-cli base +table-create \
+  --base-token bascnXXXXXXXX \
+  --name "客户管理表" \
+  --fields '[
+    {"name":"客户名称","type":"text"},
+    {"name":"负责人","type":"user","property":{"multiple":false}},
+    {"name":"签约日期","type":"datetime"},
+    {"name":"状态","type":"single_select","property":{"options":["进行中","已完成"]}}
+  ]'
+```
+
+---
+
+## 场景 2:使用原生 API 创建数据表并查看字段
+
+适合需要精确观察 `base/v3` 请求参数和响应结构的场景。原生 API 直接使用 `base` service。
+
+### 步骤 1:在已有 Base 中创建数据表
+
+```bash
+lark-cli base tables create \
+  --params '{"base_token":"bascnXXXXXXXX"}' \
+  --data '{"name":"客户管理表"}'
+```
+
+### 步骤 2:列出字段
+
+```bash
+lark-cli base table.fields list \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX","limit":100}'
+```
+
+> 提示:当前 `base/v3` 不再使用旧的 `app_token` / `app.table.*` 路径,统一改为 `base_token` + `tables` / `table.fields` / `table.records`。
+
+---
+
+## 场景 3:创建、读取、更新单条记录
+
+### 新增记录
+
+```bash
+lark-cli base table.records create \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX"}' \
+  --data '{
+    "客户名称":"字节跳动",
+    "负责人":[{"id":"ou_xxx"}],
+    "状态":"进行中"
+  }'
+```
+
+### 列出记录
+
+```bash
+lark-cli base table.records list \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX","limit":100}'
+```
+
+### 更新记录
+
+```bash
+lark-cli base table.records patch \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX","record_id":"recXXXXXXXX"}' \
+  --data '{
+    "状态":"已完成"
+  }'
+```
+
+### 删除记录
+
+```bash
+lark-cli base table.records delete \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX","record_id":"recXXXXXXXX"}'
+```
+
+---
+
+## 场景 4:配置视图筛选后按视图读取记录
+
+当前 `base/v3` 原生 spec 没有独立 `search` 方法。需要筛选查询时,推荐先写视图筛选,再通过 `view_id` 读取记录。
+
+### 更新视图筛选条件
+
+```bash
+lark-cli base view.filter update \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX","view_id":"vewXXXXXXXX"}' \
+  --data '{
+    "logic":"and",
+    "conditions":[
+      {
+        "field_name":"状态",
+        "operator":"is",
+        "value":["进行中"]
+      }
+    ]
+  }'
+```
+
+### 按视图读取记录
+
+```bash
+lark-cli base table.records list \
+  --params '{"base_token":"bascnXXXXXXXX","table_id":"tblXXXXXXXX","view_id":"vewXXXXXXXX","limit":100}'
+```
+
+---
+
+## 场景 5:什么时候优先用 Shortcut
+
+- 需要一次性建表并附带字段、视图时,优先 `lark-cli base +table-create`
+- 需要按业务字段名做 upsert 时,优先 `lark-cli base +record-upsert`
+- 需要配置筛选视图时,优先 `lark-cli base +view-set-filter`
+- 需要记录历史时,优先 `lark-cli base +record-history-list`
+
+原生 API 更适合两类场景:
+
+- 需要逐步核对 `schema base.<resource>.<method>` 的请求参数
+- 需要精确控制单次表 / 字段 / 记录 / 视图操作

+ 735 - 0
.agents/skills/lark-base/references/formula-field-guide.md

@@ -0,0 +1,735 @@
+# Base Formula Writing Guide
+
+## Mandatory Read Acknowledgement
+
+When creating or updating a formula field with `lark-cli base +field-create/+field-update --json ...` and `type` is `formula`, you should read this guide first and only then add `--i-have-read-guide` to the command.
+
+Do **not** proactively add `--i-have-read-guide` before reading this guide. Without it, the CLI will fail fast and direct you back to this guide.
+
+## Default strategy
+
+**All cross-table references, aggregations, and computed fields should use Formula fields by default.** Do NOT use Lookup fields unless the user explicitly requests it. Formula is a strict superset of Lookup — anything Lookup can do, Formula can do with a single expression.
+
+## Usage
+
+When creating a formula field, the Agent should:
+
+1. Get all table names: `lark-cli base +table-list --base-token <base>` — returns `items[].table_name`
+2. Get table structure: `lark-cli base +table-get --base-token <base> --table-id <table>` — returns `fields[]`
+3. If the formula references other tables, also get those tables' structures
+4. Write the formula expression following this guide
+5. Construct the Formula field JSON and submit it to create or update the field
+
+**Key constraints**:
+
+- The JSON must include `"type": "formula"` — this field is required
+- Table names and field names in the formula must **exactly match** those returned by `+table-list` / `+table-get`
+- The `expression` value is a string containing the formula expression; double quotes inside the expression must be properly escaped in JSON (e.g. `\"text\"`)
+
+---
+
+## Section 1: Core Concepts — Scalar vs List
+
+This is the foundation of formula logic. You must determine this before writing any formula.
+
+| Syntax                | Meaning                                      | Return type            | Example                                      |
+| --------------------- | -------------------------------------------- | ---------------------- | -------------------------------------------- |
+| `[Field]`             | Value of this field in the current row       | Scalar (single value)  | `[Name]` → `"Alice"`                         |
+| `[TableName].[Field]` | All values of this field in the target table | List (multiple values) | `[Employees].[Name]` → `["Alice","Bob",...]` |
+| `[TableName]`         | The target table (entire table)              | Table reference        | Used as data range for FILTER/COUNTIF etc.   |
+
+**Rules**:
+
+- Scalars can be used directly in operations: `[Price] * [Quantity]`
+- Lists cannot be used as scalars — they must be processed first: use `SUM()` for sum, `ARRAYJOIN(",")` for joining, `FIRST()`/`LAST()`/`NTH()` for single value extraction
+- Link field access `[LinkField].[TargetField]` returns a list (values of the target field for all linked records)
+- **LISTCOMBINE flattening rule**: When a FILTER's result column is itself a multi-value field (MultiSelect, Link, etc.), it produces a 2D array and **must** be flattened with `.LISTCOMBINE()`; for single-value fields (Number, Text, etc.) it can be omitted, but adding it is never wrong:
+
+  ```
+  [Table].FILTER(CurrentValue.[Field] = [Value]).[MultiSelectCol].LISTCOMBINE()    ← required for multi-value columns
+  [Table].FILTER(CurrentValue.[Field] = [Value]).[NumberCol].LISTCOMBINE()          ← optional for single-value columns
+  ```
+
+---
+
+## Section 2: Data Types and Type Conversion
+
+### Field storage types
+
+| Type        | Description                  | Supported operations                                                                                                                              |
+| ----------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| Number      | Stored as numeric value      | Math operations, comparisons, auto-converts to string for concatenation                                                                           |
+| Text        | Stored as string             | String operations; can participate in math if content is numeric, otherwise errors                                                                |
+| Date        | Date object                  | Date functions, add/subtract with numbers; auto-converts to default format string when using `&` — use TEXT to format first for controlled output |
+| MultiSelect | Data list                    | List functions, CONTAIN checks                                                                                                                    |
+| Link        | Links to other table records | Chained access `[LinkField].[Field]`, result is a list                                                                                            |
+| Boolean     | TRUE/FALSE                   | Logical operations; auto-converts to number when compared with numbers                                                                            |
+
+### Implicit type conversion
+
+| Scenario                     | Conversion rule                                                                                             |
+| ---------------------------- | ----------------------------------------------------------------------------------------------------------- |
+| Number + Float               | → Float                                                                                                     |
+| Date + Number                | → Date (adds/subtracts days). Use `+`/`-` for whole days, use `DURATION()` for hour/minute/second precision |
+| Date - Date                  | → Duration                                                                                                  |
+| Boolean compared with Number | Boolean auto-converts to number (TRUE=1, FALSE=0)                                                           |
+| `&` concatenation            | Both sides auto-convert to string                                                                           |
+
+### Type consistency in comparisons
+
+When using comparison operators (`>`, `>=`, `<`, `<=`, `=`, `!=`), **both sides should be the same type** to avoid semantic errors or unexpected results.
+
+**Principle**: When types differ, explicitly convert one side rather than relying on implicit conversion:
+
+- Number vs Text → use `VALUE()` to convert text to number
+- Date vs Text → use `TEXT()` to convert date to text
+- Date vs Date equality → Dates include time components, so direct `=` comparison may fail due to different hours/minutes/seconds. For day-level equality, convert to text first: `TEXT([DateA], "YYYY/MM/DD") = TEXT([DateB], "YYYY/MM/DD")`
+- Select and User fields can be compared with both same-type values and text
+- Text fields in numeric aggregation (SUM/AVERAGE/MIN/MAX etc.) → convert to number with `VALUE()` first. For FILTER results, use `.MAP(VALUE(CurrentValue)).SUM()`
+
+---
+
+## Section 3: CurrentValue
+
+**CurrentValue is the iteration variable in FILTER/MAP/COUNTIF/SUMIF functions, representing the "current item" being processed in the data range.**
+
+### CurrentValue meaning in different contexts
+
+| Data range type              | CurrentValue represents | Access pattern              | Example                                                   |
+| ---------------------------- | ----------------------- | --------------------------- | --------------------------------------------------------- |
+| Entire table `[TableName]`   | A row in the table      | `CurrentValue.[FieldName]`  | `[Orders].FILTER(CurrentValue.[Amount] > 100).[Customer]` |
+| Column `[TableName].[Field]` | A single field value    | Use `CurrentValue` directly | `[Orders].[Amount].FILTER(CurrentValue > 100)`            |
+| MultiSelect field `[Tags]`   | One option              | Use `CurrentValue` directly | `[Tags].FILTER(CurrentValue = "Important")`               |
+| LIST-generated list          | One element             | Use `CurrentValue` directly | `LIST(1,2,3).MAP(CurrentValue * 2)`                       |
+
+### Key rules
+
+1. **When data range is a table**, use `CurrentValue.[FieldName]` to access row fields
+2. **When data range is a column/list**, use `CurrentValue` directly for the element value — **cannot** use `CurrentValue.[FieldName]`
+3. CurrentValue can **only** appear inside the condition/mapping parameters of FILTER/MAP/COUNTIF/SUMIF functions
+4. To reference the current table's field value in a condition, write `[FieldName]` directly — it refers to the formula row's value, not a property of CurrentValue
+
+### Anti-patterns
+
+| Wrong                                          | Reason                                                                            | Correct                                                |
+| ---------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------ |
+| `[Table].[Col].FILTER(CurrentValue.[Col] > 0)` | Data range is a column; CurrentValue is a scalar, cannot use `.` to access fields | `[Table].[Col].FILTER(CurrentValue > 0)`               |
+| `[Table].FILTER(CurrentValue > 100)`           | Data range is a table; CurrentValue is a row, cannot compare directly             | `[Table].FILTER(CurrentValue.[Amount] > 100).[Amount]` |
+| `CurrentValue + 1` (at top level)              | CurrentValue can only be used inside iteration functions                          | Use inside MAP/FILTER etc.                             |
+
+---
+
+## Section 4: Operators
+
+Base formulas **only allow** the following operators. `like`, `in`, `<>`, `**`, `^` etc. are prohibited.
+
+| Category      | Operators                  | Description                                                                |
+| ------------- | -------------------------- | -------------------------------------------------------------------------- |
+| Arithmetic    | `+` `-` `*` `/` `%`        | Add, subtract, multiply, divide, modulo (`%` is equivalent to `MOD()`)     |
+| Comparison    | `>` `>=` `<` `<=` `=` `!=` | Greater than, greater or equal, less than, less or equal, equal, not equal |
+| Logical       | `&&` `\|\|`                | AND, OR                                                                    |
+| Concatenation | `&`                        | Text concatenation; non-text values auto-convert to string                 |
+
+**Important**:
+
+- Equality uses `=` (single equals), not `==`
+- Not-equal uses `!=`, not `<>`
+- String concatenation uses `&`, not `+`
+- Both `&&`/`||` and AND()/OR() functions are supported
+
+---
+
+## Section 5: Link Fields and Cross-Table References
+
+### Link field description
+
+When a field type is described as `FieldName: Link [target table: X, foreign key: Y]`, it links to target table X using field Y as the join key.
+
+### Chained cross-table access
+
+```
+[LinkField].[TargetField]
+```
+
+Retrieves the target field values for all linked records as a list. Supports continued chaining: `[LinkA].[LinkB].[Field]`.
+
+### Equivalent expanded form
+
+- Multi-value link: `[TargetTableX].FILTER([LinkField].CONTAIN(CurrentValue.[Y])).[TargetField].LISTCOMBINE()`
+- Single-value link: `[TargetTableX].FILTER(CurrentValue.[Y] = [LinkField]).[TargetField].LISTCOMBINE()`
+
+(`.LISTCOMBINE()` is required when `[TargetField]` is a multi-value field; optional for single-value fields)
+
+### Notes
+
+- Link fields typically return **lists** (possibly empty)
+- To output a single value, use aggregation (SUM/MAX), joining (ARRAYJOIN), or extraction (FIRST/LAST/NTH)
+- Do not nest FILTER inside FILTER for cross-table queries — prefer link field chained access
+
+---
+
+## Section 6: Function Call Conventions
+
+### Two calling styles
+
+| Style      | Format             | Description                         |
+| ---------- | ------------------ | ----------------------------------- |
+| Functional | `FUNC(arg1, arg2)` | Works for all functions             |
+| Chained    | `arg1.FUNC(arg2)`  | Moves the first argument before `.` |
+
+**Rules**:
+
+- Zero-argument functions cannot be chained: `NOW()`, `TODAY()`, `PI()`, `TRUE()`, `FALSE()`
+- SORTBY can **only** be chained: `[Table].SORTBY([Table].[SortCol]).[OutputCol]`. The sort column always uses the original table's column name (`[TableName].[Field]` format); the engine aligns rows internally, even when the data range is a FILTER result
+- FILTER is recommended to be chained: `[Table].FILTER(condition).[OutputCol]`
+
+### FILTER / SORTBY result column rules
+
+- **When data range is a table** `[TableName]`, FILTER / SORTBY returns a table reference. The chain **must** end with `.[Field]` to specify the result column, otherwise the formula fails:
+
+  ```
+  Correct: [Sales].FILTER(CurrentValue.[Amount] > 100).[Customer]
+  Correct: [Sales].FILTER(condition).SORTBY([Sales].[SortCol]).[Customer]  ← result column at end of chain
+  Wrong:   [Sales].FILTER(CurrentValue.[Amount] > 100)                     ← missing result column
+  ```
+
+- **When data range is a column** `[TableName].[Field]` or a list, FILTER returns the filtered list directly — **no** result column needed:
+
+  ```
+  Correct: [Sales].[Amount].FILTER(CurrentValue > 100)
+  ```
+
+After the result column, it's recommended to flatten with `.LISTCOMBINE()` first (especially when the result column is a multi-value field), then chain aggregation functions:
+
+```
+[Sales].FILTER(CurrentValue.[Amount] > 100).[Amount].LISTCOMBINE().SUM()
+```
+
+---
+
+## Section 7: Hard Constraints
+
+1. **Nesting prohibition**: FILTER / SUMIF / COUNTIF / MAP **must not be nested** inside each other's condition/mapping expressions. None of these functions can appear inside the condition or mapping parameter of another.
+   - Prohibited: `[Table1].FILTER(CurrentValue.[Col] = [Table2].FILTER(...).[Col])` ← FILTER inside FILTER condition
+   - Prohibited: `[Table].MAP([Table2].MAP(...))` ← MAP inside MAP mapping
+   - **Allowed**: `[Table].FILTER(cond1).[Col].FILTER(cond2)` ← chained call; the first FILTER's output is the second's data range, not nesting
+
+2. **Function whitelist**: Only use functions listed in Section 8. No unlisted functions.
+
+3. **Exact name matching**: Table names and field names in formulas must **exactly match** those returned by `+table-get` — no renaming or adding spaces.
+
+4. **Operator whitelist**: Only use operators listed in Section 4.
+
+5. **Strings use double quotes**: Strings must be wrapped in double quotes `"`, single quotes are not supported.
+
+6. **Do not use LOOKUP**: FILTER is a superset of LOOKUP. All LOOKUP formulas can be rewritten with FILTER. Use FILTER exclusively to reduce complexity.
+
+---
+
+## Section 8: Complete Function Reference
+
+### 8.1 Logic functions
+
+| Function      | Signature                                                          | Return type          | Description                                                                                  |
+| ------------- | ------------------------------------------------------------------ | -------------------- | -------------------------------------------------------------------------------------------- |
+| IF            | `IF(condition, true_val, [false_val])`                             | Matches branch type  | Returns true_val when TRUE, false_val otherwise; omitting false_val returns false (not null) |
+| IFS           | `IFS(cond1, val1, cond2, val2, ...)`                               | Matches branch type  | Multi-condition branching; returns value for the first TRUE condition                        |
+| SWITCH        | `SWITCH(expr, match1, result1, [match2, result2, ...], [default])` | Matches branch type  | Matches expression value and returns corresponding result                                    |
+| IFERROR       | `IFERROR(expr, fallback)`                                          | Matches branch type  | Returns fallback when expression errors                                                      |
+| IFBLANK       | `IFBLANK(expr, fallback)`                                          | Matches branch type  | Returns fallback when expression is blank (blank = NULL/empty string/empty list)             |
+| AND           | `AND(cond1, cond2, ...)`                                           | Boolean              | TRUE when all conditions are TRUE                                                            |
+| OR            | `OR(cond1, cond2, ...)`                                            | Boolean              | TRUE when any condition is TRUE                                                              |
+| NOT           | `NOT(condition)`                                                   | Boolean              | Logical negation                                                                             |
+| ISBLANK       | `ISBLANK(value)`                                                   | Boolean              | Tests if blank (NULL/empty string/empty list are blank; 0 and FALSE are not)                 |
+| ISNULL        | `ISNULL(value)`                                                    | Boolean              | Tests if NULL (only NULL is true; empty string is not)                                       |
+| ISERROR       | `ISERROR(expr)`                                                    | Boolean              | Tests if expression errors                                                                   |
+| ISNUMBER      | `ISNUMBER(value)`                                                  | Boolean              | Tests if value is a number                                                                   |
+| CONTAIN       | `CONTAIN(search_range, value, ...)`                                | Boolean              | Tests if list/MultiSelect contains the value; **does NOT do text substring matching**        |
+| CONTAINSALL   | `CONTAINSALL(search_range, value, ...)`                            | Boolean              | Tests if list/MultiSelect contains all specified values                                      |
+| CONTAINSONLY  | `CONTAINSONLY(search_range, value, ...)`                           | Boolean              | Tests if list/MultiSelect contains only the specified values                                 |
+| TRUE          | `TRUE()`                                                           | Boolean              | Returns TRUE                                                                                 |
+| FALSE         | `FALSE()`                                                          | Boolean              | Returns FALSE                                                                                |
+| RECORD_ID     | `RECORD_ID()`                                                      | Text                 | Returns the current row's record ID                                                          |
+| RANDOMBETWEEN | `RANDOMBETWEEN(min_int, max_int, [keep_updating])`                 | Number               | Random integer in the specified range                                                        |
+| RANDOMITEM    | `RANDOMITEM(list, [keep_updating])`                                | Matches element type | Randomly picks one element from a list                                                       |
+
+### 8.2 Numeric functions
+
+| Function                                                          | Signature                                | Return type | Description                                                                                                                                                                                                                                                |
+| ----------------------------------------------------------------- | ---------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| SUM                                                               | `SUM(val1, val2, ...)`                   | Number      | Sum; accepts multiple values or a list                                                                                                                                                                                                                     |
+| AVERAGE                                                           | `AVERAGE(val1, val2, ...)`               | Number      | Average                                                                                                                                                                                                                                                    |
+| MAX                                                               | `MAX(val1, val2, ...)`                   | Number      | Maximum                                                                                                                                                                                                                                                    |
+| MIN                                                               | `MIN(val1, val2, ...)`                   | Number      | Minimum                                                                                                                                                                                                                                                    |
+| MEDIAN                                                            | `MEDIAN(val1, val2, ...)`                | Number      | Median                                                                                                                                                                                                                                                     |
+| COUNTA                                                            | `COUNTA(val1, val2, ...)`                | Number      | Count of non-blank values                                                                                                                                                                                                                                  |
+| COUNTIF                                                           | `COUNTIF(data_range, condition)`         | Number      | Count matching items. Data range can be a **table** (CurrentValue is a row, use `CurrentValue.[Field]`) or a **column** (CurrentValue is a scalar value)                                                                                                   |
+| SUMIF                                                             | `SUMIF(data_range, condition)`           | Number      | Sum matching values. Data range **must be a numeric column** (e.g. `[Table].[NumField]`); CurrentValue is each value in that column (scalar), cannot use `CurrentValue.[Field]` to access other fields. For cross-field conditions, use FILTER+SUM instead |
+| ROUND                                                             | `ROUND(number, digits)`                  | Number      | Round. digits: 1=one decimal, 0=integer, -1=tens place                                                                                                                                                                                                     |
+| ROUNDUP                                                           | `ROUNDUP(number, digits)`                | Number      | Round away from zero. Same digits semantics as ROUND                                                                                                                                                                                                       |
+| ROUNDDOWN                                                         | `ROUNDDOWN(number, digits)`              | Number      | Round toward zero. Same digits semantics as ROUND                                                                                                                                                                                                          |
+| FLOOR                                                             | `FLOOR(number, [base])`                  | Number      | Round down to nearest multiple of base (default 1)                                                                                                                                                                                                         |
+| CEILING                                                           | `CEILING(number, [base])`                | Number      | Round up to nearest multiple of base (default 1)                                                                                                                                                                                                           |
+| ABS                                                               | `ABS(number)`                            | Number      | Absolute value                                                                                                                                                                                                                                             |
+| INT                                                               | `INT(number)`                            | Integer     | Truncate to integer                                                                                                                                                                                                                                        |
+| MOD                                                               | `MOD(dividend, divisor)`                 | Number      | Modulo                                                                                                                                                                                                                                                     |
+| POWER                                                             | `POWER(base, exponent)`                  | Number      | Exponentiation                                                                                                                                                                                                                                             |
+| QUOTIENT                                                          | `QUOTIENT(dividend, divisor)`            | Number      | Integer division                                                                                                                                                                                                                                           |
+| VALUE                                                             | `VALUE(text)`                            | Number      | Convert text to number                                                                                                                                                                                                                                     |
+| ISODD                                                             | `ISODD(number)`                          | Boolean     | Tests if number is odd                                                                                                                                                                                                                                     |
+| RANK                                                              | `RANK(value, search_range, [ascending])` | Number      | Rank of value in range; default descending                                                                                                                                                                                                                 |
+| SEQUENCE                                                          | `SEQUENCE(start, end, [step])`           | List        | Generate number sequence                                                                                                                                                                                                                                   |
+| PI                                                                | `PI()`                                   | Number      | Pi constant                                                                                                                                                                                                                                                |
+| SIN/COS/TAN/ASIN/ACOS/ATAN/ATAN2/SINH/COSH/TANH/ASINH/ACOSH/ATANH | `func(radians_or_value)`                 | Number      | Trigonometric and hyperbolic functions; arguments in radians                                                                                                                                                                                               |
+
+### 8.3 Text functions
+
+| Function        | Signature                                            | Return type | Description                                                                                              |
+| --------------- | ---------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------- |
+| CONCATENATE     | `CONCATENATE(text1, text2, ...)`                     | Text        | Concatenate multiple texts; supports lists as input                                                      |
+| LEN             | `LEN(text)`                                          | Number      | Character count                                                                                          |
+| LEFT            | `LEFT(text, [count])`                                | Text        | Extract from left; default 1                                                                             |
+| RIGHT           | `RIGHT(text, [count])`                               | Text        | Extract from right; default 1                                                                            |
+| MID             | `MID(text, start, count)`                            | Text        | Extract from middle                                                                                      |
+| FIND            | `FIND(search_val, search_range, [start])`            | Number      | Find substring position (case-sensitive); returns -1 if not found                                        |
+| REPLACE         | `REPLACE(text, start, count, new_text)`              | Text        | Replace by position                                                                                      |
+| SUBSTITUTE      | `SUBSTITUTE(text, old_text, new_text, [occurrence])` | Text        | Replace by content; can specify which occurrence                                                         |
+| UPPER           | `UPPER(text)`                                        | Text        | Convert to uppercase                                                                                     |
+| LOWER           | `LOWER(text)`                                        | Text        | Convert to lowercase                                                                                     |
+| TRIM            | `TRIM(text)`                                         | Text        | Remove leading/trailing spaces                                                                           |
+| TEXT            | `TEXT(value, format)`                                | Text        | Format output. Date formats: `"YYYY-MM-DD"`, `"YYYY/MM/DD hh:mm:ss"`; number formats: `"00"`, `"000.00"` |
+| CONTAINTEXT     | `CONTAINTEXT(text, search_text)`                     | Boolean     | Tests if text contains substring (text substring matching)                                               |
+| SPLIT           | `SPLIT(text, delimiter)`                             | List        | Split text by delimiter                                                                                  |
+| TODATE          | `TODATE(value)`                                      | Date        | Convert date string to date type                                                                         |
+| CHAR            | `CHAR(number)`                                       | Text        | ASCII code to character                                                                                  |
+| FORMAT          | `FORMAT(template, [val1, val2, ...])`                | Text        | Template string formatting; use `{1}`, `{2}` as placeholders                                             |
+| HYPERLINK       | `HYPERLINK(url, [display_text])`                     | Hyperlink   | Create a hyperlink                                                                                       |
+| ENCODEURL       | `ENCODEURL(text)`                                    | Text        | URL encode                                                                                               |
+| REGEXMATCH      | `REGEXMATCH(text, regex)`                            | Boolean     | Regex match test                                                                                         |
+| REGEXEXTRACT    | `REGEXEXTRACT(text, regex)`                          | List        | Extract first match's capture groups                                                                     |
+| REGEXEXTRACTALL | `REGEXEXTRACTALL(text, regex)`                       | 2D List     | Extract all matches                                                                                      |
+| REGEXREPLACE    | `REGEXREPLACE(text, regex, replacement)`             | Text        | Regex replace                                                                                            |
+
+### 8.4 Date functions
+
+| Function    | Signature                                       | Return type | Description                                                                                             |
+| ----------- | ----------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------- |
+| NOW         | `NOW()`                                         | Date        | Current date and time                                                                                   |
+| TODAY       | `TODAY()`                                       | Date        | Current date (midnight)                                                                                 |
+| DATE        | `DATE(year, month, day)`                        | Date        | Construct a date                                                                                        |
+| YEAR        | `YEAR(date)`                                    | Number      | Extract year                                                                                            |
+| MONTH       | `MONTH(date)`                                   | Number      | Extract month                                                                                           |
+| DAY         | `DAY(date)`                                     | Number      | Extract day                                                                                             |
+| HOUR        | `HOUR(date)`                                    | Number      | Extract hour                                                                                            |
+| MINUTE      | `MINUTE(date)`                                  | Number      | Extract minute                                                                                          |
+| SECOND      | `SECOND(date)`                                  | Number      | Extract second                                                                                          |
+| WEEKDAY     | `WEEKDAY(date, [type])`                         | Number      | Day of week                                                                                             |
+| WEEKNUM     | `WEEKNUM(date, [type])`                         | Number      | Week number                                                                                             |
+| DAYS        | `DAYS(end_date, start_date)`                    | Number      | Days between two dates (end - start), includes decimals. **Note parameter order: end date comes first** |
+| DATEDIF     | `DATEDIF(start_date, end_date, [unit])`         | Number      | Whole days/months/years between dates. Unit: `"D"`(default)/`"M"`/`"Y"`. **Start must be before end**   |
+| DURATION    | `DURATION(days, [hours], [minutes], [seconds])` | Duration    | Create a duration for date arithmetic                                                                   |
+| EDATE       | `EDATE(date, months)`                           | Date        | Date N months later                                                                                     |
+| EOMONTH     | `EOMONTH(date, [months])`                       | Date        | End of month N months later; months default 0                                                           |
+| WORKDAY     | `WORKDAY(start_date, days, [holidays])`         | Date        | Date N workdays later (skips weekends and holidays)                                                     |
+| NETWORKDAYS | `NETWORKDAYS(start_date, end_date, [holidays])` | Number      | Workdays between dates (inclusive)                                                                      |
+
+### 8.5 List functions
+
+| Function    | Signature                                                                    | Return type | Description                                                                                                                                                                                                      |
+| ----------- | ---------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| LIST        | `LIST(val1, val2, ...)`                                                      | List        | Create a list                                                                                                                                                                                                    |
+| FIRST       | `FIRST(list)`                                                                | Scalar      | First element                                                                                                                                                                                                    |
+| LAST        | `LAST(list)`                                                                 | Scalar      | Last element                                                                                                                                                                                                     |
+| NTH         | `NTH(list, index)`                                                           | Scalar      | Nth element (1-based)                                                                                                                                                                                            |
+| FILTER      | `[Table].FILTER(condition).[ResultCol]` or `[Table].[Col].FILTER(condition)` | List        | Filter by condition. When data range is a table, result column is **required**; when it's a column/list, it's not needed. Use CurrentValue in conditions. Add `.LISTCOMBINE()` when result column is multi-value |
+| MAP         | `data_range.MAP(mapping_expr)`                                               | List        | Apply mapping to each element. Use CurrentValue in mapping                                                                                                                                                       |
+| SORT        | `SORT(list, [ascending])`                                                    | List        | Sort; default ascending (TRUE)                                                                                                                                                                                   |
+| SORTBY      | `[Table].SORTBY([Table].[SortCol], [ascending]).[OutputCol]`                 | List        | Sort by column then extract output column. **Chain-only, must include output column**                                                                                                                            |
+| UNIQUE      | `UNIQUE(list)`                                                               | List        | Deduplicate                                                                                                                                                                                                      |
+| ARRAYJOIN   | `ARRAYJOIN(list, [delimiter])`                                               | Text        | Join list elements as text; default comma-separated                                                                                                                                                              |
+| LISTCOMBINE | `LISTCOMBINE(val1, [val2, ...])` or `list.LISTCOMBINE()`                     | List        | Two uses: (1) merge values/lists into one list; (2) chained call to flatten 2D array (commonly used when FILTER result column is a multi-value field)                                                            |
+| DISTANCE    | `DISTANCE(location1, location2)`                                             | Number      | Distance between two geographic locations (km)                                                                                                                                                                   |
+
+---
+
+## Section 9: Commonly Confused Functions
+
+### CONTAIN vs CONTAINTEXT
+
+|             | CONTAIN                                                        | CONTAINTEXT                                                |
+| ----------- | -------------------------------------------------------------- | ---------------------------------------------------------- |
+| Purpose     | Tests if **list/MultiSelect** contains a value                 | Tests if **text** contains a substring                     |
+| Example     | `[Tags].CONTAIN("Urgent")`                                     | `[Notes].CONTAINTEXT("completed")`                         |
+| Wrong usage | `CONTAIN([Notes], "completed")` — cannot do substring matching | `CONTAINTEXT([Tags], "Urgent")` — Tags is a list, not text |
+
+### ISBLANK vs ISNULL
+
+|                   | ISBLANK | ISNULL |
+| ----------------- | ------- | ------ |
+| NULL              | TRUE    | TRUE   |
+| `""` empty string | TRUE    | FALSE  |
+| Empty list `[]`   | TRUE    | FALSE  |
+| `0`               | FALSE   | FALSE  |
+| `FALSE`           | FALSE   | FALSE  |
+
+### DAYS vs DATEDIF
+
+|                 | DAYS                                                         | DATEDIF                                   |
+| --------------- | ------------------------------------------------------------ | ----------------------------------------- |
+| Parameter order | `DAYS(end, start)` — end first                               | `DATEDIF(start, end, unit)` — start first |
+| Precision       | Includes decimals (hours/minutes/seconds as fractional days) | Integer only (whole days/months/years)    |
+| Negative values | Returns negative when start is after end                     | **Errors** when start is after end        |
+
+### SUM vs SUMIF
+
+|           | SUM                                            | SUMIF                                                          |
+| --------- | ---------------------------------------------- | -------------------------------------------------------------- |
+| Purpose   | Sum all values                                 | Sum values **matching a condition**                            |
+| Arguments | `SUM(val1, val2, ...)` or `SUM([Table].[Col])` | `SUMIF(data_range, condition)` with CurrentValue in condition  |
+| Example   | `SUM([Orders].[Amount])` — sum all             | `SUMIF([Orders].[Amount], CurrentValue > 100)` — sum only >100 |
+
+### FILTER+aggregation vs COUNTIF/SUMIF
+
+|             | FILTER+aggregation                                    | COUNTIF/SUMIF                                                                  |
+| ----------- | ----------------------------------------------------- | ------------------------------------------------------------------------------ |
+| Nature      | Filter then aggregate (two steps)                     | One-step (syntactic sugar)                                                     |
+| Equivalence | `[Table].FILTER(cond).[Col].LISTCOMBINE().SUM()`      | `SUMIF([Table].[Col], cond)` (only when condition involves only column values) |
+| When to use | Conditions span multiple fields, or multi-step needed | Conditions only involve column values (e.g. `CurrentValue > 100`)              |
+
+---
+
+## Section 10: Decision Trees
+
+### Cross-table queries: which approach?
+
+```
+Need data from another table?
+├─ Current table has a link field to the target table?
+│   ├─ Yes → Use chained access: [LinkField].[TargetField]
+│   │         Need aggregation? → .SUM() / .ARRAYJOIN(",") / .FIRST()
+│   └─ No → Need to match by field value?
+│       ├─ Field matching or complex filtering → [TargetTable].FILTER(CurrentValue.[MatchField] = [Value]).[OutputCol]
+│       └─ Only counting or summing → COUNTIF([TargetTable], condition) / FILTER+SUM
+```
+
+### Conditional logic: IF vs IFS vs SWITCH?
+
+```
+Need conditional logic?
+├─ Single condition → IF(condition, true_val, false_val)
+├─ Multiple mutually exclusive conditions (if-elseif-else) → IFS(cond1, val1, cond2, val2, ...)
+├─ Matching a value against fixed options → SWITCH(expr, option1, result1, option2, result2, ..., default)
+└─ Need error handling?
+    ├─ Catch errors → IFERROR(expr, fallback)
+    └─ Catch blanks → IFBLANK(expr, fallback)
+```
+
+### Aggregation: which function?
+
+```
+Need to aggregate data?
+├─ Sum/average/max/min for entire column → SUM/AVERAGE/MAX/MIN([Table].[Col])
+├─ Count non-blank → COUNTA([Table].[Col])
+├─ Conditional count → COUNTIF([Table], CurrentValue.[Field] = [Value])
+├─ Conditional sum (column-only condition) → SUMIF([Table].[Col], CurrentValue > threshold)
+├─ Conditional sum (cross-field condition) → [Table].FILTER(CurrentValue.[Field]=value).[NumCol].LISTCOMBINE().SUM()
+├─ Count unique → [Table].[Col].UNIQUE().COUNTA()
+└─ Ranking → RANK([Value], [Table].[Col])
+```
+
+---
+
+## Section 11: Common Formula Patterns
+
+### Pattern 1: Cross-table conditional count
+
+Count rows in target table matching a condition:
+
+```
+[TargetTable].COUNTIF(CurrentValue.[MatchField] = [CurrentTableField])
+```
+
+### Pattern 2: Cross-table conditional sum
+
+Filter target table by current row's value, then sum:
+
+```
+[TargetTable].FILTER(CurrentValue.[MatchField] = [CurrentTableField]).[NumCol].LISTCOMBINE().SUM()
+```
+
+SUMIF works when data range is a column and conditions only involve column values:
+
+```
+SUMIF([TargetTable].[NumCol], CurrentValue > 100)
+```
+
+Note: COUNTIF can use a table as data range (only counting, no specific column needed), but SUMIF's data range **must be a numeric column** (needs values to sum), so `CurrentValue` is each value in that column (scalar) — cannot use `CurrentValue.[OtherField]` to access other fields. For cross-field conditions, use FILTER with a table as data range.
+
+### Pattern 3: Cross-table lookup
+
+```
+[TargetTable].FILTER(CurrentValue.[MatchCol] = [CurrentTableField]).[ReturnCol]
+```
+
+### Pattern 4: Link field values + aggregation
+
+```
+SUM([LinkField].[NumField])
+[LinkField].[TextField].UNIQUE().ARRAYJOIN(",")
+```
+
+### Pattern 5: Conditional text concatenation
+
+```
+IF([Condition], "prefix" & [Field] & "suffix", "default text")
+```
+
+### Pattern 6: Date difference
+
+```
+DATEDIF([StartDate], [EndDate], "D") & " days"
+DAYS([EndDate], [StartDate])
+```
+
+### Pattern 7: List element mapping
+
+```
+[MultiSelectField].MAP(CurrentValue & " tag")
+SPLIT([TextField], ",").MAP(TRIM(CurrentValue))
+```
+
+### Pattern 8: Cross-table with sorting
+
+```
+[TargetTable].SORTBY([TargetTable].[SortCol], FALSE).[OutputCol]
+[TargetTable].FILTER(CurrentValue.[Field] = [Value]).SORTBY([TargetTable].[SortCol]).[OutputCol]
+```
+
+---
+
+## Section 12: Anti-Pattern Collection
+
+### Mistake 1: Extra argument in MAP
+
+```
+Wrong:   [Table].[Col].MAP([Table2].[Col], CurrentValue + 1)
+Correct: [Table].[Col].MAP(CurrentValue + 1)
+```
+
+Reason: MAP takes only two arguments (data range + mapping expression), no "lookup range".
+
+### Mistake 2: Inverted FILTER syntax
+
+```
+Wrong:   condition.[Table].FILTER()
+Correct: [Table].FILTER(condition).[ResultCol]    (result column required when data range is a table)
+```
+
+Reason: FILTER's data range comes first, condition is passed as the argument.
+
+### Mistake 3: Using CurrentValue.[Field] on a column range
+
+```
+Wrong:   SUMIF([Sales].[Revenue], CurrentValue.[Salesperson] = [Name])
+Correct: [Sales].FILTER(CurrentValue.[Salesperson] = [Name]).[Revenue].LISTCOMBINE().SUM()
+```
+
+Reason: `SUMIF([Sales].[Revenue], ...)` uses "Revenue" column as data range. CurrentValue is each revenue value (scalar), not a row — cannot use `.` to access other fields. Use FILTER with the table as data range for cross-field conditions.
+
+### Mistake 4: Missing result column after FILTER
+
+```
+Wrong:   [Sales].FILTER(CurrentValue.[Amount] > 100)
+Correct: [Sales].FILTER(CurrentValue.[Amount] > 100).[Customer]
+```
+
+Reason: FILTER on a table returns a table reference; must specify result column with `.[Field]` at the end.
+
+### Mistake 5: Nested FILTER
+
+```
+Wrong:   [Table1].FILTER(CurrentValue.[ID] = [Table2].FILTER(CurrentValue.[Status]="Done").[ID])
+Correct: [Table1].FILTER(CurrentValue.[ID] = [CurrentRowField]).[OutputCol]
+```
+
+Reason: FILTER/MAP/SUMIF/COUNTIF cannot be nested inside each other's conditions. Split into multiple steps or use link fields.
+
+### Mistake 6: SORTBY without output column
+
+```
+Wrong:   [Table].SORTBY([Table].[Col])
+Correct: [Table].SORTBY([Table].[Col]).[OutputCol]
+```
+
+Reason: SORTBY must have an output column at the end; otherwise the result cannot be represented as an array.
+
+### Mistake 7: SORTBY sort column without table name
+
+```
+Wrong:   [Table].SORTBY([Col]).[OutputCol]
+Correct: [Table].SORTBY([Table].[Col]).[OutputCol]
+```
+
+Reason: SORTBY's sort column must use `[TableName].[FieldName]` format.
+
+### Mistake 8: Using CONTAIN for text substring matching
+
+```
+Wrong:   CONTAIN([Notes], "urgent")
+Correct: CONTAINTEXT([Notes], "urgent")
+```
+
+Reason: CONTAIN checks if a list/MultiSelect contains a whole value, not substring matching. Use CONTAINTEXT for text substrings.
+
+### Mistake 9: Date concatenation without formatting
+
+```
+Not recommended: "Deadline: " & [DateField]                          ← output format is uncontrolled
+Recommended:     "Deadline: " & TEXT([DateField], "YYYY-MM-DD")
+```
+
+Reason: Concatenating a date with `&` won't error, but uses the default format. Use TEXT to specify the format explicitly.
+
+### Mistake 10: Reversed DAYS parameter order
+
+```
+Wrong:   DAYS([StartDate], [EndDate])  → returns negative
+Correct: DAYS([EndDate], [StartDate])  → returns positive
+```
+
+Reason: DAYS parameter order is end date first, start date second.
+
+### Mistake 11: Chaining zero-argument functions
+
+```
+Wrong:   TODAY.DAYS([Date])
+Correct: TODAY().DAYS([Date])
+```
+
+Reason: NOW, TODAY, PI and other zero-argument functions must include parentheses.
+
+---
+
+## Section 13: Complete Examples
+
+### Example 1: Employee sales summary
+
+**Table structure** (from `+table-get`):
+
+- Employees: EmployeeID (Text), Name (Text), Department (Text)
+- Sales: ContractID (Number), SalespersonID (Text), Quantity (Number), Total (Number)
+
+**Current table**: Employees
+
+**Requirement**: For each employee, output "Sold XX orders" if they have sales records, otherwise "No sales records".
+
+**Formula**:
+
+```
+IF(
+  [Sales].COUNTIF(CurrentValue.[SalespersonID] = [EmployeeID]) >= 1,
+  "Sold " & [Sales].COUNTIF(CurrentValue.[SalespersonID] = [EmployeeID]) & " orders",
+  "No sales records"
+)
+```
+
+**Field JSON**:
+
+```json
+{
+  "type": "formula",
+  "name": "Sales Summary",
+  "expression": "IF([Sales].COUNTIF(CurrentValue.[SalespersonID] = [EmployeeID]) >= 1, \"Sold \" & [Sales].COUNTIF(CurrentValue.[SalespersonID] = [EmployeeID]) & \" orders\", \"No sales records\")"
+}
+```
+
+**Explanation**: `[Sales].COUNTIF(...)` uses the entire Sales table as data range. CurrentValue represents each row in Sales, accessing `CurrentValue.[SalespersonID]` for that row's salesperson. `[EmployeeID]` refers to the current row in the Employees table (where the formula lives).
+
+### Example 2: Chained cross-table access via link fields
+
+**Table structure**:
+
+- Orders: ID (AutoNumber), OrderItems (Link [target: OrderItems, foreign key: ID])
+- OrderItems: ID (AutoNumber), Product (Link [target: Products, foreign key: ID])
+- Products: ID (AutoNumber), ProductName (Text)
+
+**Current table**: Orders
+
+**Requirement**: Deduplicate and comma-join all product names from linked order items.
+
+**Formula**:
+
+```
+[OrderItems].[Product].[ProductName].UNIQUE().ARRAYJOIN(",")
+```
+
+**Field JSON**:
+
+```json
+{
+  "type": "formula",
+  "name": "Product List",
+  "expression": "[OrderItems].[Product].[ProductName].UNIQUE().ARRAYJOIN(\",\")"
+}
+```
+
+**Explanation**: `[OrderItems]` gets linked order item records, `.[Product]` expands to each item's linked product, `.[ProductName]` gets all product names, `.UNIQUE()` deduplicates, `.ARRAYJOIN(",")` joins with commas.
+
+### Example 3: Cross-table filter + sort
+
+**Table structure**:
+
+- Projects: ProjectName (Text), Status (Text), Owner (Text)
+- Tasks: TaskName (Text), Project (Text), Priority (Number), DueDate (Date)
+
+**Current table**: Projects
+
+**Requirement**: Find the highest-priority (lowest number) task name for the current project.
+
+**Formula**:
+
+```
+FIRST(
+  [Tasks].FILTER(CurrentValue.[Project] = [ProjectName]).SORTBY([Tasks].[Priority], TRUE).[TaskName]
+)
+```
+
+**Field JSON**:
+
+```json
+{
+  "type": "formula",
+  "name": "Top Priority Task",
+  "expression": "FIRST([Tasks].FILTER(CurrentValue.[Project] = [ProjectName]).SORTBY([Tasks].[Priority], TRUE).[TaskName])"
+}
+```
+
+**Explanation**: `[Tasks].FILTER(CurrentValue.[Project] = [ProjectName])` filters tasks belonging to the current project. `.SORTBY([Tasks].[Priority], TRUE)` sorts by priority ascending. `.[TaskName]` extracts task names. `FIRST(...)` gets the first one (highest priority).
+
+---
+
+## Section 14: Translating User Requirements to Formulas
+
+When the user describes their formula need in natural language, follow these rules to convert it into a precise expression:
+
+1. **Numbers must use precise values**: "less than 80%" → field value less than `0.8`. "above 1000" → `>= 1000`.
+2. **Interval boundaries**: "above/below/within" = closed (inclusive); "less than/more than/outside" = open (exclusive).
+3. **Branching logic** must be organized as an ordered list with a fallback branch. Each branch has a condition and output.
+   - Example: "return risk level for 1-3" → `IFS([Value] = 1, "low", [Value] = 2, "medium", [Value] = 3, "high")` with an `IFERROR` or trailing empty-string fallback.
+4. **Multi-level branches must be flattened** to a single level. Nested if-else chains → flat IFS.
+5. **Branch conditions must be mutually exclusive**. If the user's conditions overlap, rewrite to eliminate ambiguity.
+6. **Reorder branches by logical priority** if the user's order is illogical (e.g., check specific conditions before catch-all).
+
+---
+
+## Section 15: Constraint Summary
+
+- Request body must include `"type": "formula"` — this field is required
+- Only use functions and operators listed in this document
+- FILTER/SUMIF/COUNTIF/MAP must not be nested inside each other's conditions (chained calls are not nesting)
+- Do not use LOOKUP — use FILTER exclusively
+- Table and field names must exactly match `+table-get` output
+- Strings must use double quotes `"`
+- Format dates with TEXT before concatenating, to control output format
+- SORTBY can only be chained and must include an output column
+- Link fields return lists — aggregate or extract single values before output

+ 83 - 0
.agents/skills/lark-base/references/lark-base-advperm-disable.md

@@ -0,0 +1,83 @@
+# base +advperm-disable
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+停用指定 Base 的高级权限。停用后自定义角色等高级权限功能将不可用。
+
+## 推荐命令
+
+```bash
+# 停用高级权限
+lark-cli base +advperm-disable \
+  --base-token VwGhbYCXQaYGMzsWlEZcBbfMnod
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/advperm/enable?enable=false
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识,27 位字母数字字符串 |
+
+**Query 参数:**
+
+| 参数 | 必填 | 类型 | 说明 |
+|------|------|------|------|
+| `enable` | 是 | bool | 固定为 `false`,表示停用高级权限 |
+
+## API 出参详情
+
+**Response:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | int32 | 错误码,0 表示成功 |
+| `message` | string | 错误信息 |
+| `data` | string | 成功时为空 |
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "success": true
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**高风险写入操作** — 停用高级权限会影响所有已配置的自定义角色,执行前必须向用户确认。
+
+1. 向用户确认 `--base-token`,并提醒停用会影响已有角色配置
+2. 执行命令
+3. 确认返回 `code: 0` 表示停用成功
+
+## 坑点
+
+- ⚠️ **操作用户必须为 Base 管理员**:非管理员调用会返回权限错误
+- ⚠️ **停用影响已有角色**:停用高级权限后,已创建的自定义角色将失效
+- ⚠️ **API 路径版本**:本接口使用 `base/v3`,路径必须从原始文档提取,不要用 WebSearch 补全
+- ⚠️ **data 字段是 JSON 字符串**:响应中 `data` 是 string 类型(非 object),需要双重解析
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 80 - 0
.agents/skills/lark-base/references/lark-base-advperm-enable.md

@@ -0,0 +1,80 @@
+# base +advperm-enable
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+启用指定 Base 的高级权限。启用后可使用自定义角色等高级权限功能。
+
+## 推荐命令
+
+```bash
+# 启用高级权限
+lark-cli base +advperm-enable \
+  --base-token VwGh**************Mnod
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/advperm/enable?enable=true
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识,27 位字母数字字符串 |
+
+**Query 参数:**
+
+| 参数 | 必填 | 类型 | 说明 |
+|------|------|------|------|
+| `enable` | 是 | bool | 固定为 `true`,表示启用高级权限 |
+
+## API 出参详情
+
+**Response:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | int32 | 错误码,0 表示成功 |
+| `message` | string | 错误信息 |
+| `data` | string | 成功时为空 |
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "success": true
+  }
+}
+```
+
+## 工作流
+
+1. 向用户确认 `--base-token`
+2. 执行命令
+3. 确认返回 `code: 0` 表示启用成功
+
+## 坑点
+
+- ⚠️ **操作用户必须为 Base 管理员**:非管理员调用会返回权限错误
+- ⚠️ **API 路径版本**:本接口使用 `base/v3`,路径必须从原始文档提取,不要用 WebSearch 补全
+- ⚠️ **data 字段是 JSON 字符串**:响应中 `data` 是 string 类型(非 object),需要双重解析
+- ⚠️ **启用后才能管理角色**:`+role-create / +role-update / +role-delete` 等角色操作需要先启用高级权限
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 79 - 0
.agents/skills/lark-base/references/lark-base-base-copy.md

@@ -0,0 +1,79 @@
+# base +base-copy
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+复制一个已有 Base;可选只复制结构,不复制内容。
+
+## 推荐命令
+
+```bash
+lark-cli base +base-copy \
+  --base-token app_xxx \
+  --name "Copied Base"
+
+lark-cli base +base-copy \
+  --base-token app_xxx \
+  --name "Copied Base" \
+  --folder-token fld_xxx \
+  --time-zone Asia/Shanghai \
+  --without-content
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 源 Base Token |
+| `--name <name>` | 否 | 新 Base 名称 |
+| `--folder-token <token>` | 否 | 目标文件夹 token |
+| `--time-zone <tz>` | 否 | 时区,如 `Asia/Shanghai` |
+| `--without-content` | 否 | 只复制结构,不复制内容 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/copy
+```
+
+## 返回重点
+
+- 返回 `base`。
+- CLI 会额外标记 `copied: true`。
+- 回复结果时,必须主动返回新 Base 的可访问链接:
+  - 优先使用返回结果中的 `base.url`
+  - 同时返回新 Base 的 token;字段名以实际返回为准,常见为 `base_token` 或 `app_token`
+  - 如果本次返回没有 `url`,至少返回新 Base 的名称和 token
+
+> [!IMPORTANT]
+> 如果 Base 是**以应用身份(bot)复制**出来的,agent 在复制成功后应**默认继续使用 bot 身份**,为当前可用的 user 身份添加该 Base 的 `full_access`(管理员)权限。
+> 推荐流程:
+> 1. 先用 `lark-cli contact +get-user` 获取当前用户信息,并从返回结果中读取该用户的 `open_id`
+> 2. 再切回 bot 身份,使用这个 `open_id` 给该用户授权该 Base 的 `full_access`(管理员)权限
+>
+> 如果 `lark-cli contact +get-user` 无法执行,或者本地没有可用的 user 身份、拿不到当前用户的 `open_id`,则应视为“本地没有可用的 user 身份”,明确说明因此未完成授权。
+>
+> 回复复制结果时,除 `base token` 和可访问链接外,还必须明确告知用户授权结果:
+> - 如果授权成功:直接说明当前 user 已获得该 Base 的管理员权限
+> - 如果本地没有可用的 user 身份:明确说明因此未完成授权
+> - 如果授权失败:明确说明 Base 已复制成功,但授权失败,并透出失败原因;同时提示用户可以稍后重试授权,或继续使用应用身份(bot)处理该 Base
+>
+> 如果授权未完成,应继续给出后续引导:用户可以稍后重试授权,也可以继续使用应用身份(bot)处理该 Base;如果希望后续改由自己管理,也可将 Base owner 转移给该用户。
+>
+> **仍然不要擅自执行 owner 转移。** 如果用户需要把 owner 转给自己,必须单独确认。
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 先确认源 Base Token。
+2. `--name`、`--folder-token`、`--time-zone` 都是可选项;用户没要求时不要为这些可选参数额外追问。
+3. 只要结构时,显式传 `--without-content`。
+4. 复制成功后,整理并返回:新 Base 名称、token,以及响应中已有的可访问链接。
+
+## 参考
+
+- [lark-base-workspace.md](lark-base-workspace.md) — base / workspace 索引页
+- [lark-base-base-create.md](lark-base-base-create.md) — 创建全新 Base

+ 68 - 0
.agents/skills/lark-base/references/lark-base-base-create.md

@@ -0,0 +1,68 @@
+# base +base-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+创建一个新的 Base;可选指定父文件夹和时区。
+
+## 推荐命令
+
+```bash
+lark-cli base +base-create \
+  --name "New Base"
+
+lark-cli base +base-create \
+  --name "项目管理" \
+  --folder-token fld_xxx \
+  --time-zone Asia/Shanghai
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--name <name>` | 是 | 新 Base 名称 |
+| `--folder-token <token>` | 否 | 目标文件夹 token |
+| `--time-zone <tz>` | 否 | 时区,如 `Asia/Shanghai` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases
+```
+
+## 返回重点
+
+- 返回 `base`。
+- CLI 会额外标记 `created: true`。
+- 回复结果时,必须主动返回新 Base 的可访问链接:
+  - 优先使用返回结果中的 `base.url`
+  - 同时返回新 Base 的 token;字段名以实际返回为准,常见为 `base_token` 或 `app_token`
+  - 如果本次返回没有 `url`,至少返回新 Base 的名称和 token
+
+> [!IMPORTANT]
+> 如果 Base 是**以应用身份(bot)创建**的,shortcut 会在创建成功后自动尝试为当前 CLI 用户添加该 Base 的 `full_access`(管理员)权限,并在输出中附带 `permission_grant` 字段。
+>
+> `permission_grant.status` 语义如下:
+> - `granted`:当前 CLI 用户已获得该 Base 的管理员权限
+> - `skipped`:Base 已创建成功,但没有可授权的当前 CLI 用户,或创建结果缺少可授权 token
+> - `failed`:Base 已创建成功,但自动授权失败;结果中会包含失败原因,用户可稍后重试授权,或继续使用应用身份(bot)处理该 Base
+>
+> 回复创建结果时,除 `base token` 和可访问链接外,还必须明确告知用户 `permission_grant` 的结果。
+>
+> **仍然不要擅自执行 owner 转移。** 如果用户需要把 owner 转给自己,必须单独确认。
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 先确认 Base 名称。
+2. `--folder-token`、`--time-zone` 都是可选项;用户没要求时不要为此额外追问。
+3. 创建成功后,整理并返回:Base 名称、token,以及响应中已有的可访问链接。
+
+## 参考
+
+- [lark-base-workspace.md](lark-base-workspace.md) — base / workspace 索引页
+- [lark-base-base-copy.md](lark-base-base-copy.md) — 复制 Base

+ 39 - 0
.agents/skills/lark-base/references/lark-base-base-get.md

@@ -0,0 +1,39 @@
+# base +base-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+读取一个 Base 的详情。
+
+## 推荐命令
+
+```bash
+lark-cli base +base-get \
+  --base-token app_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token
+```
+
+## 返回重点
+
+- 返回 `base`,通常包含 `base_token / name / url` 等信息。
+
+## 坑点
+
+- ⚠️ 先确认传入的是 `base_token`,不是 `workspace_token`。
+- ⚠️ 如果最初输入来自 `/wiki/...`,不要直接把 `wiki_token` 当 `--base-token`;若报 `param baseToken is invalid` / `base_token invalid`,先用 `lark-cli wiki spaces get_node` 取 `node.obj_token`,再重试 `+base-get`。
+
+## 参考
+
+- [lark-base-workspace.md](lark-base-workspace.md) — base 索引页

+ 83 - 0
.agents/skills/lark-base/references/lark-base-dashboard-arrange.md

@@ -0,0 +1,83 @@
+# base +dashboard-arrange
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流
+
+自动重新排列仪表盘组件布局。服务端根据组件数量和类型进行智能布局优化。
+
+## 使用场景
+
+| 场景 | 说明 |
+|------|------|
+| **从 0 到 1 搭建后** | 使用 `+dashboard-create` 和 `+dashboard-block-create` 创建仪表盘后,默认布局可能不够工整美观,推荐使用本命令做一次整体重排 |
+| **用户明确要求** | 用户主动要求对已有仪表盘进行布局重排或美化时 |
+
+> [!CAUTION]
+> - **不建议**在已有仪表盘上自动调用此命令,除非用户明确要求
+> - 排列结果是**服务端智能推荐**,不一定完全符合用户预期
+> - 无法指定具体位置(如"第一排放 A,第二排放 B"),排列逻辑是**自适应**的
+
+## 推荐命令
+
+```bash
+# 基础用法
+lark-cli base +dashboard-arrange \
+  --base-token xxx \
+  --dashboard-id blk_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--user-id-type <type>` | 否 | 用户 ID 类型:open_id / union_id / user_id |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "dashboard_id": "blk_xxx",
+  "name": "数据分析",
+  "blocks": [
+    {
+      "block_id": "chtbxxxx",
+      "block_name": "总销售额",
+      "block_type": "statistics",
+      "layout": {
+        "x": 0,
+        "y": 0,
+        "w": 6,
+        "h": 6
+      }
+    },
+    {
+      "block_id": "chtbcrxxxx",
+      "block_name": "月度趋势",
+      "block_type": "column",
+      "layout": {
+        "x": 6,
+        "y": 0,
+        "w": 6,
+        "h": 6
+      }
+    }
+  ],
+  "arranged": true
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `blocks[].layout` | 重排后的布局信息,包含 x/y/w/h |
+| `arranged` | 是否重排成功 |
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 108 - 0
.agents/skills/lark-base/references/lark-base-dashboard-block-create.md

@@ -0,0 +1,108 @@
+# base +dashboard-block-create
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流
+> **关键:** 创建前必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解组件类型和 data_config 结构
+
+在仪表盘中创建一个组件(Block)。
+
+## 关键约束
+
+- **`type` 创建后不可修改**,创建时务必选对
+- **`data_config` 结构随 `type` 变化**,不同组件类型字段不同,**⚠️ 必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解如何构造**
+- **组件创建必须串行执行**,不能并发
+
+## 推荐命令
+
+```bash
+# 简单示例:创建一个指标卡(统计记录数)
+lark-cli base +dashboard-block-create \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --name "总记录数" \
+  --type statistics \
+  --data-config '{"table_name":"订单表","count_all":true}'
+
+# 文本组件示例(Markdown 富文本)
+lark-cli base +dashboard-block-create \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --name "说明文字" \
+  --type text \
+  --data-config '{"text":"# 标题\n## 副标题\n**加粗** *斜体* ~~删除~~\n1. 列表1\n2. 列表2"}'
+
+# 复杂配置用文件传入
+lark-cli base +dashboard-block-create \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --name "销售额趋势" \
+  --type line \
+  --data-config @config.json
+```
+
+完整流程参考 [lark-base-dashboard.md](lark-base-dashboard.md) 的「场景 1:从 0 到 1 创建仪表盘」
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID(从 `+dashboard-list/get` 获取) |
+| `--name <name>` | **是** | 组件名称(允许重名) |
+| `--type <type>` | **是** | 组件类型,见下方枚举值。**不同 type 对应不同的 data_config 结构**,常用:`column`(柱状图)、`line`(折线图)、`pie`(饼图)、`statistics`(指标卡)、`text`(文本) |
+| `--data-config <json>` | 否 | 数据配置 JSON,**结构随 type 变化**。**⚠️ 必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解如何构造**。创建时会做本地校验,更新时由后端校验 |
+| `--user-id-type <type>` | 否 | 用户 ID 类型,filter 涉及人员字段时使用 |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+### type 枚举值
+
+| 值 | 说明 |
+|----|------|
+| `column` | 柱状图 |
+| `bar` | 条形图 |
+| `line` | 折线图 |
+| `pie` | 饼图 |
+| `ring` | 环形图 |
+| `area` | 面积图 |
+| `combo` | 组合图 |
+| `scatter` | 散点图 |
+| `funnel` | 漏斗图 |
+| `wordCloud` | 词云 |
+| `radar` | 雷达图 |
+| `statistics` | 指标卡 |
+| `text` | 文本(支持 Markdown) |
+
+## 返回示例
+
+```json
+{
+  "block": {
+    "block_id": "chtxxxxxxxx",
+    "name": "总记录数",
+    "type": "statistics",
+    "data_config": {
+      "table_name": "电商交易明细",
+      "count_all": true
+    }
+  },
+  "created": true
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `block.block_id` | 组件 ID,后续编辑/删除需要用到,务必记录 |
+| `block.name` | 组件名称 |
+| `block.type` | 组件类型 |
+| `block.data_config` | 实际创建的数据配置(可能包含后端自动添加的默认值)|
+| `created` | 是否创建成功 |
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引
+- [dashboard-block-data-config.md](dashboard-block-data-config.md) — data_config 结构、图表类型、filter 规则

+ 46 - 0
.agents/skills/lark-base/references/lark-base-dashboard-block-delete.md

@@ -0,0 +1,46 @@
+# base +dashboard-block-delete
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+删除仪表盘中的一个组件(Block),不可恢复。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-block-delete \
+  --base-token bascn***************CtadY \
+  --dashboard-id blkxxx \
+  --block-id chtxxxxxxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--block-id <id>` | 是 | Block ID |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "block_id": "chtxxxxxxxx",
+  "deleted": true
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `block_id` | 被删除的组件 ID |
+| `deleted` | 是否删除成功 |
+
+> [!CAUTION]
+> 这是**写入操作**且**不可逆** — 执行前必须向用户确认。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 57 - 0
.agents/skills/lark-base/references/lark-base-dashboard-block-get.md

@@ -0,0 +1,57 @@
+# base +dashboard-block-get
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+获取仪表盘中单个组件的详情(包含 data_config 完整配置)。常用于:1) 查看组件的完整配置;2) 编辑组件前了解当前配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-block-get \
+  --base-token bascn***************CtadY \
+  --dashboard-id blkxxx \
+  --block-id chtxxxxxxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--block-id <id>` | 是 | Block ID |
+| `--user-id-type <type>` | 否 | 用户 ID 类型:open_id / union_id / user_id |
+| `--format <fmt>` | 否 | 输出格式 |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "block": {
+    "block_id": "chtxxxxxxxx",
+    "name": "柱状图",
+    "type": "column",
+    "data_config": {
+      "table_name": "电商交易明细",
+      "series": [{"field_name": "营销费用", "rollup": "SUM"}],
+      "group_by": [{"field_name": "品类", "mode": "integrated"}]
+    },
+    "layout": {"x": 0, "y": 0, "w": 6, "h": 4}
+  }
+}
+```
+
+## 返回重点
+
+| 字段 | 说明                            |
+|------|-------------------------------|
+| `block.block_id` | 组件 ID                         |
+| `block.name` | 组件名称                          |
+| `block.type` | 组件类型(如 `column`/`line`/`pie`) |
+| `block.data_config` | 数据配置(新建/编辑组件时可基于此字段修改)        |
+| `block.layout` | 布局信息(只读,x/y/w/h 坐标和尺寸)        |
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 53 - 0
.agents/skills/lark-base/references/lark-base-dashboard-block-list.md

@@ -0,0 +1,53 @@
+# base +dashboard-block-list
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+分页列出仪表盘中的所有组件(Block)。常用于:1) 查看仪表盘有哪些组件;2) 获取组件 ID 和类型用于后续编辑/删除。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-block-list \
+  --base-token bascn***************CtadY \
+  --dashboard-id blkxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--page-size <n>` | 否 | 每页数量,默认 20,最大 100 |
+| `--page-token <token>` | 否 | 分页标记 |
+| `--format <fmt>` | 否 | 输出格式:json / pretty / table / csv / ndjson |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "items": [
+    {"block_id": "chtxxxxxxxx", "name": "图表", "type": "column"},
+    {"block_id": "chtxxxxxxxx", "name": "总利润", "type": "statistics"}
+  ],
+  "total": 4,
+  "has_more": false
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `items` | 组件列表,每项包含 `block_id`(ID)、`name`(名称)、`type`(类型)|
+| `total` | 组件总数 |
+| `has_more` | 是否有更多组件(为 `true` 时需用 `page_token` 继续获取)|
+
+## 坑点
+
+- `+dashboard-block-list` 禁止并发调用;批量执行时只能串行。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 84 - 0
.agents/skills/lark-base/references/lark-base-dashboard-block-update.md

@@ -0,0 +1,84 @@
+# base +dashboard-block-update
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流
+> **关键:** 更新前必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解 data_config 结构和更新规则
+
+更新仪表盘中组件的名称或数据配置。
+
+## 关键约束
+
+- **不可修改 `type` 和 `layout`** — 只能更新 `name` 和 `data_config`。
+- **`data_config` 顶层按 key merge** — 只需传入要修改的顶层字段,未传的字段保留原值;但每个字段内部是全量替换(如传新 `filter` 会完整覆盖旧 `filter`)。
+- **`series` 与 `count_all` 二选一** — 且至少提供其一。
+- **表名用 name,不是 ID** — `table_name` 对应的是表名称(如「订单表」),不是 `table_id`。
+- **`user_id_type`** 仅在 filter 涉及人员字段时有意义。
+
+> [!TIP]
+> CLI 默认会对 `data_config` 做轻量校验与规范化;如需兼容特殊场景,可加 `--no-validate` 跳过。
+
+## 推荐命令
+
+```bash
+# 示例 1:更新组件名称
+lark-cli base +dashboard-block-update \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --block-id chtxxxxxxxx \
+  --name "新名称"
+
+# 示例 2:更新数据配置(只传要改的字段,未传字段保留原值)
+lark-cli base +dashboard-block-update \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --block-id chtxxxxxxxx \
+  --data-config '{"filter":{"conjunction":"and","conditions":[{"field_name":"状态","operator":"is","value":"已完成"}]}}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--block-id <id>` | 是 | Block ID |
+| `--name <name>` | 否 | 新名称 |
+| `--data-config <json>` | 否 | 数据配置 JSON。**结构随 block 的 `type` 变化**。**⚠️ 必须阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解如何构造** |
+| `--user-id-type <type>` | 否 | 用户 ID 类型,filter 涉及人员字段时使用 |
+| `--no-validate` | 否 | 跳过 data_config 本地校验(用于兼容特殊场景) |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "block": {
+    "block_id": "chtxxxxxxxx",
+    "name": "新名称",
+    "type": "column",
+    "data_config": {
+      "table_name": "订单表",
+      "series": [{"field_name": "金额", "rollup": "SUM"}],
+      "group_by": [{"field_name": "类别", "mode": "integrated"}]
+    }
+  },
+  "updated": true
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `block.block_id` | 组件 ID |
+| `block.name` | 更新后的名称 |
+| `block.type` | 组件类型(不可修改)|
+| `block.data_config` | 更新后的数据配置 |
+| `updated` | 是否更新成功 |
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引
+- [dashboard-block-data-config.md](dashboard-block-data-config.md) — data_config 结构、图表类型、filter 规则

+ 73 - 0
.agents/skills/lark-base/references/lark-base-dashboard-create.md

@@ -0,0 +1,73 @@
+# base +dashboard-create
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+创建空白仪表盘。创建成功后务必记录返回的 `dashboard_id`,后续添加组件和管理仪表盘都需要用到。
+
+## 关键约束
+
+- **dashboard_id** 在 create 返回中取得,后续 get/update/delete 使用。
+
+## 推荐命令
+
+```bash
+# 创建仪表盘
+lark-cli base +dashboard-create \
+  --base-token VwGhb**************fMnod \
+  --name "销售报表"
+
+# 创建仪表盘(指定主题)
+lark-cli base +dashboard-create \
+  --base-token VwGhb**************fMnod \
+  --name "销售报表" \
+  --theme-style default
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--name <name>` | 是 | 仪表盘名称 |
+| `--theme-style <style>` | 否 | 主题风格(见下方枚举) |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+### theme-style 枚举
+
+| 值 | 说明 |
+|------|------|
+| `default` | 默认主题 |
+| `SimpleBlue` | 简约蓝 |
+| `DarkGreen` | 深绿 |
+| `summerBreeze` | 夏日微风 |
+| `simplistic` | 简洁 |
+| `energetic` | 活力 |
+| `deepDark` | 深色 |
+| `futuristic` | 未来感 |
+
+## 返回示例
+
+```json
+{
+  "dashboard_id": "blkxxxxxxxxxxxx",
+  "name": "数据分析仪表盘",
+  "theme": {
+    "theme_style": "default"
+  }
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `dashboard_id` | 仪表盘 ID(如 `blkxxxxxxxxxxxx`),后续操作都需要用到,务必记录 |
+| `name` | 仪表盘名称 |
+| `theme.theme_style` | 主题风格 |
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 44 - 0
.agents/skills/lark-base/references/lark-base-dashboard-delete.md

@@ -0,0 +1,44 @@
+# base +dashboard-delete
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+删除仪表盘(会同时删除其下所有组件,不可恢复)。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-delete \
+  --base-token VwGhb**************fMnod \
+  --dashboard-id blkxxxxxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "dashboard_id": "blkxxxxxxxxxxxx",
+  "deleted": true
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `dashboard_id` | 被删除的仪表盘 ID |
+| `deleted` | 是否删除成功 |
+
+> [!CAUTION]
+> 这是**写入操作**且**不可逆** — 执行前必须向用户确认。删除仪表盘会同时删除其下所有组件,不可恢复。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 59 - 0
.agents/skills/lark-base/references/lark-base-dashboard-get.md

@@ -0,0 +1,59 @@
+# base +dashboard-get
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+获取仪表盘详情(名称、主题配置、包含的所有组件列表)。常用于:1) 查看仪表盘有哪些组件;2) 获取组件 ID 用于后续编辑/删除。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-get \
+  --base-token VwGhb**************fMnod \
+  --dashboard-id blkxxxxxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--format <fmt>` | 否 | 输出格式 |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "dashboard_id": "blkxxxxxxxxxxxx",
+  "name": "数据分析仪表盘",
+  "theme": {
+    "theme_style": "default"
+  },
+  "blocks": [
+    {
+      "block_id": "chtxxxxxxxx",
+      "block_name": "总净利润",
+      "block_type": "statistics"
+    },
+    {
+      "block_id": "chtxxxxxxxx",
+      "block_name": "品类占比",
+      "block_type": "pie"
+    }
+  ]
+}
+```
+
+## 返回重点
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `dashboard_id` | string | 仪表盘 ID(如 `blkxxxxxxxxxxxx`)|
+| `name` | string | 仪表盘名称 |
+| `theme.theme_style` | string | 主题风格:`default` / `SimpleBlue` / `DarkGreen` / `summerBreeze` / `simplistic` / `energetic` / `deepDark` / `futuristic` |
+| `blocks` | []object | 组件列表,每项包含 `block_id`(组件ID)、`block_name`(名称)、`block_type`(类型,如 `column`/`line`/`pie`)|
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 52 - 0
.agents/skills/lark-base/references/lark-base-dashboard-list.md

@@ -0,0 +1,52 @@
+# base +dashboard-list
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+分页列出一个 Base 下的所有仪表盘。常用于:1) 查看当前有哪些仪表盘;2) 获取 dashboard_id 用于后续操作(如添加组件、查看详情)。
+
+## 关键约束
+
+- `+dashboard-list` 禁止并发调用;批量列多个 Base 时必须串行。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-list \
+  --base-token VwGhb**************fMnod
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--page-size <n>` | 否 | 每页数量 |
+| `--page-token <token>` | 否 | 分页标记 |
+| `--format <fmt>` | 否 | 输出格式:json / pretty / table / csv / ndjson |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 返回示例
+
+```json
+{
+  "items": [
+    {"dashboard_id": "blkxxxxxxxxxxxx", "name": "商品总览仪表盘"},
+    {"dashboard_id": "blkxxxxxxxxxxxx", "name": "订单总览仪表盘"},
+    {"dashboard_id": "blkxxxxxxxxxxxx", "name": "销售数据分析仪表盘"}
+  ],
+  "total": 3,
+  "has_more": false
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `items` | 仪表盘列表,每项包含 `dashboard_id`(ID)和 `name`(名称)|
+| `total` | 总数 |
+| `has_more` | 是否有下一页(为 `true` 时需用 `page_token` 继续获取)|
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 69 - 0
.agents/skills/lark-base/references/lark-base-dashboard-update.md

@@ -0,0 +1,69 @@
+# base +dashboard-update
+
+> **前置条件:** 先阅读 [lark-base-dashboard.md](lark-base-dashboard.md) 了解整体工作流。
+
+更新仪表盘名称或主题。
+
+## 推荐命令
+
+```bash
+lark-cli base +dashboard-update \
+  --base-token VwGhb**************fMnod \
+  --dashboard-id blkxxxxxxx \
+  --name "新名称" \
+  --theme-style default
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--dashboard-id <id>` | 是 | 仪表盘 ID |
+| `--name <name>` | 否 | 新名称 |
+| `--theme-style <style>` | 否 | 主题风格(见下方枚举) |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+### theme-style 枚举
+
+| 值 | 说明 |
+|------|------|
+| `default` | 默认主题 |
+| `SimpleBlue` | 简约蓝 |
+| `DarkGreen` | 深绿 |
+| `summerBreeze` | 夏日微风 |
+| `simplistic` | 简洁 |
+| `energetic` | 活力 |
+| `deepDark` | 深色 |
+| `futuristic` | 未来感 |
+
+## 返回示例
+
+```json
+{
+  "dashboard": {
+    "dashboard_id": "blkxxxxxxxxxxxx",
+    "name": "新名称",
+    "theme": {
+      "theme_style": "default"
+    }
+  },
+  "updated": true
+}
+```
+
+## 返回重点
+
+| 字段 | 说明 |
+|------|------|
+| `dashboard` | 更新后的仪表盘对象 |
+| `dashboard.name` | 新名称(如果更新了)|
+| `dashboard.theme.theme_style` | 新主题(如果更新了)|
+| `updated` | 是否更新成功 |
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+## 参考
+
+- [lark-base-dashboard.md](lark-base-dashboard.md) — dashboard 模块指引

+ 240 - 0
.agents/skills/lark-base/references/lark-base-dashboard.md

@@ -0,0 +1,240 @@
+# Dashboard(仪表盘/数据看板)模块指引
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+Dashboard 是 Base 中的数据可视化看板,可以把表格数据变成**组件**(图表、指标卡等)进行展示。
+
+## 核心概念
+
+- **Dashboard(仪表盘)**:容器,包含多个组件
+- **Block(组件)**:仪表盘中的单个可视化元素(柱状图、折线图、饼图、指标卡等)
+- **data_config**:组件的数据源配置(表名、字段、分组等)
+
+## 能力速览
+
+| 你想做什么 | 用这些命令 | 关键文档 |
+|------|-----------|---------|
+| 创建/删除/改名称 | `+dashboard-create/delete/update` | 本页下方「仪表盘管理」 |
+| 在仪表盘里添加组件 | `+dashboard-block-create` | 先读 [lark-base-dashboard-block-create.md](lark-base-dashboard-block-create.md),再读 [dashboard-block-data-config.md](dashboard-block-data-config.md) |
+| 修改组件 | `+dashboard-block-update` | 先读 [lark-base-dashboard-block-update.md](lark-base-dashboard-block-update.md),再读 [dashboard-block-data-config.md](dashboard-block-data-config.md) |
+| 查看仪表盘有哪些组件 | `+dashboard-get` 或 `+dashboard-block-list` | 本页下方「查看仪表盘」 |
+| 智能重排组件布局 | `+dashboard-arrange` | [lark-base-dashboard-arrange.md](lark-base-dashboard-arrange.md) |
+
+## 典型场景工作流
+
+### 场景 1:从 0 到 1 创建仪表盘
+
+示例:搭建一个销售数据分析仪表盘
+
+```bash
+# 第 1 步:创建空白仪表盘
+lark-cli base +dashboard-create --base-token xxx --name "销售数据分析"
+# 记录返回的 dashboard_id
+
+# 第 2 步:获取数据源信息
+lark-cli base +table-list --base-token xxx
+lark-cli base +field-list --base-token xxx --table-id tbl_xxx
+
+# 第 3 步:规划应该创建哪些组件(根据用户需求确定组件类型和数量)
+# 例如:总销售额(指标卡)、月度趋势(折线图)、品类占比(饼图)
+
+# 第 4 步:顺序创建每个组件(必须串行执行,不能并发)
+# 重要:创建组件前,先阅读 [lark-base-dashboard-block-create.md](lark-base-dashboard-block-create.md) 了解命令参数
+# 再阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解 data_config 结构、组件类型和 filter 规则
+
+# 第 1 个组件
+lark-cli base +dashboard-block-create \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --name "总销售额" \
+  --type statistics \
+  --data-config '{"table_name":"订单表","series":[{"field_name":"金额","rollup":"SUM"}]}'
+
+# 第 2 个组件(等上一个完成后再执行)
+lark-cli base +dashboard-block-create \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --name "月度趋势" \
+  --type line \
+  --data-config '{"table_name":"订单表","series":[{"field_name":"金额","rollup":"SUM"}],"group_by":[{"field_name":"月份","mode":"integrated"}]}'
+
+# 继续创建其他组件...
+
+# 第 5 步:组件创建完成后,使用 arrange 命令智能重排布局(可选但推荐)
+# 默认布局可能不够美观,arrange 会根据组件数量和类型自动优化布局
+lark-cli base +dashboard-arrange \
+  --base-token xxx \
+  --dashboard-id blk_xxx
+```
+
+### 场景 2:在已有仪表盘上添加新组件
+
+```bash
+# 第 1 步:列出仪表盘,定位到当前仪表盘
+lark-cli base +dashboard-list --base-token xxx
+# 获取目标 dashboard_id
+
+# 第 2 步:根据用户诉求规划组件类型和数据源
+# 建议先查看当前仪表盘已有组件,避免重复创建,或作为参考
+lark-cli base +dashboard-get --base-token xxx --dashboard-id blk_xxx
+
+# 第 3 步:获取数据源信息
+lark-cli base +table-list --base-token xxx
+lark-cli base +field-list --base-token xxx --table-id tbl_xxx
+
+# 第 4 步:顺序创建每个新组件(必须串行执行,不能并发)
+# 重要:先阅读 [lark-base-dashboard-block-create.md](lark-base-dashboard-block-create.md) 了解命令参数
+# 再阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解 data_config 结构
+lark-cli base +dashboard-block-create \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --name "新组件名" \
+  --type column \
+  --data-config '{...}'
+```
+
+### 场景 3:编辑已有组件
+
+> [!IMPORTANT]
+> `+dashboard-block-update` **不能修改组件的 `type`**(图表类型),只能更新 `name` 和 `data_config`。
+> 如需更换组件类型,必须先删除再重新创建。
+
+```bash
+# 第 1 步:列出仪表盘,定位到当前仪表盘
+lark-cli base +dashboard-list --base-token xxx
+
+# 第 2 步:列出组件,获取到目标组件
+lark-cli base +dashboard-block-list --base-token xxx --dashboard-id blk_xxx
+# 获取目标 block_id
+# 提示:查看已有组件可作为参考,或检查是否重复创建相似组件
+
+# 第 3 步:获取组件当前详情
+lark-cli base +dashboard-block-get --base-token xxx --dashboard-id blk_xxx --block-id chtxxxxxxxx
+
+# 第 4 步:根据用户编辑诉求准备更新
+# 如果编辑诉求涉及数据源变更,需要先获取数据源信息
+lark-cli base +table-list --base-token xxx
+lark-cli base +field-list --base-token xxx --table-id tbl_xxx
+
+# 第 5 步:执行更新
+# 重要:先阅读 [lark-base-dashboard-block-update.md](lark-base-dashboard-block-update.md) 了解命令参数
+# 再阅读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解 data_config 更新规则
+lark-cli base +dashboard-block-update \
+  --base-token xxx \
+  --dashboard-id blk_xxx \
+  --block-id chtxxxxxxxx \
+  --data-config '{...}'
+```
+
+### 场景 4:重排仪表盘布局
+
+当用户明确要求对已有仪表盘进行布局重排或美化时使用。
+
+> [!CAUTION]
+> - 排列结果是**服务端智能推荐**,不一定完全符合用户预期
+> - 无法指定具体位置(如"第一排放 A,第二排放 B"),排列逻辑是**自适应**的
+> - **不建议**在已有仪表盘上自动调用,除非用户明确要求
+
+```bash
+# 第 1 步:列出仪表盘,定位到目标仪表盘
+lark-cli base +dashboard-list --base-token xxx
+
+# 第 2 步:执行智能重排
+lark-cli base +dashboard-arrange \
+  --base-token xxx \
+  --dashboard-id blk_xxx
+```
+
+### 场景 5:读取仪表盘或组件现状
+
+**选择查询方式:**
+- 想看仪表盘整体结构(含主题、所有组件名称和类型)→ 用 **方式 A**
+- 只想快速查看有哪些组件 → 用 **方式 B**
+- 想看某个组件的详细 data_config 配置 → 用 **方式 C**
+
+```bash
+# 第 1 步:列出仪表盘,定位到当前仪表盘
+lark-cli base +dashboard-list --base-token xxx
+
+# 第 2 步:根据用户诉求查看详情
+
+# 方式 A:查看仪表盘整体情况(包含所有组件列表)
+lark-cli base +dashboard-get --base-token xxx --dashboard-id blk_xxx
+
+# 方式 B:列出所有组件
+lark-cli base +dashboard-block-list --base-token xxx --dashboard-id blk_xxx
+
+# 方式 C:查看某个组件的详细配置
+lark-cli base +dashboard-block-get --base-token xxx --dashboard-id blk_xxx --block-id chtxxxxxxxx
+
+# 最后:把获取到的现状信息整理好告诉用户
+```
+
+## 组件类型选择
+
+组件 `type` 决定展示形式:
+
+| 用户想看什么 | 选什么 type | 说明 |
+|-------------|------------|------|
+| 数据趋势(时间变化) | line | 折线图组件 |
+| 类别比较(谁高谁低) | column | 柱状图组件 |
+| 占比分布(各部分比例) | pie | 饼图组件 |
+| 单个关键指标 | statistics | 指标卡组件 |
+| 富文本说明/标题/注释 | text | 文本组件(支持 Markdown) |
+
+详细组件类型和 data_config 完整规则:[dashboard-block-data-config.md](dashboard-block-data-config.md)
+
+## 常见问题
+
+**Q: 创建组件的命令和 data_config 怎么写?**
+A:
+1. 先读 [lark-base-dashboard-block-create.md](lark-base-dashboard-block-create.md) 了解 `--name`、`--type`、`--data-config` 等参数
+2. 再读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解:
+   - 全部组件类型的可复制模板
+   - filter 筛选条件格式
+   - 字段类型与操作符对应表
+
+**Q: 为什么组件创建失败了?**
+A: 常见原因:
+- `table_name` 用了 table_id 而不是表名(必须用表名称,如「订单表」)
+- `series` 和 `count_all` 同时存在(必须二选一,互斥)
+- 字段名拼写错误(必须用 `+field-list` 获取的真实字段名,禁止猜测)
+- 组件创建并发执行(必须串行,等上一个完成再执行下一个)
+
+**Q: 可以一次创建多个组件吗?**
+A: 不可以,必须串行执行。等上一个 `+dashboard-block-create` 完成后再执行下一个。
+
+**Q: 组件的 `type` 创建后能改吗?**
+A: 不能。`+dashboard-block-update` 只能修改 `name` 和 `data_config`,不能修改 `type`。
+
+**Q: 更新组件的命令和 data_config 怎么写?**
+A:
+1. 先读 [lark-base-dashboard-block-update.md](lark-base-dashboard-block-update.md) 了解更新参数
+2. 再读 [dashboard-block-data-config.md](dashboard-block-data-config.md) 了解 data_config 结构
+
+**data_config 更新策略(顶层 key merge)**:
+- 只传入需要修改的顶层字段(如 `series`、`filter`)
+- 未传的顶层字段(如 `group_by`)自动保留原值
+- 但每个传入的字段内部是**全量替换**(如传新 `filter` 会完整覆盖旧 `filter`)
+
+**Q: 查看已有组件有什么用?**
+A: 在「添加新组件」或「编辑组件」前查看已有组件可以:
+- 了解当前仪表盘已有哪些可视化
+- 避免重复创建相似的组件
+- 参考已有组件的 data_config 结构作为模板
+
+## 命令详细文档
+
+| CLI 命令 | 说明 | 详细文档 |
+|----------|------|----------|
+| `+dashboard-list` | 列出所有仪表盘 | [lark-base-dashboard-list.md](lark-base-dashboard-list.md) |
+| `+dashboard-get` | 获取仪表盘详情(含所有组件)| [lark-base-dashboard-get.md](lark-base-dashboard-get.md) |
+| `+dashboard-create` | 创建仪表盘 | [lark-base-dashboard-create.md](lark-base-dashboard-create.md) |
+| `+dashboard-update` | 修改仪表盘 | [lark-base-dashboard-update.md](lark-base-dashboard-update.md) |
+| `+dashboard-delete` | 删除仪表盘 | [lark-base-dashboard-delete.md](lark-base-dashboard-delete.md) |
+| `+dashboard-arrange` | 智能重排布局 | [lark-base-dashboard-arrange.md](lark-base-dashboard-arrange.md) |
+| `+dashboard-block-list` | 列出组件 | [lark-base-dashboard-block-list.md](lark-base-dashboard-block-list.md) |
+| `+dashboard-block-get` | 获取单个组件详情 | [lark-base-dashboard-block-get.md](lark-base-dashboard-block-get.md) |
+| `+dashboard-block-create` | 创建组件 | [lark-base-dashboard-block-create.md](lark-base-dashboard-block-create.md) |
+| `+dashboard-block-update` | 更新组件 | [lark-base-dashboard-block-update.md](lark-base-dashboard-block-update.md) |
+| `+dashboard-block-delete` | 删除组件 | [lark-base-dashboard-block-delete.md](lark-base-dashboard-block-delete.md) |

+ 375 - 0
.agents/skills/lark-base/references/lark-base-data-query.md

@@ -0,0 +1,375 @@
+
+# base +data-query
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+对多维表格数据进行聚合查询(分组、过滤、排序、聚合计算),基于以下语法的 JSON DSL:
+
+## 限制
+
+- **权限要求**:调用者必须是目标多维表格的管理员,它才能拥有目标多维表格的 **FA(Full Access / 完全访问权限)**,否则返回权限错误
+- **支持的字段类型**(白名单,仅以下类型可用于 dimensions / measures / filters / sort):
+  文本、邮箱、条码、数字、进度、货币、评分、单选、多选、日期、复选框、人员、超链接
+- **不支持的字段类型**:公式、查找引用、附件、时长、阶段、创建时间、修改时间、创建人、修改人、群组、电话号码、自动编号、地理位置、关联、双向关联 —— 不可用于 dimensions / measures / filters / sort,使用会返回校验错误
+
+## 推荐命令
+
+```bash
+# 按字段分组计数
+lark-cli base +data-query \
+  --base-token MAGObxxxxx \
+  --dsl '{
+    "datasource": {"type": "table", "table": {"tableId": "tblxxxxxxxx"}},
+    "dimensions": [{"field_name": "城市", "alias": "dim_city"}],
+    "measures": [{"field_name": "城市", "aggregation": "count", "alias": "count"}],
+    "shaper": {"format": "flat"}
+  }'
+
+# 带过滤条件 + 排序 + 限制条数
+lark-cli base +data-query \
+  --base-token MAGObxxxxx \
+  --dsl '{
+    "datasource": {"type": "table", "table": {"tableId": "tblxxxxxxxx"}},
+    "dimensions": [{"field_name": "城市", "alias": "dim_city"}],
+    "measures": [{"field_name": "金额", "aggregation": "sum", "alias": "total_amount"}],
+    "filters": {
+      "type": 1,
+      "conjunction": "and",
+      "conditions": [{"field_name": "城市", "operator": "isNot", "value": [""]}]
+    },
+    "sort": [{"field_name": "total_amount", "order": "desc"}],
+    "pagination": {"limit": 100},
+    "shaper": {"format": "flat"}
+  }'
+
+# 使用 tableName(表名)代替 tableId
+lark-cli base +data-query \
+  --base-token MAGObxxxxx \
+  --dsl '{
+    "datasource": {"type": "table", "table": {"tableName": "销售数据"}},
+    "measures": [{"field_name": "金额", "aggregation": "sum", "alias": "total"}],
+    "shaper": {"format": "flat"}
+  }'
+```
+
+## 参数
+
+| 参数                     | 必填 | 说明 |
+|------------------------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App Token(base_token) |
+| `--dsl <json>`         | 是 | LiteQuery Protocol JSON DSL 查询语句 |
+
+## 如何从链接中提取参数
+
+用户通常会提供如下 URL:
+
+```
+https://example.feishu.cn/base/<app_token>?table=<table_id>
+```
+
+- `--base-token`:取 `/base/` 后面的字符串
+- DSL 中的 `tableId`:取 `table=` 后面的值
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/data/query
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 App Token |
+
+**Request Body — DSL 结构:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `datasource` | object | 是 | 数据源,包含 `type`(固定 `"table"`)和 `table` 对象 |
+| `datasource.table.tableId` | string | 二选一 | 目标数据表 ID |
+| `datasource.table.tableName` | string | 二选一 | 目标数据表名称 |
+| `dimensions` | Dimension[] | 否* | 分组维度字段(GROUP BY) |
+| `measures` | Measure[] | 否* | 聚合度量字段 |
+| `filters` | FilterGroup | 否 | 过滤条件(WHERE) |
+| `sort` | Sort[] | 否 | 排序规则 |
+| `pagination` | object | 否 | 限制返回行数,`{limit: N}`,最大 5000 |
+| `shaper` | object | 否 | 结果格式,固定 `{format: "flat"}` |
+
+> \* `dimensions` 和 `measures` 至少填写一个。
+
+**Dimension 字段:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `field_name` | string | 是 | 字段名称 |
+| `alias` | string | 否 | 输出列别名,需全局唯一 |
+
+**Measure 字段:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `field_name` | string | 是 | 字段名称 |
+| `aggregation` | string | 是 | 聚合函数:`sum`、`avg`、`min`、`max`、`count`、`count_all`、`distinct_count` |
+| `alias` | string | 否 | 输出列别名,需全局唯一 |
+
+**聚合函数适用字段类型:**
+
+| 聚合函数 | 适用字段类型 |
+|----------|-------------|
+| `sum` / `avg` | 数字、进度、货币、评分(不含复选框) |
+| `min` / `max` | 数字、进度、货币、评分、日期 |
+| `count` | 白名单内所有类型,计数非空值 |
+| `count_all` | 白名单内所有类型,计数所有行 |
+| `distinct_count` | 白名单内所有类型 |
+
+**FilterGroup:**
+
+```json
+{
+  "filters": {
+    "type": 1,
+    "conjunction": "and",
+    "conditions": [
+      {"field_name": "城市", "operator": "is", "value": ["北京"]}
+    ]
+  }
+}
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `type` | int | 是 | 固定填 `1` |
+| `conjunction` | string | 否 | 条件组合逻辑:`"and"` 或 `"or"`,默认 `"and"` |
+| `conditions` | Condition[] | 否 | 条件列表 |
+
+**Condition:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `field_name` | string | 是 | 字段名称(必须与表中字段名精确匹配) |
+| `operator` | string | 是 | 运算符(见下方运算符表) |
+| `value` | string[] | 是 | 条件值数组;`isEmpty`/`isNotEmpty` 时**必须**传空数组 `[]` |
+
+**运算符:**
+
+| 运算符 | 说明 |
+|--------|------|
+| `is` | 等于 |
+| `isNot` | 不等于 |
+| `contains` | 包含 |
+| `doesNotContain` | 不包含 |
+| `isEmpty` | 为空 |
+| `isNotEmpty` | 不为空 |
+| `isGreater` | 大于 |
+| `isGreaterEqual` | 大于等于 |
+| `isLess` | 小于 |
+| `isLessEqual` | 小于等于 |
+
+> 各运算符的适用字段类型见下方「按各字段类型筛选时 value 格式详解」。
+
+**按各字段类型筛选时 value 格式详解:**
+
+*文本 / 邮箱 / 条码*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` / `isNot` / `contains` / `doesNotContain` | `["文本内容"]` | 仅 1 个 | `["Hello"]` |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]` |
+
+*数字 / 货币*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` / `isNot` / `isGreater` / `isGreaterEqual` / `isLess` / `isLessEqual` | `["数字字符串"]` | 仅 1 个 | `["23.4"]`、`["-100"]` |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]` |
+
+> value 必须为合法数字的字符串形式。
+
+*进度*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` / `isNot` / `isGreater` / `isGreaterEqual` / `isLess` / `isLessEqual` | `["小数字符串"]` | 仅 1 个 | `["0.34"]`(= 34%) |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]` |
+
+> **用小数表示百分比**:`["0.34"]` 表示 34%,不是 `["34"]`。
+
+*评分*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` / `isNot` / `isGreater` / `isGreaterEqual` / `isLess` / `isLessEqual` | `["数字字符串"]` | 仅 1 个 | `["4"]` |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]` |
+
+*单选 / 多选*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` / `isNot` | `["选项名"]` | **仅 1 个** | `["选项A"]` |
+| `contains` / `doesNotContain` | `["选项A", "选项B"]` | 可多个 | `["选项A", "选项B"]` |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]` |
+
+*人员*
+
+| 运算符 | value 格式 | 元素个数 | 示例                     |
+|--------|-----------|---------|------------------------|
+| `is` / `isNot` | `["用户ID"]` | **仅 1 个** | `["ou_aaa"]`           |
+| `contains` / `doesNotContain` | `["用户ID1", "用户ID2"]` | 可多个 | `["ou_aaa", "ou_bbb"]` |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]`                   |
+
+> 用户 ID 使用 `open_id`(`ou_` 前缀),接口层会自动做 ID 转换。
+
+*超链接*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` / `isNot` / `contains` / `doesNotContain` | `["链接显示名称"]` | 仅 1 个 | `["点击查看"]` |
+| `isEmpty` / `isNotEmpty` | `[]` | 0 个 | `[]` |
+
+> **按显示名称筛选**,不是按 URL 本身。
+
+*复选框*
+
+| 运算符 | value 格式 | 元素个数 | 示例 |
+|--------|-----------|---------|------|
+| `is` | `["true"]` 或 `["false"]` | 仅 1 个 | `["true"]` |
+
+> 仅支持 `is` 运算符,不支持其他运算符。
+
+*日期*
+
+日期字段仅支持 `is`、`isEmpty`、`isNotEmpty`、`isGreater`、`isLess` 五种运算符。
+
+value 使用预定义关键字机制,第一个元素为字符串常量名称:
+
+| 关键字 | 说明 | value 格式 | 支持的运算符 |
+|--------|------|-----------|-------------|
+| `ExactDate` | 精确日期 | `["ExactDate", "1773187200000"]`(毫秒时间戳) | `is`、`isGreater`、`isLess` |
+| `Today` | 今天 | `["Today"]` | `is`、`isGreater`、`isLess` |
+| `Tomorrow` | 明天 | `["Tomorrow"]` | `is`、`isGreater`、`isLess` |
+| `Yesterday` | 昨天 | `["Yesterday"]` | `is`、`isGreater`、`isLess` |
+| `CurrentWeek` | 本周 | `["CurrentWeek"]` | 仅 `is` |
+| `LastWeek` | 上周 | `["LastWeek"]` | 仅 `is` |
+| `CurrentMonth` | 本月 | `["CurrentMonth"]` | 仅 `is` |
+| `LastMonth` | 上月 | `["LastMonth"]` | 仅 `is` |
+| `TheLastWeek` | 过去七天 | `["TheLastWeek"]` | 仅 `is` |
+| `TheNextWeek` | 未来七天 | `["TheNextWeek"]` | 仅 `is` |
+| `TheLastMonth` | 过去三十天 | `["TheLastMonth"]` | 仅 `is` |
+| `TheNextMonth` | 未来三十天 | `["TheNextMonth"]` | 仅 `is` |
+
+> - **ExactDate 时区行为**:毫秒时间戳在实际筛选时会被转为**文档时区当天零点**,跨时区场景需注意日期可能偏移一天。
+> - **范围型关键字**(`CurrentWeek`、`LastWeek`、`CurrentMonth`、`LastMonth`、`TheLastWeek`、`TheNextWeek`、`TheLastMonth`、`TheNextMonth`)仅支持 `is` 运算符。
+> - **关键字大小写敏感**:`ExactDate`、`Today`、`CurrentWeek` 等首字母大写,写错大小写会导致校验失败。
+
+**Sort 字段:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `field_name` | string | 是 | 字段名称或 alias |
+| `order` | string | 否 | `"asc"`(默认)或 `"desc"` |
+
+**Pagination 字段:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `limit` | int | 否 | 返回记录数上限,必须为正整数,最大 5000;不填时使用系统默认值。不支持 offset |
+
+**Shaper 字段:**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `format` | string | 是 | 固定为 `"flat"`,表示返回扁平化的对象数组 |
+
+## API 出参详情
+
+**成功时:**
+
+```json
+{"code": 0, "data": {"main_data": [{"dim_city": {"value": "北京"}, "total_amount": {"value": 12345.00}}, ...]}, "msg": ""}
+```
+
+**失败时:**
+
+```json
+{"code": 800004006, "data": {"error": {"code": 800004006, ...}}, "msg": "DSL validation failed"}
+```
+
+**Response 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | int | 状态码,0 为成功 |
+| `msg` | string | 错误信息 |
+| `data.main_data` | []object | 查询结果数组,每个元素为一行数据 |
+| `data.error` | object | 失败时的错误详情 |
+
+每行数据的字段值封装在 CellValue 中:
+
+```json
+{
+  "dim_city": {
+    "value": "北京"
+  },
+  "total_amount": {
+    "value": 12345.00
+  }
+}
+```
+
+- `value`:展示值(人员名称、选项名称、格式化日期等)
+
+## 返回值
+
+命令成功后输出 `data` 字段的内容:
+
+```json
+{
+  "main_data": [
+    {
+      "dim_city": {"value": "直营"},
+      "measure_count": {"value": 1}
+    },
+    {
+      "dim_city": {"value": "加盟"},
+      "measure_count": {"value": 2}
+    }
+  ]
+}
+```
+
+## 工作流
+
+1. 确认 base-token 和 table-id
+2. **先查表结构**:执行 `lark-cli base app.table.fields list --params '{"app_token":"<token>","table_id":"<id>"}'`
+3. 从返回的字段列表中:
+   - 获取 field_name(DSL 中使用的字段名称)
+   - 仅选择白名单内的字段类型(见「限制」章节),排除公式、查找引用、附件等不支持的字段
+4. 根据字段信息构造 DSL JSON
+5. 执行 +data-query
+6. 解读返回结果:
+   - 结果在 `data.main_data` 数组中,每个元素代表一行
+   - 每行对象的 key 为 DSL 中指定的 `alias`;未指定 alias 时,key 为自动生成的列名
+   - 每个 value 是 CellValue 对象,实际值在 `value` 字段中,如 `{"value": "北京"}` 或 `{"value": 12345.00}`
+   - 失败时结果在 `data.error` 中,包含具体错误码和信息
+
+## 坑点
+
+- ⚠️ **必须先查表结构**:DSL 的 `field_name` 必须与表中字段名称精确匹配(区分大小写),不能凭猜测构造。先用 `base app.table.fields list` 获取真实字段名
+- ⚠️ **权限要求 FA**:调用者必须是目标多维表格的管理员,它才能拥有目标多维表格的 **FA(Full Access / 完全访问权限)**,否则返回权限错误
+- ⚠️ **alias 不支持中文**:dimensions 和 measures 的 alias 必须使用英文(如 `dim_city`、`total_amount`),中文 alias 会导致错误
+- ⚠️ **API 路径是 `base/v3`**:本接口路径为 `/open-apis/base/v3/bases/:base_token/data/query`,不是 `bitable/v1`。两者完全不同,用错版本号会返回 `[2200] Internal Error`
+- ⚠️ **`dimensions` 和 `measures` 至少填一个**:两个都不填会返回 DSL 校验错误
+- ⚠️ **`shaper` 必须为 `{"format": "flat"}`**:不填或填其他值会导致结果格式不可预期,建议始终显式指定
+- ⚠️ **数据表标识 `tableId` vs `tableName`**:datasource 中可以用 `tableId`(如 `tblXXX`)或 `tableName`(数据表的用户自定义显示名称),二选一,不要混用
+- ⚠️ **`pagination.limit` 最大 5000**:超过会报错,且不支持 offset,只支持 limit
+- ⚠️ **所有 alias 必须全局唯一**:dimensions 和 measures 之间的 alias 也不能重名
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数
+- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — shortcut 字段值格式规范
+- [lark-base-shortcut-field-properties.md](lark-base-shortcut-field-properties.md) — shortcut 字段类型与 JSON 结构

+ 104 - 0
.agents/skills/lark-base/references/lark-base-field-create.md

@@ -0,0 +1,104 @@
+# base +field-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+创建一个字段。
+
+## Agent 最小工作流
+
+1. 先判断是不是 `formula` / `lookup`。
+2. 如果是:先读对应 guide。
+3. 没读 guide 前,不要直接创建 formula / lookup 字段。
+4. 读完 guide 后,再构造 `--json` 并创建字段。
+5. 如果是跨表 formula / lookup,再补查**目标表**的结构。
+
+## 推荐命令
+
+```bash
+lark-cli base +field-create \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --json '{"name":"预算","type":"number","precision":2}' 
+
+lark-cli base +field-create \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --json '{"name":"状态","type":"select","multiple":false,"options":[{"name":"Todo","hue":"Blue","lightness":"Lighter"},{"name":"Done","hue":"Green","lightness":"Light"}]}'
+
+lark-cli base +field-create \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --json '{"name":"负责人","type":"user","multiple":false,"description":"用于标记记录的直接负责人;协作约定可参考[团队字段约定](https://example.com/field-spec)"}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--json <body>` | 是 | 字段属性 JSON 对象 |
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/tables/:table_id/fields
+```
+
+## JSON 值规范
+
+- `--json` 必须是 **JSON 对象**,顶层直接传字段定义,不要再套一层。
+- 顶层最少包含:`name`、`type`。
+- 如需字段说明,直接传 `description`;支持纯文本,也支持 Markdown 链接,如 `协作约定可参考[团队字段约定](https://example.com/field-spec)`。
+- `type` 不同,必填子字段不同:
+  - `select`:用 `multiple` + `options`(`options` 里只传 `name/hue/lightness`,不要传 `id`)。
+  - `link`:必须有 `link_table`,可选 `bidirectional`、`bidirectional_link_field_name`。
+  - `formula`:必须有 `expression`;先读 formula guide,再创建。
+  - `lookup`:必须有 `from`、`select`、`where`;先读 lookup guide,再创建。
+
+**正确(base +field-create)**
+
+```json
+{
+  "name": "状态",
+  "type": "select",
+  "multiple": false,
+  "options": [
+    { "name": "Todo", "hue": "Blue", "lightness": "Lighter" },
+    { "name": "Done", "hue": "Green", "lightness": "Light" }
+  ]
+}
+```
+
+**字段说明示例**
+
+```json
+{
+  "name": "负责人",
+  "type": "user",
+  "multiple": false,
+  "description": "用于标记记录的直接负责人;协作约定可参考[团队字段约定](https://example.com/field-spec)"
+}
+```
+
+## 返回重点
+
+- 返回 `field` 和 `created: true`。
+
+## 工作流
+
+
+1. formula / lookup 字段必须先阅读对应指南;没读之前不要直接创建。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 当 `type` 是 `formula` 或 `lookup` 时,先读对应 guide,再创建。
+
+## 参考
+
+- [lark-base-field.md](lark-base-field.md) — field 索引页
+- [lark-base-shortcut-field-properties.md](lark-base-shortcut-field-properties.md) — shortcut 字段 JSON 规范(推荐)
+- [formula-field-guide.md](formula-field-guide.md) — formula 指南(创建公式必读)
+- [lookup-field-guide.md](lookup-field-guide.md) — lookup 指南(创建查找引用必读)

+ 51 - 0
.agents/skills/lark-base/references/lark-base-field-delete.md

@@ -0,0 +1,51 @@
+# base +field-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+删除一个字段。
+
+## 推荐命令
+
+```bash
+lark-cli base +field-delete \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --field-id fld_xxx \
+  --yes
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--field-id <id_or_name>` | 是 | 字段 ID 或字段名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+DELETE /open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id
+```
+
+## 返回重点
+
+- 返回 `deleted: true` 和目标字段标识。
+
+## 工作流
+
+> 这是**高风险写入操作**。CLI 层要求显式传 `--yes`;如果用户已经明确要求删除且目标明确,直接执行并带上 `--yes`,不要再补一次确认。
+
+1. 建议先用 `+field-get` 或 `+field-list` 确认目标字段。
+2. 只有当字段目标仍不明确时,才继续追问;如果删除意图和目标都明确,直接执行。
+
+## 坑点
+
+- ⚠️ 高风险写操作,删除后不可恢复。
+- ⚠️ 忘记带 `--yes` 会被 CLI 拦截。
+
+## 参考
+
+- [lark-base-field.md](lark-base-field.md) — field 索引页

+ 42 - 0
.agents/skills/lark-base/references/lark-base-field-get.md

@@ -0,0 +1,42 @@
+# base +field-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取一个字段的完整配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +field-get \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --field-id fld_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--field-id <id_or_name>` | 是 | 字段 ID 或字段名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id
+```
+
+## 返回重点
+
+- 返回完整字段配置,适合做更新前的基线。
+
+## 坑点
+
+- ⚠️ 重名字段场景下,建议优先传 `fld_xxx`。
+
+## 参考
+
+- [lark-base-field.md](lark-base-field.md) — field 索引页

+ 44 - 0
.agents/skills/lark-base/references/lark-base-field-list.md

@@ -0,0 +1,44 @@
+# base +field-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+分页列出一张表下的字段。
+
+## 推荐命令
+
+```bash
+lark-cli base +field-list \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --offset 0 \
+  --limit 100
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--offset <n>` | 否 | 分页偏移,默认 `0` |
+| `--limit <n>` | 否 | 分页大小,默认 `100`,范围 `1-200` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/fields
+```
+
+## 返回重点
+
+- 返回字段列表及 `offset / limit / count / total`。
+
+## 坑点
+
+- ⚠️ `+field-list` 禁止并发调用;批量列多个表字段时只能串行。
+
+## 参考
+
+- [lark-base-field.md](lark-base-field.md) — field 索引页

+ 48 - 0
.agents/skills/lark-base/references/lark-base-field-search-options.md

@@ -0,0 +1,48 @@
+# base +field-search-options
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+搜索单选 / 多选字段的候选项。
+
+## 推荐命令
+
+```bash
+lark-cli base +field-search-options \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --field-id fld_status \
+  --keyword 已完成 \
+  --offset 0 \
+  --limit 30
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--field-id <id_or_name>` | 是 | 字段 ID 或字段名 |
+| `--keyword <text>` | 否 | 查询关键字;会映射到 API 的 `query` |
+| `--offset <n>` | 否 | 分页偏移,默认 `0` |
+| `--limit <n>` | 否 | 分页大小,默认 `30` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id/options
+```
+
+## 返回重点
+
+- 返回 `options`、`total`、以及回显的 `field_id / field_name / keyword`。
+
+## 坑点
+
+- ⚠️ 只适用于带选项集的字段;普通文本 / 数字字段没有可搜索选项。
+
+## 参考
+
+- [lark-base-field.md](lark-base-field.md) — field 索引页

+ 97 - 0
.agents/skills/lark-base/references/lark-base-field-update.md

@@ -0,0 +1,97 @@
+# base +field-update
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新一个已有字段。
+
+## 推荐命令
+
+```bash
+lark-cli base +field-update \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --field-id fld_xxx \
+  --json '{"name":"状态","type":"select","multiple":false,"options":[{"name":"Todo","hue":"Blue","lightness":"Lighter"},{"name":"Doing","hue":"Orange","lightness":"Light"},{"name":"Done","hue":"Green","lightness":"Light"}]}'
+
+lark-cli base +field-update \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --field-id fld_xxx \
+  --json '{"name":"负责人","type":"user","multiple":false,"description":"用于标记记录的直接负责人;协作约定可参考[团队字段约定](https://example.com/field-spec)"}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--field-id <id_or_name>` | 是 | 字段 ID 或字段名 |
+| `--json <body>` | 是 | 字段属性 JSON 对象 |
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/fields/:field_id
+```
+
+## JSON 值规范
+
+- `--json` 必须是 **JSON 对象**,顶层直接传字段定义。
+- 更新语义是 `PUT`(全量字段配置更新),不要只传零散片段;至少显式包含 `name`、`type`,并补齐该类型所需关键配置。
+- 如需字段说明,直接传 `description`;支持纯文本,也支持 Markdown 链接,如 `协作约定可参考[团队字段约定](https://example.com/field-spec)`。
+- `select` 更新时:`options` 仍按对象数组传,避免混入无效字段。
+- `link` 更新限制:
+  - 不能把非 `link` 字段改成 `link`,也不能把 `link` 改成非 `link`。
+  - 现有 `link` 字段的 `bidirectional` 不能改。
+
+**推荐更新示例**
+
+```json
+{
+  "name": "状态",
+  "type": "select",
+  "multiple": false,
+  "options": [
+    { "name": "Todo", "hue": "Blue", "lightness": "Lighter" },
+    { "name": "Doing", "hue": "Orange", "lightness": "Light" },
+    { "name": "Done", "hue": "Green", "lightness": "Light" }
+  ]
+}
+```
+
+**字段说明示例**
+
+```json
+{
+  "name": "负责人",
+  "type": "user",
+  "multiple": false,
+  "description": "用于标记记录的直接负责人;协作约定可参考[团队字段约定](https://example.com/field-spec)"
+}
+```
+
+## 返回重点
+
+- 返回 `field` 和 `updated: true`。
+
+## 工作流
+
+
+1. 建议先用 `+field-get` 拉现状,再做最小化修改。
+2. `formula/lookup` 类型更新前先阅读对应指南。
+
+## 坑点
+
+- ⚠️ 这是全量字段属性更新语义,不是 patch。
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 当 `type` 是 `formula` 或 `lookup` 时,先阅读对应指南再执行。
+
+## 参考
+
+- [lark-base-field.md](lark-base-field.md) — field 索引页
+- [lark-base-field-get.md](lark-base-field-get.md) — 查字段
+- [lark-base-shortcut-field-properties.md](lark-base-shortcut-field-properties.md) — shortcut 字段 JSON 规范(推荐)
+- [formula-field-guide.md](formula-field-guide.md) — formula 指南(更新公式前必读)
+- [lookup-field-guide.md](lookup-field-guide.md) — lookup 指南(更新查找引用前必读)

+ 22 - 0
.agents/skills/lark-base/references/lark-base-field.md

@@ -0,0 +1,22 @@
+# base field shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+field 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-field-list.md](lark-base-field-list.md) | `+field-list` | 分页列字段 |
+| [lark-base-field-get.md](lark-base-field-get.md) | `+field-get` | 获取单字段配置 |
+| [lark-base-field-create.md](lark-base-field-create.md) | `+field-create` | 创建字段 |
+| [lark-base-field-update.md](lark-base-field-update.md) | `+field-update` | 更新字段 |
+| [lark-base-field-search-options.md](lark-base-field-search-options.md) | `+field-search-options` | 搜索选项字段候选值 |
+| [lark-base-field-delete.md](lark-base-field-delete.md) | `+field-delete` | 删除字段 |
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。
+- 写字段 JSON 前优先阅读 [lark-base-shortcut-field-properties.md](lark-base-shortcut-field-properties.md)。

+ 87 - 0
.agents/skills/lark-base/references/lark-base-form-create.md

@@ -0,0 +1,87 @@
+# base +form-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+在多维表格数据表中创建新表单。
+
+## ⚠️ 注意事项
+
+- **表格选择**:创建问卷前先考虑:这是新的业务领域吗?如果是,建议先用 `+table-create` 创建新表格
+- **命名一致性**:问卷名称应与表格用途相关,避免在通用表格(如"收集表")中创建不相关的问卷
+
+## 命令
+
+```bash
+# 创建表单(仅必填参数)
+lark-cli base +form-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --name "用户调研问卷"
+
+# 创建时附带描述(纯文本)
+lark-cli base +form-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --name "用户调研问卷" \
+  --description "2024年度用户满意度调研"
+
+# 创建时附带描述(含链接)
+lark-cli base +form-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --name "用户调研问卷" \
+  --description "2024年度调研,[详情请查看](https://example.com)"
+
+# 使用应用身份(bot)
+lark-cli base +form-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --name "用户调研问卷" \
+  --as bot
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--name <name>` | 是 | 表单名称 |
+| `--description <string>` | 否 | 表单描述(纯文本或 Markdown 链接,如 `[文本](https://example.com)`) |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 输出格式
+
+| 字段 | 说明 |
+|------|------|
+| `id` | 新创建的表单 ID |
+| `name` | 表单名称 |
+| `description` | 表单描述 |
+
+```json
+{
+  "ok": true,
+  "data": {
+    "id": "vewX58te9D",
+    "name": "用户调研问卷",
+    "description": "2024年度用户满意度调研"
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 确认目标 `app_token` 和 `table_id`
+2. 确认表单名称和描述
+3. 执行命令
+4. 报告返回的 `form_id`,后续可用于添加问题(`+form-questions-create`)
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 64 - 0
.agents/skills/lark-base/references/lark-base-form-delete.md

@@ -0,0 +1,64 @@
+# base +form-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+删除多维表格数据表中的指定表单。**不可逆操作**,执行前务必确认。
+
+## 命令
+
+```bash
+# 删除表单
+lark-cli base +form-delete \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id>
+
+# 预览(不实际执行)
+lark-cli base +form-delete \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --dry-run
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 要删除的表单 ID |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 输出格式
+
+```json
+{
+  "ok": true,
+  "data": {
+    "deleted": true,
+    "form_id": "vewX58te9D"
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**高风险写入操作(删除)** — 执行前必须明确向用户确认,告知此操作不可逆。
+
+1. 先用 `+form-list` 或 `+form-get` 确认目标表单存在
+2. 向用户展示将要删除的表单名称和 ID,等待明确确认
+3. 执行删除
+4. 报告删除结果
+
+## 提示
+
+- 删除前建议先用 `+form-questions-list` 了解表单内容,避免误删
+- `form_id` 可通过 `+form-list` 查询
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 68 - 0
.agents/skills/lark-base/references/lark-base-form-get.md

@@ -0,0 +1,68 @@
+# base +form-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取多维表格数据表中指定表单的详情。只读操作,不修改任何数据。
+
+## 命令
+
+```bash
+# 获取表单详情
+lark-cli base +form-get \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id>
+
+# 以 pretty 格式展示
+lark-cli base +form-get \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --format pretty
+
+# 使用应用身份(bot)
+lark-cli base +form-get \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --as bot
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 表单 ID |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 输出格式
+
+| 字段 | 说明 |
+|------|------|
+| `id` | 表单 ID |
+| `name` | 表单名称 |
+| `description` | 表单描述 |
+
+```json
+{
+  "ok": true,
+  "data": {
+    "id": "vewX58te9D",
+    "name": "用户调研问卷",
+    "description": "2024年度用户满意度调研"
+  }
+}
+```
+
+## 提示
+
+- `form_id` 可通过 `lark-cli base +form-list --base-token <token> --table-id <id>` 获取
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 73 - 0
.agents/skills/lark-base/references/lark-base-form-list.md

@@ -0,0 +1,73 @@
+# base +form-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+列出多维表格数据表中的所有表单。自动翻页,一次性返回全量结果。只读操作,不修改任何数据。
+
+## 命令
+
+```bash
+# 列出指定数据表的所有表单
+lark-cli base +form-list \
+  --base-token <base_token> \
+  --table-id <table_id>
+
+# 以表格形式展示
+lark-cli base +form-list \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --format table
+
+# 使用应用身份(bot)
+lark-cli base +form-list \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --as bot
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--page-size <n>` | 否 | 每次请求的分页大小,默认 100,最大 100 |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 输出格式
+
+每条表单包含以下字段:
+
+| 字段 | 说明 |
+|------|------|
+| `id` | 表单 ID(如 `vewX58te9D`) |
+| `name` | 表单名称 |
+| `description` | 表单描述 |
+
+JSON 输出示例(`--format json`,默认):
+
+```json
+{
+  "ok": true,
+  "data": {
+    "forms": [
+      {"id": "vewX58te9D", "name": "用户调研问卷", "description": "..."},
+      {"id": "form_yyyy",  "name": "产品反馈表",   "description": "..."}
+    ],
+    "total": 2
+  }
+}
+```
+
+## 提示
+
+- `base_token` 在多维表格 URL 中可找到(形如 `bascnXXXX`)
+- `table_id` 可通过 `lark-cli base app.tables list --app-token <token> --params '{"app_token":"<token>"}'` 获取
+- 如无表单,输出 `forms: []`
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 118 - 0
.agents/skills/lark-base/references/lark-base-form-questions-create.md

@@ -0,0 +1,118 @@
+# base +form-questions-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+向多维表格表单/问卷中批量添加问题。
+
+## 命令
+
+```bash
+# 添加一个文本必填问题
+lark-cli base +form-questions-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"type":"text","title":"您的姓名是?","required":true}]'
+
+# 添加多个问题(按顺序排列)
+lark-cli base +form-questions-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[
+    {"type":"text","title":"您的姓名是?","required":true},
+    {"type":"text","title":"您的联系方式是?","required":false}
+  ]'
+
+# 添加单选题(带选项)
+lark-cli base +form-questions-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"type":"select","title":"满意度评价","required":true,"multiple":false,"options":[{"name":"非常满意","hue":"Green"},{"name":"满意","hue":"Blue"},{"name":"一般","hue":"Yellow"}]}]'
+
+# 添加评分题
+lark-cli base +form-questions-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"type":"number","title":"服务评分","style":{"type":"rating","icon":"star","min":1,"max":5}}]'
+  
+# 添加带描述的问题(纯文本)
+lark-cli base +form-questions-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"type":"text","title":"您的姓名","description":"请填写真实姓名"}]'
+# 添加带描述的问题(含链接)
+lark-cli base +form-questions-create \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"type":"text","title":"反馈建议","description":"更多详情请查看[帮助文档](https://example.com/help)"}]'  
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 表单 ID |
+| `--questions <json>` | 是 | 问题 JSON 数组,最多 10 个(见下方格式) |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## `--questions` 格式
+
+每个问题对象支持以下字段:
+
+| 字段                    | 必填 | 说明 |
+|-----------------------|------|------|
+| `title`               | **是** | 问题标题(字段名) |
+| `type`                | **是** | 题目类型:`text`、`number`、`select`、`datetime`、`user`、`attachment`、`location` |
+| `description`         | 否 | 问题描述(纯文本或 Markdown 链接,如 `[文本](https://example.com)`) |
+| `required`            | 否 | 是否必填(true/false) |
+| `option_display_mode` | 否 | 选项展示方式(仅 `select` 有效):`0`=下拉,`1`=纵向(默认),`2`=横向 |
+| `multiple`            | 否 | 是否多选(`select`/`user` 类型有效,bool) |
+| `options`             | 否 | 选项列表(仅 `select` 有效):`[{"name":"选项1","hue":"Blue"}]`,hue 可选:`Red`/`Orange`/`Yellow`/`Green`/`Blue`/`Purple`/`Gray` |
+| `style`               | 否 | 字段样式配置(见下方说明) |
+
+### `style` 字段说明
+
+| 类型 | style 结构 | 说明 |
+|------|------|------|
+| `text` | `{"type":"plain"}` | type 可选:`plain`(纯文本)、`phone`(电话)、`url`(链接)、`email`(邮件)、`barcode`(扫码) |
+| `number` | `{"type":"plain","precision":2}` | precision 为小数位数 |
+| `number`(评分) | `{"type":"rating","icon":"star","min":1,"max":5}` | icon 可选:`star`/`heart`/`thumbsup`/`fire`/`smile`/`lightning`/`flower`/`number` |
+| `datetime` | `{"type":"plain","format":"yyyy/MM/dd"}` | format 可选:`yyyy/MM/dd`、`yyyy/MM/dd HH:mm`、`MM-dd`、`MM/dd/yyyy`、`dd/MM/yyyy` |
+
+## 输出格式
+
+返回创建成功的问题列表:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "items": [
+      {"id": "q_001", "title": "您的姓名是?", "required": true}
+    ]
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 先用 `+form-questions-list` 查看现有问题
+2. 确认要添加的问题内容
+3. 执行命令并报告新建的问题 ID
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 68 - 0
.agents/skills/lark-base/references/lark-base-form-questions-delete.md

@@ -0,0 +1,68 @@
+# base +form-questions-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+从多维表格表单中批量删除问题。**不可逆操作**,执行前务必确认。
+
+## 命令
+
+```bash
+# 删除一个问题
+lark-cli base +form-questions-delete \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --question-ids '["q_001"]'
+
+# 批量删除多个问题
+lark-cli base +form-questions-delete \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --question-ids '["q_001","q_002","q_003"]'
+
+# 预览(不实际执行)
+lark-cli base +form-questions-delete \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --question-ids '["q_001"]' \
+  --dry-run
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 表单 ID |
+| `--question-ids <json>` | 是 | 要删除的问题 ID JSON 数组,最多 10 个,如 `'["q_001","q_002"]'` |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 输出格式
+
+```json
+{
+  "ok": true,
+  "data": {
+    "deleted": true,
+    "question_ids": ["q_001", "q_002"]
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**高风险写入操作(删除)** — 执行前必须明确向用户确认,告知此操作不可逆。
+
+1. 先用 `+form-questions-list` 查看问题列表,确认要删除的 `id`
+2. 向用户展示将要删除的问题标题和 ID,等待明确确认
+3. 执行删除并报告结果
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 84 - 0
.agents/skills/lark-base/references/lark-base-form-questions-list.md

@@ -0,0 +1,84 @@
+# base +form-questions-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+列出多维表格表单/问卷中的所有问题。只读操作,不修改任何数据。
+
+## 命令
+
+```bash
+# 列出表单所有问题
+lark-cli base +form-questions-list \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id>
+
+# 以表格形式展示
+lark-cli base +form-questions-list \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --format table
+
+# 使用应用身份(bot)
+lark-cli base +form-questions-list \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --as bot
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 表单 ID |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 输出格式
+
+每条问题包含以下字段:
+
+| 字段 | 说明 |
+|------|------|
+| `id` | 问题 ID(即数据表的 field_id) |
+| `title` | 问题标题 |
+| `description` | 问题描述 |
+| `required` | 是否必填 |
+
+```json
+{
+  "ok": true,
+  "data": {
+    "questions": [
+      {
+        "id": "q_001",
+        "title": "您的姓名是?",
+        "description": "请填写真实姓名",
+        "required": true
+      },
+      {
+        "id": "q_002",
+        "title": "您的联系方式是?",
+        "description": "手机号或邮箱",
+        "required": false
+      }
+    ],
+    "total": 2
+  }
+}
+```
+
+## 提示
+
+- 问题 `id` 与数据表的 `field_id` 相同
+- 返回的问题列表已按顺序排列
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 92 - 0
.agents/skills/lark-base/references/lark-base-form-questions-update.md

@@ -0,0 +1,92 @@
+# base +form-questions-update
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+批量更新多维表格表单/问卷中的问题(标题、描述、是否必填)。
+
+## 命令
+
+```bash
+# 更新一个问题的标题
+lark-cli base +form-questions-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"id":"q_001","title":"您的真实姓名是?"}]'
+
+# 同时更新多个问题
+lark-cli base +form-questions-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[
+    {"id":"q_001","title":"姓名(必填)","required":true},
+    {"id":"q_002","title":"联系方式","required":false}
+  ]'
+  
+# 更新问题描述(纯文本)
+lark-cli base +form-questions-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"id":"q_001","description":"请填写您的真实姓名"}]'
+# 更新问题描述(含链接)
+lark-cli base +form-questions-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --questions '[{"id":"q_001","description":"更多说明请参考[帮助文档](https://example.com/help)"}]'  
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 表单 ID |
+| `--questions <json>` | 是 | 问题更新 JSON 数组,最多 10 个(见下方格式) |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## `--questions` 格式
+
+每个问题对象必须包含 `id`,其余字段按需传入:
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `id` | **是** | 问题 ID(field_id),不可修改 |
+| `title` | 否 | 新的问题标题 |
+| `description` | 否 | 新的问题描述(纯文本或 Markdown 链接,如 `[文本](https://example.com)`) |
+| `required` | 否 | 是否必填 |
+| `option_display_mode` | 否 | 选项展示方式(仅 `select` 有效):`0`=下拉,`1`=纵向(默认),`2`=横向 |
+
+## 输出格式
+
+返回更新后的问题列表:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "items": [
+      {"id": "q_001", "title": "姓名(必填)", "required": true}
+    ]
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 先用 `+form-questions-list` 获取现有问题及其 `id`
+2. 构造包含 `id` 的更新数组
+3. 执行命令并报告更新结果
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 23 - 0
.agents/skills/lark-base/references/lark-base-form-questions.md

@@ -0,0 +1,23 @@
+# base form questions shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+form questions 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-form-questions-list.md](lark-base-form-questions-list.md) | `+form-questions-list` | 列出表单问题 |
+| [lark-base-form-questions-create.md](lark-base-form-questions-create.md) | `+form-questions-create` | 创建表单问题 |
+| [lark-base-form-questions-update.md](lark-base-form-questions-update.md) | `+form-questions-update` | 更新表单问题 |
+| [lark-base-form-questions-delete.md](lark-base-form-questions-delete.md) | `+form-questions-delete` | 删除表单问题 |
+
+## 相关
+
+- [lark-base-form.md](lark-base-form.md) — 表单管理
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。

+ 82 - 0
.agents/skills/lark-base/references/lark-base-form-update.md

@@ -0,0 +1,82 @@
+# base +form-update
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新多维表格数据表中指定表单的名称或描述。
+
+## 命令
+
+```bash
+# 更新表单名称
+lark-cli base +form-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --name "新表单名称"
+
+# 更新描述(纯文本)
+lark-cli base +form-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --description "新的描述内容"
+
+# 更新描述(含链接)
+lark-cli base +form-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --description "新描述,[了解更多](https://example.com)"
+
+# 同时更新名称和描述
+lark-cli base +form-update \
+  --base-token <base_token> \
+  --table-id <table_id> \
+  --form-id <form_id> \
+  --name "新表单名称" \
+  --description "新的描述内容"
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 App token(base_token) |
+| `--table-id <id>` | 是 | 数据表 ID |
+| `--form-id <id>` | 是 | 表单 ID |
+| `--name <name>` | 否 | 新的表单名称 |
+| `--description <string>` | 否 | 新的表单描述(纯文本或 Markdown 链接,如 `[文本](https://example.com)`) |
+| `--format` | 否 | 输出格式:json(默认)\| pretty \| table \| ndjson \| csv |
+| `--as` | 否 | 身份:user(默认)\| bot |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+> `--name` 和 `--description` 至少传一个,否则无实际变更。
+
+## 输出格式
+
+返回更新后的表单信息:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "id": "vewX58te9D",
+    "name": "新表单名称",
+    "description": "新的描述内容"
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 确认 `form_id`(可通过 `+form-list` 获取)
+2. 确认要修改的字段
+3. 执行命令并报告更新后的值
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 24 - 0
.agents/skills/lark-base/references/lark-base-form.md

@@ -0,0 +1,24 @@
+# base form shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+form 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-form-list.md](lark-base-form-list.md) | `+form-list` | 分页列出表单 |
+| [lark-base-form-get.md](lark-base-form-get.md) | `+form-get` | 获取表单详情 |
+| [lark-base-form-create.md](lark-base-form-create.md) | `+form-create` | 创建表单 |
+| [lark-base-form-update.md](lark-base-form-update.md) | `+form-update` | 更新表单 |
+| [lark-base-form-delete.md](lark-base-form-delete.md) | `+form-delete` | 删除表单 |
+
+## 相关
+
+- [lark-base-form-questions.md](lark-base-form-questions.md) — 表单问题(表单字段)管理
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。

+ 16 - 0
.agents/skills/lark-base/references/lark-base-history.md

@@ -0,0 +1,16 @@
+# base history shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+history 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-record-history-list.md](lark-base-record-history-list.md) | `+record-history-list` | 按 `table-id + record-id` 查询记录变更历史 |
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。

+ 76 - 0
.agents/skills/lark-base/references/lark-base-record-batch-create.md

@@ -0,0 +1,76 @@
+# base +record-batch-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+批量创建记录。
+
+## 适用场景(重点)
+
+- 适合大量创建写入场景,例如导入 CSV / Excel、外部系统一次性写入新数据。
+- 当输入是长表格或长文本数据时,先按 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) 做字段映射和类型规范化,再组装 `fields + rows` 调用本命令写入。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-batch-create \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --json '{"fields":["标题","状态"],"rows":[["任务 A","Open"],["任务 B","Done"]]}'
+```
+
+```bash
+lark-cli base +record-batch-create \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --json @batch-create.json
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--json <body>` | 是 | 批量创建请求体,必须是 JSON 对象。支持直接传 JSON 字符串,或 `@<file_path>` 从文件读取 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```http
+POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/batch_create
+```
+
+## `--json` 结构
+
+对象形态:`{"fields":[...],"rows":[...]}`。
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `fields` | `string[]` | 是 | 字段 ID 或字段名数组 |
+| `rows` | `any[][]` | 是 | 二维数组,每一行按 `fields` 同序给值;单次最多 200 行 |
+
+## 返回重点
+
+`data` 为多行二维数组,与 `+record-list` 返回的多行数据结构一致(按 `fields` 列顺序对齐)。
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `fields` | `string[]` | 返回的字段名数组 |
+| `field_id_list` | `string[]` | 返回的字段 ID 数组 |
+| `record_id_list` | `string[]` | 新创建记录 ID 列表 |
+| `data` | `any[][]` | 与 `fields` 对齐的多行数据 |
+| `ignored_fields` | `array` | 可选,表示被忽略的字段信息 |
+
+## 坑点
+
+- ⚠️ `--json` 必须是对象。
+- ⚠️ 写 `rows` 前必须先阅读 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md),按字段类型填值,禁止按自然语言猜测 value 结构。
+- ⚠️ `fields` 与 `rows` 列顺序必须一一对应。
+- ⚠️ 空单元格可以显式用 `null` 填充。
+- ⚠️ 单次最多 200 行,超出需分批写入。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页
+- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — 记录值格式规范

+ 71 - 0
.agents/skills/lark-base/references/lark-base-record-batch-update.md

@@ -0,0 +1,71 @@
+# base +record-batch-update (batch update)
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+批量更新记录(将同一份 `patch` 批量应用到一批 `record_id_list`)。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-batch-update \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --json '{"record_id_list":["recXXX"],"patch":{"field_id_or_name":"value"}}'
+```
+
+```bash
+lark-cli base +record-batch-update \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --json @batch-update.json
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--json <body>` | 是 | 批量更新请求体,必须是 JSON 对象。支持直接传 JSON 字符串,或 `@<file_path>` 从文件读取 |
+
+## 生成 `patch` 前必看
+
+- 先阅读 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md),按字段类型构造 `patch` 的 value,避免类型不匹配。
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```http
+POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/batch_update
+```
+
+## `--json` 结构
+
+对象形态:`{"record_id_list":[...],"patch":{...}}`。
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `record_id_list` | `string[]` | 是 | 要更新的记录 ID 列表(单次最多 200 条) |
+| `patch` | `object` | 是 | 同一份字段更新对象,会应用到 `record_id_list` 内所有记录 |
+
+## 返回重点
+
+返回结构如下(其中 `update` 可与 `+record-list` 的单行字段对象结构对齐):
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `record_id_list` | `string[]` | 本次更新到的记录 ID 列表 |
+| `update` | `object` | 本次应用的字段更新结果;可能为空对象 |
+| `ignored_fields` | `{id,name,reason}[]` | 可选,被忽略字段信息 |
+
+## 坑点
+
+- ⚠️ `--json` 必须是对象。
+- ⚠️ 该接口是“同值批量更新”:同一请求内所有 `record_id_list` 都会应用同一份 `patch`。
+- ⚠️ `record_id_list` 最大 200 条,超过会被接口校验拒绝。
+- ⚠️ 命令不会自动做字段/行映射转换,传什么就发什么。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页

+ 51 - 0
.agents/skills/lark-base/references/lark-base-record-delete.md

@@ -0,0 +1,51 @@
+# base +record-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+删除一条记录。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-delete \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx \
+  --yes
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--record-id <id>` | 是 | 记录 ID |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+DELETE /open-apis/base/v3/bases/:base_token/tables/:table_id/records/:record_id
+```
+
+## 返回重点
+
+- 返回 `deleted: true` 和 `record_id`。
+
+## 工作流
+
+> 这是**高风险写入操作**。CLI 层要求显式传 `--yes`;如果用户已经明确要求删除且目标明确,直接执行并带上 `--yes`,不要再补一次确认。
+
+1. 建议先用 `+record-get` 确认目标记录。
+2. 只有当目标记录仍不明确时,才继续追问;如果删除意图和目标都明确,直接执行。
+
+## 坑点
+
+- ⚠️ 高风险写操作,删除后不可恢复。
+- ⚠️ 忘记带 `--yes` 会被 CLI 拦截。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-record-get.md

@@ -0,0 +1,38 @@
+# base +record-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取单条记录,可选裁剪输出字段。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-get \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--record-id <id>` | 是 | 记录 ID |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/records/:record_id
+```
+
+## 返回重点
+
+- 成功时直接返回接口 `data` 字段内容。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页

+ 86 - 0
.agents/skills/lark-base/references/lark-base-record-history-list.md

@@ -0,0 +1,86 @@
+# base +record-history-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+查询指定记录的变更历史。当前可执行命令为 `+record-history-list`,无 `+history-list` 别名。
+
+## 推荐命令
+
+```bash
+# 查询最新一页历史
+lark-cli base +record-history-list \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx
+
+# 指定分页大小,带游标翻页
+lark-cli base +record-history-list \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx \
+  --page-size 30 \
+  --max-version 123456
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID |
+| `--record-id <id>` | 是 | 记录 ID |
+| `--page-size <n>` | 否 | 每页条数,默认 `30`,最大 `50` |
+| `--max-version <n>` | 否 | 翻页游标,取上一页返回的 `next_max_version` 值 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/record_history
+```
+
+- Query 参数:`table_id`、`record_id`、`page_size`、`max_version`。
+
+## 返回重点
+
+- 返回记录历史条目列表(按版本号降序,最新在前),而不是记录当前值。
+- 每条历史包含:版本号(`rev`)、操作人(`operator`)、操作时间(`create_time`,**秒级** Unix 时间戳)、操作类型(`activity_type`)、字段变更列表(`field_changes`)。
+- 字段变更包含:字段 ID、字段名、字段类型、变更前值(`before`)、变更后值(`after`)。
+- 适合定位谁改了这条记录、什么时候改的、改了哪些字段。
+
+### activity_type 取值
+
+| 值 | 含义 |
+|------|------|
+| `create` | 记录创建 |
+| `update` | 记录编辑 |
+| `delete` | 记录删除 |
+
+### 不出现在历史中的字段类型
+
+以下字段类型的变更**不会**出现在 `field_changes` 中:
+- **计算字段**:公式(formula)、查找引用(lookup)
+- **系统字段**:自动编号、创建时间、创建人、修改时间、修改人
+
+## 翻页工作流
+
+1. **首次请求**:不传 `--max-version`,获取最新一页。
+2. **判断是否有下一页**:检查返回的 `has_more` 字段。
+3. **翻页**:若 `has_more = true`,取返回的 `next_max_version` 值,传入下一次请求的 `--max-version`。
+4. **终止**:当 `has_more = false` 时停止。
+
+## 工作流
+
+1. 先确认 `table-id` 和 `record-id` 都来自同一张表。
+2. 先查最新一页,再按翻页工作流向前翻页。
+
+## 坑点
+
+- ⚠️ `+record-history-list` 属于 `+xxx-list`,禁止并发调用;批量执行时只能串行。
+- ⚠️ 当前不支持整表历史扫描,只支持单条记录历史。
+
+## 参考
+
+- [lark-base-history.md](lark-base-history.md) — history 索引页
+- [lark-base-record.md](lark-base-record.md) — record 索引页

+ 83 - 0
.agents/skills/lark-base/references/lark-base-record-list.md

@@ -0,0 +1,83 @@
+# base +record-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+分页列出一张表里的记录;可按视图过滤,也可按字段裁剪返回列。
+
+> 默认优先使用 `+record-list`;仅当用户提供明确搜索关键词时,才使用 [lark-base-record-search.md](lark-base-record-search.md)。
+
+## 返回关键字段
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `has_more` | boolean | 是否还有下一页数据;`true` 表示可继续翻页,`false` 表示已到末页 |
+| `query_context.record_scope` | string | 记录范围:`all_records`(全表)或 `view_filtered_records`(按视图过滤) |
+| `query_context.field_scope` | string | 字段范围:`selected_fields`(显式传 `--field-id`)/ `view_visible_fields`(未传 `--field-id` 且按视图可见字段)/ `all_fields`(未传 `--field-id` 且无视图限制) |
+
+## 字段返回优先级
+
+- `query_context.field_scope` 的优先级为:`selected_fields`(explicit `--field-id`) > `view_visible_fields`(view visible fields) > `all_fields`(table all fields)。
+
+## 按需翻页规则
+
+1. 先执行一次 `+record-list` 获取首批结果。
+2. 检查返回的 `has_more`。
+3. 仅当同时满足以下条件时才继续翻页:
+   - `has_more = true`
+   - 用户问题需要更多数据(例如“全部导出”“统计全量明细”“继续加载下一页”)
+4. 若用户只要部分结果(例如“先看前 20 条”“先给示例数据”),即使 `has_more = true` 也不继续翻页。
+5. 继续翻页时,`offset` 按已读取数量递增,直到满足用户需求或 `has_more = false`。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-list \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --offset 0 \
+  --limit 100
+
+lark-cli base +record-list \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --view-id vewXXX \
+  --field-id fldStatus \
+  --field-id 项目名称 \
+  --offset 0 \
+  --limit 50
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id>` | 否 | 视图 ID;传入后只读该视图结果 |
+| `--field-id <id_or_name>` | 否 | 字段 ID 或字段名;可重复传入多个 `--field-id` 裁剪返回列 |
+| `--offset <n>` | 否 | 分页偏移,默认 `0` |
+| `--limit <n>` | 否 | 分页大小,默认 `100`,范围 `1-200`(最大 `200`,超过会报错) |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/records
+```
+
+- 查询参数会附带 `view_id / field_id(repeatable) / offset / limit`。
+
+
+## 坑点
+
+- ⚠️ `+record-list` 禁止并发调用;批量拉多个视图或多张表时必须串行。
+- ⚠️ `--limit` 最大 `200`,不要传超过 `200` 的值。
+- ⚠️ 分页时优先根据返回的 `has_more` 判断是否继续请求,不要盲目预拉全量数据。
+- ⚠️ `--field-id` 接受字段 ID 或字段名。
+- ⚠️ 复杂筛选优先落到视图里,再用 `--view-id` 读取。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页
+- [lark-base-view-set-filter.md](lark-base-view-set-filter.md) — 配筛选

+ 72 - 0
.agents/skills/lark-base/references/lark-base-record-search.md

@@ -0,0 +1,72 @@
+# base +record-search
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+按关键词检索记录;CLI 侧通过 `--json` 透传请求体。
+
+## 适用场景
+
+- 需要关键词检索记录。
+- 用户已提供明确搜索关键词(`keyword`)。
+- 需要附带 `view_id / select_fields` 控制检索范围与返回字段。
+- 不用于聚合统计。涉及 SUM/AVG/COUNT/MAX/MIN 时改用 `+data-query`。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-search \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --json '{"keyword":"Created","search_fields":["Title","fld_owner"],"offset":0,"limit":100}'
+
+lark-cli base +record-search \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --json '{"view_id":"vewXXX","keyword":"Alice","search_fields":["Title","Owner"],"select_fields":["Title","Owner","Status"],"offset":0,"limit":50}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--json <object>` | 是 | 搜索请求体 JSON(结构要求见下方“JSON 要求”) |
+
+## 返回关键字段
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `query_context.record_scope` | string | 记录范围:`all_records`(全表)/ `view_filtered_records`(按 `view_id` 限定到视图记录) |
+| `query_context.field_scope` | string | 字段范围:`selected_fields`(显式传 `select_fields`)/ `view_visible_fields`(未传 `select_fields` 且按视图可见字段)/ `all_fields`(未传 `select_fields` 且无视图限制) |
+| `query_context.search_scope` | string | 实际参与搜索的字段集合,格式类似 `fieldTitle(Title), fieldOwner(Owner)` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```http
+POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/search
+```
+
+### JSON 格式要求
+
+| 字段 | 必填 | 类型 | 约束 |
+|------|------|------|------|
+| `view_id` | 否 | string | 传入后仅在该视图范围内搜索,并默认按该视图可见字段返回结果 |
+| `keyword` | 是 | string | 非空,最小长度 `1` |
+| `search_fields` | 是 | string[] | 数组长度 `1-20`;每项是字段 `field_id` 或字段名,代表在这些字段中做关键词搜索 |
+| `select_fields` | 否 | string[] | 数组长度 `<=50`;每项是字段 `field_id` 或字段名 |
+| `offset` | 否 | int | `>=0`,默认 `0` |
+| `limit` | 否 | int | `1-200`,默认 `10` |
+
+## 坑点
+
+- ⚠️ `+record-search` 用于检索,不用于聚合分析;聚合场景使用 `+data-query`。
+- ⚠️ 部分字段不支持搜索(例如 `attachment`、`link`);传入后通常不会报错,但可能导致无法命中对应记录。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页
+- [lark-base-record-list.md](lark-base-record-list.md) — 分页列表读取
+- [lark-base-data-query.md](lark-base-data-query.md) — 聚合分析

+ 51 - 0
.agents/skills/lark-base/references/lark-base-record-upload-attachment.md

@@ -0,0 +1,51 @@
+# base +record-upload-attachment
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+上传本地文件到当前 Base,并把附件值写入指定记录的附件字段。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-upload-attachment \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx \
+  --field-id fld_attach \
+  --file ./report.pdf
+
+lark-cli base +record-upload-attachment \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx \
+  --field-id "附件" \
+  --file ./report.pdf \
+  --name "Q1-final.pdf"
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--record-id <id>` | 是 | 记录 ID |
+| `--field-id <id_or_name>` | 是 | 附件字段 ID 或字段名 |
+| `--file <path>` | 是 | 本地文件路径,最大 2GB |
+| `--name <name>` | 否 | 写入附件字段时显示的文件名,默认使用本地文件名 |
+
+
+## 工作流
+
+> [!CAUTION]
+> 这是写入操作。用户已经明确要上传到某条记录的某个附件字段时可直接执行;如果 `record-id` 或目标字段仍有歧义,再先确认。
+
+## 坑点
+
+- ⚠️ 目标字段必须是 `attachment` 字段。
+- ⚠️ 记录里的附件 `file_token` 属于 Drive media token;下载时不要走 `lark-cli drive +download`,应使用 `lark-cli docs +media-download --token <file_token> --output <path>`。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页
+- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — 记录值格式详解

+ 89 - 0
.agents/skills/lark-base/references/lark-base-record-upsert.md

@@ -0,0 +1,89 @@
+# base +record-upsert
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+创建记录,或在带 `--record-id` 时更新记录。
+
+## 推荐命令
+
+```bash
+lark-cli base +record-upsert \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --json '{"项目名称":"Apollo","状态":"进行中"}' 
+
+lark-cli base +record-upsert \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --record-id rec_xxx \
+  --json '{"项目名称":"Apollo","状态":"进行中","标签":["高优","外部依赖"],"截止日期":"2026-03-24 10:00:00"}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--record-id <id>` | 否 | 传入时走更新,不传时走创建 |
+| `--json <body>` | 是 | 记录 JSON 对象 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records
+```
+
+- 带 `--record-id` 时内部改走 `PATCH /records/:record_id`。
+
+## JSON 值规范
+
+- `--json` 必须是 **JSON 对象**。
+- key 可用字段名或字段 ID,但一次请求里同一字段只用一种标识,避免重复写入冲突。
+- value 必须匹配字段类型;先 `+field-list` 再构造值。
+- 推荐值形状(常用):
+  - 文本:`"标题"`
+  - 数字:`12.5`
+  - 单选:`"Todo"`
+  - 多选:`["A","B"]`
+  - 复选框:`true`
+  - 人员:`[{"id":"ou_xxx"}]`
+  - 关联记录:`[{"id":"rec_xxx"}]`
+  - 日期:`"YYYY-MM-DD HH:mm:ss"`(如 `"2026-03-24 10:00:00"`)
+- 需要清空字段时优先传 `null`(字段允许清空时)。
+- 公式、查找引用、创建/更新时间、创建/修改人等只读字段不要写入。
+
+**正确(base +record-upsert)**
+
+```json
+{
+  "项目名称": "Apollo",
+  "状态": "进行中",
+  "标签": ["高优", "外部依赖"],
+  "负责人": [{ "id": "ou_xxx" }],
+  "截止日期": "2026-03-24 10:00:00"
+}
+```
+
+## 返回重点
+
+- 创建时返回 `record` 和 `created: true`。
+- 更新时返回 `record` 和 `updated: true`。
+
+## 工作流
+
+
+1. 先确定是新增还是修改。
+
+## 坑点
+
+- ⚠️ `--json` 必须是对象,不支持数组。
+- ⚠️ 有 `--record-id` 就一定走更新;不传就一定走创建,不会自动查重。
+- ⚠️ 这是写入操作,执行前必须确认。
+
+## 参考
+
+- [lark-base-record.md](lark-base-record.md) — record 索引页
+- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — shortcut 记录值格式规范(推荐)

+ 28 - 0
.agents/skills/lark-base/references/lark-base-record.md

@@ -0,0 +1,28 @@
+# base record shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+record 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-record-search.md](lark-base-record-search.md) | `+record-search` | 按关键词和字段范围检索记录 |
+| [lark-base-record-list.md](lark-base-record-list.md) | `+record-list` | 分页列记录 |
+| [lark-base-record-get.md](lark-base-record-get.md) | `+record-get` | 获取单条记录 |
+| [lark-base-record-upsert.md](lark-base-record-upsert.md) | `+record-upsert` | 创建或更新记录 |
+| [lark-base-record-batch-create.md](lark-base-record-batch-create.md) | `+record-batch-create` | 按 `fields/rows` 批量创建记录 |
+| [lark-base-record-batch-update.md](lark-base-record-batch-update.md) | `+record-batch-update` | 批量更新记录 |
+| [lark-base-record-upload-attachment.md](lark-base-record-upload-attachment.md) | `+record-upload-attachment` | 上传本地文件到附件字段并更新记录 |
+| [`../../lark-doc/references/lark-doc-media-download.md`](../../lark-doc/references/lark-doc-media-download.md) | `lark-cli docs +media-download` | 下载 Base 附件到本地(附件的 `file_token` 来自 `+record-get` 的附件字段) |
+| [lark-base-record-delete.md](lark-base-record-delete.md) | `+record-delete` | 删除记录 |
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。
+- `+record-list` 支持重复传参 `--field-id` 做字段筛选。
+- 写记录 JSON 前优先阅读 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md)。
+- 本地文件写入附件字段时,必须使用 `+record-upload-attachment`。
+- 从附件字段下载文件时,用 `lark-cli docs +media-download --token <file_token> --output <path>`,用法见 [`../../lark-doc/references/lark-doc-media-download.md`](../../lark-doc/references/lark-doc-media-download.md)。

+ 89 - 0
.agents/skills/lark-base/references/lark-base-role-create.md

@@ -0,0 +1,89 @@
+# base +role-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+> 
+> **前置条件:** 需要base开启了高级权限,如果调用这个接口返回没有开启高级权限,可以参考 [`lark-base-advperm-enable.md`](lark-base-advperm-enable.md) 了解高级权限启用规则。
+
+在指定 Base 中创建一个自定义角色,需传入完整的 AdvPermBaseRoleConfig 作为角色配置。
+
+## 推荐命令
+
+```bash
+# 创建简单角色(仅设置名称和类型)
+lark-cli base +role-create \
+  --base-token VwGhb**************fMnod \
+  --json '{"role_name":"财务审核员","role_type":"custom_role"}'
+
+# 创建角色并配置表权限、字段权限、记录筛选
+lark-cli base +role-create \
+  --base-token VwGhb**************fMnod \
+  --json '{"role_name":"财务审核员","role_type":"custom_role","base_rule_map":{"copy":false,"download":false},"table_rule_map":{"订单表":{"perm":"edit","record_rule":{"record_operations":["add"],"edit_filter_rule_group":{"conjunction":"and","filter_rules":[{"conjunction":"and","filters":[{"field_name":"部门","operator":"is","filter_values":["财务部"]}]}]},"other_record_all_read":true},"field_rule":{"field_perm_mode":"specify","field_perms":{"金额":"edit","备注":"read","密码":"no_perm"}}},"用户表":{"perm":"read_only"}},"dashboard_rule_map":{"销售看板":{"perm":"read_only"}}}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+| `--json <body>` | 是 | AdvPermBaseRoleConfig JSON,包含角色名称、类型、权限配置 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/roles
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识,27 位字母数字字符串 |
+
+**Request Body(JSON — AdvPermBaseRoleConfig):**
+
+> 完整的权限配置结构详见 [role-config.md](role-config.md)
+
+## API 出参详情
+
+**Response:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | int32 | 错误码,0 表示成功 |
+| `message` | string | 错误信息 |
+| `data` | string | 创建成功时为空 |
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "success": true
+  }
+}
+```
+
+## 工作流
+
+
+1. 向用户确认 `--base-token` 和角色配置 JSON
+2. 执行命令
+3. 确认返回 `code: 0` 表示创建成功
+
+## 坑点
+
+- ⚠️ **role_type 必须为 custom_role**:创建接口仅支持 `custom_role`,传其他值会报业务错误
+- ⚠️ **API 路径版本**:本接口使用 `base/v3`,路径必须从原始文档提取,不要用 WebSearch 补全
+- ⚠️ **data 字段是 JSON 字符串**:响应中 `data` 是 string 类型(非 object),需要双重解析
+- ⚠️ **Filter 字段**:`field_name`、`operator`、`filter_values` 由客户端传入,`field_type`、`field_ui_type`、`reference_type` 由服务端 filterFiller 自动补全
+- ⚠️ **前置条件**:Base 必须已开启高级权限,操作用户必须为 Base 管理员
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 83 - 0
.agents/skills/lark-base/references/lark-base-role-delete.md

@@ -0,0 +1,83 @@
+# base +role-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+>
+> **前置条件:** 需要base开启了高级权限,如果调用这个接口返回没有开启高级权限,可以参考 [`lark-base-advperm-enable.md`](lark-base-advperm-enable.md) 了解高级权限启用规则。
+
+删除指定的自定义角色。系统角色(editor / reader)不可删除。
+
+## 推荐命令
+
+```bash
+lark-cli base +role-delete \
+  --base-token VwGhb**************fMnod \
+  --role-id rolxxxxxx4
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+| `--role-id <id>` | 是 | 角色 ID,格式 `rol` + 8 位字母数字 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+DELETE /open-apis/base/v3/bases/:base_token/roles/:role_id
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识 |
+| `role_id` | 是 | 角色 ID |
+
+无 Query 参数,无 Request Body。
+
+## API 出参详情
+
+**Response:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | int32 | 错误码,0 表示成功 |
+| `message` | string | 错误信息 |
+| `data` | string | 删除成功时为空 |
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "success": true
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**高风险不可逆操作** — 删除后无法恢复,执行前必须向用户二次确认。
+
+1. 建议先用 `+role-list` 确认角色存在
+2. 向用户确认 `--base-token` 和 `--role-id`
+3. 执行命令
+4. 确认返回 `code: 0`
+
+## 坑点
+
+- ⚠️ **仅支持删除自定义角色**:系统角色(editor / reader)不可删除,会报业务错误
+- ⚠️ **不可逆操作**:删除后角色及其关联的成员配置无法恢复
+- ⚠️ **role_id 来源**:可通过 `+role-list` 获取,格式为 `rol` + 8 位字母数字
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 87 - 0
.agents/skills/lark-base/references/lark-base-role-get.md

@@ -0,0 +1,87 @@
+# base +role-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+>
+> **前置条件:** 需要base开启了高级权限,如果调用这个接口返回没有开启高级权限,可以参考 [`lark-base-advperm-enable.md`](lark-base-advperm-enable.md) 了解高级权限启用规则。
+
+获取指定角色的完整配置详情(AdvPermBaseRole),包含表权限、字段权限、记录筛选等全量配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +role-get \
+  --base-token VwGhb**************fMnod \
+  --role-id rolxxxxxx4
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+| `--role-id <id>` | 是 | 角色 ID,格式 `rol` + 8 位字母数字 |
+| `--format <fmt>` | 否 | 输出格式:json / pretty / table / csv / ndjson |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/roles/:role_id
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识 |
+| `role_id` | 是 | 角色 ID |
+
+无 Query 参数,无 Request Body。
+
+## API 出参详情
+
+**Response `data` 字段(JSON 字符串,需双重解析):**
+
+完整的 AdvPermBaseRole 对象(结构详见 [role-config.md](role-config.md)):
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `role_id` | string | 角色 ID |
+| `role_name` | string | 角色名称 |
+| `role_type` | string | 角色类型 |
+| `base_rule_map` | map\<string, bool\> | Base 级权限(copy/download) |
+| `table_rule_map` | map\<string, TableRule\> | 数据表权限配置 |
+| `dashboard_rule_map` | map\<string, DashboardRule\> | 仪表盘权限配置 |
+| `docx_rule_map` | map\<string, DocxRule\> | 文档权限配置 |
+
+## 返回值
+
+命令成功后输出完整角色配置 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "role_id": "rolxxxxxx4",
+    "role_name": "财务审核员",
+    "role_type": "custom_role",
+    "base_rule_map": {"copy": false, "download": false},
+    "table_rule_map": {
+      "订单表": {"perm": "edit", "record_rule": {...}, "field_rule": {...}},
+      "用户表": {"perm": "read_only"}
+    }
+  }
+}
+```
+
+## 坑点
+
+- ⚠️ **与 +role-list 的区别**:`+role-list` 只返回摘要(role_id/name/type),`+role-get` 返回完整的权限配置
+- ⚠️ **data 是 JSON 字符串**:响应 `data` 是 string 类型,需要双重解析
+- ⚠️ **角色不存在时**:data 为空字符串,不会报错
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 81 - 0
.agents/skills/lark-base/references/lark-base-role-list.md

@@ -0,0 +1,81 @@
+# base +role-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+>
+> **前置条件:** 需要base开启了高级权限,如果调用这个接口返回没有开启高级权限,可以参考 [`lark-base-advperm-enable.md`](lark-base-advperm-enable.md) 了解高级权限启用规则。。
+
+获取指定 Base 下所有角色的摘要信息列表(包括系统角色和自定义角色),返回 role_id / role_name / role_type。
+
+## 推荐命令
+
+```bash
+lark-cli base +role-list --base-token VwGhb**************fMnod
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+| `--format <fmt>` | 否 | 输出格式:json / pretty / table / csv / ndjson |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/roles
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识 |
+
+无 Query 参数,无 Request Body。
+
+## API 出参详情
+
+**Response `data` 字段(JSON 字符串,需双重解析):**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `base_roles` | []string | AIBaseRoleRef 的 JSON 字符串数组 |
+| `total` | int32 | 角色总数 |
+
+**AIBaseRoleRef 结构:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `role_id` | string | 角色 ID,如 `rolxxxxxx1` |
+| `role_name` | string | 角色名称 |
+| `role_type` | string | 角色类型:`editor` / `reader` / `custom_role` |
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "base_roles": [
+      "{\"role_id\":\"rolxxxxxx1\",\"role_name\":\"技术管理员\",\"role_type\":\"custom_role\"}",
+      "{\"role_id\":\"rolxxxxxx2\",\"role_name\":\"编辑者\",\"role_type\":\"editor\"}"
+    ],
+    "total": 4
+  }
+}
+```
+
+## 坑点
+
+- ⚠️ **data 是 JSON 字符串**:响应 `data` 是 string 类型,内部 `base_roles` 数组的每个元素也是 JSON 字符串,需要多层解析
+- ⚠️ **返回摘要信息**:此接口只返回 role_id / role_name / role_type,不含完整权限配置。要获取完整配置请用 `+role-get`
+- ⚠️ **包含系统角色**:返回结果包含  editor / reader 两个系统角色
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 94 - 0
.agents/skills/lark-base/references/lark-base-role-update.md

@@ -0,0 +1,94 @@
+# base +role-update
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+>
+> **前置条件:** 需要base开启了高级权限,如果调用这个接口返回没有开启高级权限,可以参考 [`lark-base-advperm-enable.md`](lark-base-advperm-enable.md) 了解高级权限启用规则。
+
+更新指定角色的权限配置。
+
+## 推荐命令
+
+```bash
+# 仅修改角色名称
+lark-cli base +role-update \
+  --base-token VwGhb**************fMnod \
+  --role-id rolxxxxxx4 \
+  --json '{"role_name":"高级审核员","role_type":"custom_role"}'
+
+# 修改某个表的权限(其他表不受影响)
+lark-cli base +role-update \
+  --base-token VwGhb**************fMnod \
+  --role-id rolxxxxxx4 \
+  --json '{"role_name":"财务审核员","role_type":"custom_role","table_rule_map":{"订单表":{"perm":"read_only"}}}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token,27 位字母数字字符串 |
+| `--role-id <id>` | 是 | 角色 ID,格式 `rol` + 8 位字母数字 |
+| `--json <body>` | 是 | 增量 AdvPermBaseRoleConfig JSON,仅含需变更的字段 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/roles/:role_id
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | Base 的唯一标识 |
+| `role_id` | 是 | 角色 ID |
+
+**Request Body(JSON — 增量 AdvPermBaseRoleConfig):**
+
+> 完整的权限配置结构详见 [role-config.md](role-config.md),**更新时需要在原始配置上修改,传入的role配置信息尽量完整**。
+
+## API 出参详情
+
+**Response:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | int32 | 错误码,0 表示成功 |
+| `message` | string | 错误信息 |
+| `data` | string | 更新成功时为空 |
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "success": true
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**高危写入操作** — 执行前必须向用户确认,需要 `--yes` 标志。
+
+1. 建议先用 `+role-get` 获取当前配置,确认变更范围
+2. 向用户确认 `--base-token`、`--role-id` 和变更 JSON,对于变化的部分可以高亮提示用户
+3. 执行命令
+4. 确认返回 `code: 0`
+
+## 坑点
+
+- ⚠️ **Delta Merge 语义**:仅传入需变更的字段即可,未传入的保持不变。例如只传 `table_rule_map` 中某个表的 perm,其他表不受影响
+- ⚠️ **role_name 和 role_type 必填**:即使不修改也必须传入当前值
+- ⚠️ **body 不能为 nil**:PUT 请求必须传 body,否则服务端返回错误
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 679 - 0
.agents/skills/lark-base/references/lark-base-shortcut-field-properties.md

@@ -0,0 +1,679 @@
+# base shortcut field JSON 规范(lark-base-shortcut-field-properties)
+
+> 适用命令:`lark-cli base +field-create`、`lark-cli base +field-update`
+
+本文件定义 **shortcut 写字段** 时 `--json` 的推荐格式,避免 AI 混用旧版 `type=数字 + field_name + property` 结构。
+
+## 1. 顶层规则(必须遵守)
+
+- `--json` 必须是 JSON 对象。
+- 顶层统一使用:`type` + `name` + 类型特有字段。
+- 如需字段说明,直接传 `description`;支持纯文本,也支持 Markdown 链接。
+- 不要使用旧结构:`field_name`、`property`、`ui_type`、数字枚举 `type`。
+- `+field-update` 是 `PUT` 语义,建议先 `+field-get` 再全量提交目标字段配置。
+- `type=formula` 或 `type=lookup` 创建时,必须先读对应 guide。
+
+```json
+{
+  "type": "text",
+  "name": "需求背景",
+  "description": "记录需求背景与已知约束;填写口径可参考[说明模板](https://example.com/spec)"
+}
+```
+
+## 2. 各类型格式与示例
+
+### 2.1 text
+
+**要求**:`name` 必填;可选传 `description`;`style.type` 可选,默认 `plain`。
+
+```json
+{
+  "type": "text",
+  "name": "标题",
+  "style": { "type": "plain" }
+}
+```
+
+`style.type` 常用值:`plain`、`phone`、`url`、`email`、`barcode`。
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "text", "description": "Text field type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "style": {
+      "type": "object",
+      "properties": { "type": { "type": "string", "enum": ["plain", "phone", "url", "email", "barcode"], "description": "Text style type" } },
+      "required": ["type"],
+      "additionalProperties": false,
+      "description": "Text style",
+      "default": { "type": "plain" }
+    }
+  },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Text field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.2 number
+
+**要求**:`name` 必填;`style.type` 常用 `plain/currency/progress/rating`。
+
+```json
+{
+  "type": "number",
+  "name": "工时",
+  "style": {
+    "type": "plain",
+    "precision": 2,
+    "percentage": false,
+    "thousands_separator": true
+  }
+}
+```
+
+```json
+{
+  "type": "number",
+  "name": "预算",
+  "style": { "type": "currency", "precision": 2, "currency_code": "CNY" }
+}
+```
+
+```json
+{
+  "type": "number",
+  "name": "完成度",
+  "style": { "type": "progress", "percentage": true, "color": "Blue" }
+}
+```
+
+```json
+{
+  "type": "number",
+  "name": "评分",
+  "style": { "type": "rating", "icon": "star", "min": 1, "max": 5 }
+}
+```
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "number", "description": "Number field type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "style": {
+      "anyOf": [
+        {
+          "type": "object",
+          "properties": {
+            "type": { "type": "string", "const": "plain", "description": "Plain style type" },
+            "precision": { "type": "number", "minimum": 0, "maximum": 4, "default": 2, "description": "Decimal precision" },
+            "percentage": { "type": "boolean", "default": false, "description": "Use percentage" },
+            "thousands_separator": { "$ref": "#/properties/style/anyOf/0/properties/percentage", "default": false, "description": "Use thousand separator" }
+          },
+          "required": ["type"],
+          "additionalProperties": false,
+          "description": "Plain number style"
+        },
+        {
+          "type": "object",
+          "properties": {
+            "type": { "type": "string", "const": "currency", "description": "Currency style type" },
+            "precision": { "type": "number", "minimum": 0, "maximum": 4, "default": 2, "description": "Decimal precision" },
+            "currency_code": {
+              "type": "string",
+              "enum": ["CNY", "USD", "EUR", "GBP", "AED", "AUD", "BRL", "CAD", "CHF", "HKD", "INR", "IDR", "JPY", "KRW", "MOP", "MXN", "MYR", "PHP", "PLN", "RUB", "SGD", "THB", "TRY", "TWD", "VND"],
+              "default": "CNY",
+              "description": "Currency code"
+            }
+          },
+          "required": ["type"],
+          "additionalProperties": false,
+          "description": "Currency style"
+        },
+        {
+          "type": "object",
+          "properties": {
+            "type": { "type": "string", "const": "progress", "description": "Progress style type" },
+            "percentage": { "$ref": "#/properties/style/anyOf/0/properties/percentage", "default": true, "description": "Use percentage" },
+            "color": {
+              "type": "string",
+              "enum": ["Blue", "Purple", "DarkGreen", "Green", "Cyan", "Orange", "Red", "Gray", "WhiteToBlueGradient", "WhiteToPurpleGradient", "WhiteToOrangeGradient", "GreedToRedGradient", "RedToGreenGradient", "BlueToPinkGradient", "PinkToBlueGradient", "SpectralGradient"],
+              "description": "Progress color"
+            }
+          },
+          "required": ["type", "color"],
+          "additionalProperties": false,
+          "description": "Progress style"
+        },
+        {
+          "type": "object",
+          "properties": {
+            "type": { "type": "string", "const": "rating", "description": "Rating style type" },
+            "icon": { "type": "string", "enum": ["star", "heart", "thumbsup", "fire", "smile", "lightning", "flower", "number"], "default": "star", "description": "Rating icon" },
+            "min": { "type": "integer", "minimum": 0, "maximum": 1, "default": 1, "description": "Minimum rating" },
+            "max": { "type": "integer", "minimum": 1, "maximum": 10, "default": 5, "description": "Maximum rating" }
+          },
+          "required": ["type"],
+          "additionalProperties": false,
+          "description": "Rating style"
+        }
+      ],
+      "default": { "type": "plain" },
+      "description": "Number style"
+    }
+  },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Number field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.3 select(单选/多选)
+
+**要求**:`name` 必填;`multiple` 控制单/多选;`options` 为对象数组。
+
+```json
+{
+  "type": "select",
+  "name": "状态",
+  "multiple": false,
+  "options": [
+    { "name": "Todo", "hue": "Blue", "lightness": "Lighter" },
+    { "name": "Done", "hue": "Green", "lightness": "Light" }
+  ]
+}
+```
+
+- `options[].name` 必填。
+- `options` 不要传 `id`(创建场景由后端生成)。
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "select", "description": "Select field type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "multiple": { "type": "boolean", "default": false, "description": "Allow multiple" },
+    "options": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "name": { "type": "string", "description": "Option name" },
+          "hue": { "type": "string", "enum": ["Red", "Orange", "Yellow", "Lime", "Green", "Turquoise", "Wathet", "Blue", "Carmine", "Purple", "Gray"], "description": "Option hue", "default": "Blue" },
+          "lightness": { "type": "string", "enum": ["Lighter", "Light", "Standard", "Dark", "Darker"], "description": "Option lightness", "default": "Lighter" }
+        },
+        "required": ["name"],
+        "additionalProperties": false,
+        "description": "Select option"
+      },
+      "maxItems": 10000,
+      "description": "Static options"
+    }
+  },
+  "required": ["type", "name", "options"],
+  "additionalProperties": false,
+  "description": "Select field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.4 datetime / created_at / updated_at
+
+**要求**:`name` 必填;`style.format` 可选。
+
+```json
+{
+  "type": "datetime",
+  "name": "截止时间",
+  "style": { "format": "yyyy-MM-dd HH:mm" }
+}
+```
+
+```json
+{ "type": "created_at", "name": "创建时间", "style": { "format": "yyyy/MM/dd" } }
+```
+
+```json
+{ "type": "updated_at", "name": "更新时间", "style": { "format": "yyyy/MM/dd HH:mm" } }
+```
+
+**Schema - datetime**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "datetime", "description": "Date time type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "style": {
+      "type": "object",
+      "properties": { "format": { "type": "string", "enum": ["yyyy/MM/dd", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm Z", "yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm Z", "MM-dd", "MM/dd/yyyy", "dd/MM/yyyy"], "default": "yyyy/MM/dd", "description": "Date format" } },
+      "additionalProperties": false,
+      "default": { "format": "yyyy/MM/dd" },
+      "description": "Date time style"
+    }
+  },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Date time field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+**Schema - created_at**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "created_at", "description": "Created time type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "style": {
+      "type": "object",
+      "properties": { "format": { "type": "string", "enum": ["yyyy/MM/dd", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm Z", "yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm Z", "MM-dd", "MM/dd/yyyy", "dd/MM/yyyy"], "default": "yyyy/MM/dd", "description": "Date format" } },
+      "additionalProperties": false,
+      "default": { "format": "yyyy/MM/dd" },
+      "description": "Created time style"
+    }
+  },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Created time field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+**Schema - updated_at**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "updated_at", "description": "Modified time type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "style": {
+      "type": "object",
+      "properties": { "format": { "type": "string", "enum": ["yyyy/MM/dd", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH:mm Z", "yyyy-MM-dd", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm Z", "MM-dd", "MM/dd/yyyy", "dd/MM/yyyy"], "default": "yyyy/MM/dd", "description": "Date format" } },
+      "additionalProperties": false,
+      "default": { "format": "yyyy/MM/dd" },
+      "description": "Modified time style"
+    }
+  },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Modified time field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.5 user / created_by / updated_by
+
+```json
+{ "type": "user", "name": "负责人", "multiple": true }
+```
+
+```json
+{ "type": "created_by", "name": "创建人" }
+```
+
+```json
+{ "type": "updated_by", "name": "更新人" }
+```
+
+**Schema - user**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "user", "description": "User field type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" }, "multiple": { "type": "boolean", "default": true, "description": "Allow multiple" } },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "User field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+**Schema - created_by**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "created_by", "description": "Created by type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" } },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Created by field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+**Schema - updated_by**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "updated_by", "description": "Modified by type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" } },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Modified by field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.6 link
+
+**要求**:`link_table` 必填;`bidirectional` 默认 `false`。
+
+```json
+{
+  "type": "link",
+  "name": "关联任务",
+  "link_table": "任务表",
+  "bidirectional": true,
+  "bidirectional_link_field_name": "反向关联"
+}
+```
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "link", "description": "Link field type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "link_table": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Linked table" },
+    "bidirectional": { "type": "boolean", "default": false, "description": "Bidirectional link" },
+    "bidirectional_link_field_name": { "$ref": "#/properties/name", "description": "Bidirectional link field name" }
+  },
+  "required": ["type", "name", "link_table"],
+  "additionalProperties": false,
+  "description": "Link field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.7 formula
+
+**要求**:`expression` 必填。
+
+```json
+{
+  "type": "formula",
+  "name": "合计",
+  "expression": "1+1"
+}
+```
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "formula", "description": "Formula field type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" }, "expression": { "type": "string", "description": "Formula expression" } },
+  "required": ["type", "name", "expression"],
+  "additionalProperties": false,
+  "description": "Formula field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.8 lookup
+
+**要求**:`from`、`select`、`where` 必填;`aggregate` 可选。`where.logic` 仅支持 `and/or`,`conditions` 每项必须是三元组 `[field, op, value]`。
+
+```json
+{
+  "type": "lookup",
+  "name": "状态汇总",
+  "from": "任务表",
+  "select": "状态",
+  "where": {
+    "logic": "and",
+    "conditions": [
+      ["负责人", "==", { "type": "field_ref", "field": "当前负责人" }],
+      ["状态", "non_empty", null]
+    ]
+  },
+  "aggregate": "raw_value"
+}
+```
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "lookup", "description": "Lookup field type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "from": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Source data table" },
+    "select": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Field to aggregate from source table" },
+    "where": {
+      "type": "object",
+      "properties": {
+        "logic": { "type": "string", "enum": ["and", "or"], "default": "and", "description": "Filter Condition Logic" },
+        "conditions": {
+          "type": "array",
+          "items": {
+            "type": "array",
+            "minItems": 3,
+            "maxItems": 3,
+            "items": [
+              { "type": "string", "minLength": 1, "maxLength": 100, "description": "Field from source table to filter on" },
+              { "type": "string", "enum": ["==", "!=", ">", ">=", "<", "<=", "intersects", "disjoint", "empty", "non_empty"], "description": "Condition operator" },
+              {
+                "anyOf": [
+                  {
+                    "anyOf": [
+                      {
+                        "type": "object",
+                        "properties": {
+                          "type": { "type": "string", "const": "constant" },
+                          "value": {
+                            "anyOf": [
+                              { "type": "string", "description": "text & formula & location field support string as filter value" },
+                              { "type": "number", "description": "number & auto_number(the underfly incremental_number) field support number as filter value" },
+                              { "type": "array", "items": { "type": "string", "description": "option name" }, "description": "select field support one option: [\"option1\"] or multiple options: `[\"option1\", \"option2\"]` as filter value." },
+                              { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "record id" } }, "required": ["id"], "additionalProperties": false }, "description": "link field support record id list as filter value" },
+                              { "type": "string", "description": "\ndatetime & create_at & updated_at field support relative and absolute filter value.\nabsolute:\n- \"ExactDate(yyyy-MM-dd)\"\nrelative:\n- Today\n- Tomorrow\n- Yesterday\n" },
+                              { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "user id" } }, "required": ["id"], "additionalProperties": false }, "description": "user field support user id list as filter value" },
+                              { "type": "boolean", "description": "checkbox field support boolean as filter value" }
+                            ]
+                          }
+                        },
+                        "required": ["type", "value"],
+                        "additionalProperties": false,
+                        "description": "Constant filter value"
+                      },
+                      {
+                        "type": "object",
+                        "properties": { "type": { "type": "string", "const": "field_ref" }, "field": { "type": "string", "minLength": 1, "maxLength": 100, "description": "Field id or name" } },
+                        "required": ["type", "field"],
+                        "additionalProperties": false,
+                        "description": "Dynamic field reference from current table"
+                      }
+                    ]
+                  },
+                  { "type": "null" }
+                ],
+                "description": "Condition value (null for isEmpty/isNotEmpty)"
+              }
+            ],
+            "description": "Lookup condition tuple: [fieldRef, operator, value?]"
+          },
+          "minItems": 1,
+          "description": "Filter conditions"
+        }
+      },
+      "required": ["conditions"],
+      "additionalProperties": false
+    },
+    "aggregate": { "type": "string", "enum": ["raw_value", "sum", "average", "counta", "unique_counta", "max", "min", "unique"], "default": "raw_value", "description": "Aggregation function" }
+  },
+  "required": ["type", "name", "from", "select", "where"],
+  "additionalProperties": false,
+  "description": "Lookup field. You MUST Read xxx document first!",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.9 auto_number
+
+```json
+{
+  "type": "auto_number",
+  "name": "编号",
+  "style": {
+    "rules": [
+      { "type": "text", "text": "TASK-" },
+      { "type": "incremental_number", "length": 4 }
+    ]
+  }
+}
+```
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": {
+    "type": { "type": "string", "const": "auto_number", "description": "Auto number type" },
+    "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" },
+    "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" },
+    "style": {
+      "type": "object",
+      "properties": {
+        "rules": {
+          "type": "array",
+          "items": {
+            "anyOf": [
+              {
+                "type": "object",
+                "properties": { "type": { "type": "string", "const": "text", "description": "Text rule type" }, "text": { "type": "string", "description": "Prefix text" } },
+                "required": ["type", "text"],
+                "additionalProperties": false,
+                "description": "Auto number text rule"
+              },
+              {
+                "type": "object",
+                "properties": { "type": { "type": "string", "const": "incremental_number", "description": "Increment rule type" }, "length": { "type": "integer", "minimum": 1, "maximum": 9, "description": "Serial length" } },
+                "required": ["type", "length"],
+                "additionalProperties": false,
+                "description": "Auto number increment rule"
+              },
+              {
+                "type": "object",
+                "properties": {
+                  "type": { "type": "string", "const": "created_time", "description": "Date rule type(auto fill record created date)" },
+                  "date_format": { "type": "string", "enum": ["yyyyMMdd", "yyyyMM", "yyMM", "MMdd", "yyyy", "MM", "dd"], "description": "Date format" }
+                },
+                "required": ["type", "date_format"],
+                "additionalProperties": false,
+                "description": "Auto number date rule"
+              }
+            ]
+          },
+          "minItems": 1,
+          "maxItems": 9,
+          "description": "Numbering rules"
+        }
+      },
+      "required": ["rules"],
+      "additionalProperties": false,
+      "default": {
+        "rules": [
+          { "type": "text", "text": "NO." },
+          { "type": "incremental_number", "length": 3 }
+        ]
+      },
+      "description": "Auto number style"
+    }
+  },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Auto number field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+### 2.10 attachment / location / checkbox
+
+```json
+{ "type": "attachment", "name": "附件" }
+```
+
+```json
+{ "type": "location", "name": "位置" }
+```
+
+```json
+{ "type": "checkbox", "name": "完成" }
+```
+
+**Schema - attachment**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "attachment", "description": "Attachment field type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" } },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Attachment field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+**Schema - location**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "location", "description": "Location field type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" } },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Location field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+**Schema - checkbox**
+
+```json
+{
+  "type": "object",
+  "properties": { "type": { "type": "string", "const": "checkbox", "description": "Checkbox field type" }, "name": { "type": "string", "minLength": 1, "maxLength": 1000, "description": "Field name" }, "description": { "type": "string", "description": "Field description; supports plain text or Markdown links" } },
+  "required": ["type", "name"],
+  "additionalProperties": false,
+  "description": "Checkbox field",
+  "$schema": "http://json-schema.org/draft-07/schema#"
+}
+```
+
+## 3. 推荐工作流
+
+1. `+field-list` / `+field-get` 先拿当前字段结构。
+2. 按本规范构造 `--json`。
+3. `type=formula/lookup` 时先读对应 guide,再创建。

+ 200 - 0
.agents/skills/lark-base/references/lark-base-shortcut-record-value.md

@@ -0,0 +1,200 @@
+# base shortcut record JSON 规范(lark-base-shortcut-record-value)
+
+> 适用命令:`lark-cli base +record-upsert`
+
+本文件定义 **shortcut 写记录** 时 `--json` 的推荐格式,目标是让 AI 一次写对。
+
+## 1. 顶层规则(必须遵守)
+
+- `--json` 必须是 JSON 对象。
+- 顶层直接传字段映射:`{"字段名或字段ID": 值}`。
+- 一次 payload 里同一字段只用一种 key(字段名或字段 ID),不要重复。
+- 写入前先 `+field-list` 获取字段 `type/style/multiple`,再构造值。
+
+## 2. 各类型值格式与示例
+
+### 2.1 text / phone / url
+
+**推荐值**:字符串。
+
+```json
+{
+    "标题": "Hello",
+    "联系电话": "1380000000000",
+    "官网": "https://example.com"
+}
+```
+
+**Schema**
+
+```json
+{ "type": "string", "description": "text field cell, example: \"one string and [one url](https://foo.bar)\"" }
+```
+
+### 2.2 number
+
+**推荐值**:数字。
+
+```json
+{
+    "工时": 12.5,
+    "预算": 3000
+}
+```
+
+**Schema**
+
+```json
+{ "type": "number", "description": "number field cell, can be any float64 value" }
+```
+
+### 2.3 select(单选/多选/阶段)
+
+**推荐值**:
+- 单选:字符串
+- 多选:字符串数组
+
+```json
+{
+    "状态": "Todo",
+    "标签": ["后端", "高优"]
+}
+```
+
+**Schema**
+
+```json
+{ "type": "array", "items": { "type": "string", "description": "option name" }, "description": "select field cell, example: [\"option_1\", \"option_2\"]" }
+```
+
+### 2.4 datetime
+
+**推荐值**:`YYYY-MM-DD HH:mm:ss` 字符串(稳妥写法)。
+
+```json
+{
+    "截止时间": "2026-03-24 10:00:00"
+}
+```
+
+**Schema**
+
+```json
+{ "type": "string", "description": "datetime field cell. accepts common datetime strings and timestamp-like values. Prefer \"YYYY-MM-DD HH:mm:ss\" in requests because it is the most stable format and matches the API output. Example: \"2026-01-01 19:30:00\"" }
+```
+
+### 2.5 checkbox
+
+**推荐值**:布尔值。
+
+```json
+{
+    "已完成": true
+}
+```
+
+**Schema**
+
+```json
+{ "type": "boolean", "description": "checkbox field cell" }
+```
+
+### 2.6 user
+
+**推荐值**:对象数组,元素至少有 `id`。
+
+```json
+{
+    "负责人": [
+      { "id": "ou_xxx" }
+    ]
+}
+```
+
+**Schema**
+
+```json
+{ "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "user id" } }, "required": ["id"], "additionalProperties": false }, "description": "user field cell, example: [{\"id\": \"ou_123\"}]" }
+```
+
+### 2.7 link
+
+**推荐值**:对象数组,元素至少有 `id`。
+
+```json
+{
+    "关联任务": [
+      { "id": "rec_xxx" }
+    ]
+}
+```
+
+**Schema**
+
+```json
+{ "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "record id" } }, "required": ["id"], "additionalProperties": false }, "description": "link field cell, example: [{\"id\": \"rec_123\"}]" }
+```
+
+### 2.8 location
+
+**推荐值**:对象 `{lng, lat}`。
+
+```json
+{
+    "坐标": {
+      "lng": 116.397428,
+      "lat": 39.90923
+    }
+}
+```
+
+**Schema**
+
+```json
+{
+  "type": "object",
+  "properties": { "lng": { "type": "number", "description": "Longitude" }, "lat": { "type": "number", "description": "Latitude" } },
+  "required": ["lng", "lat"],
+  "additionalProperties": false,
+  "description": "location field cell, example: {\"lng\": 113.94765, \"lat\": 22.528533}"
+}
+```
+
+### 2.9 attachment
+
+对 agent 而言,附件上传是**特殊链路**:如果用户要把本地文件加到记录里,必须使用 `lark-cli base +record-upload-attachment` 上传到已有记录。
+
+**Schema - attachment**
+
+```json
+{
+  "type": "array",
+  "items": { "type": "object", "properties": { "file_token": { "type": "string", "minLength": 0, "maxLength": 50 }, "name": { "type": "string", "minLength": 1, "maxLength": 255 } }, "required": ["file_token", "name"], "additionalProperties": false },
+  "description": "attachment field cell. For agent, do not synthesize this payload via +record-upsert; must use +record-upload-attachment to upload files."
+}
+```
+
+## 3. 只读字段(不要写)
+
+以下字段在写记录时应视为只读:
+- `auto_number`
+- `lookup`
+- `formula`
+- `created_time` / `modified_time`
+- `created_by` / `modified_by`
+
+## 4. 快速可用完整示例
+
+```json
+{
+    "标题": "Created from shortcut",
+    "状态": "Todo",
+    "标签": ["高优", "外部依赖"],
+    "工时": 8,
+    "截止时间": "2026-03-24 10:00:00",
+    "已完成": false,
+    "负责人": [{ "id": "ou_123" }],
+    "关联任务": [{ "id": "rec_456" }],
+    "坐标": { "lng": 116.397428, "lat": 39.90923 }
+}
+```

+ 62 - 0
.agents/skills/lark-base/references/lark-base-table-create.md

@@ -0,0 +1,62 @@
+# base +table-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+创建数据表;可选地继续创建字段和视图。
+
+## 推荐命令
+
+```bash
+lark-cli base +table-create \
+  --base-token app_xxx \
+  --name "客户名单"
+
+lark-cli base +table-create \
+  --base-token app_xxx \
+  --name "项目管理" \
+  --fields '[{"name":"项目名称","type":"text"}]' \
+  --view '[{"name":"默认表格","type":"grid"}]' 
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--name <name>` | 是 | 新表名称 |
+| `--fields <json>` | 否 | 字段 JSON 数组 |
+| `--view <json>` | 否 | 视图 JSON 对象或数组 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/tables
+```
+
+- 如果传了 `--fields`,CLI 会继续调用字段接口。
+- 如果传了 `--view`,CLI 会继续调用视图接口。
+
+## 返回重点
+
+- 至少返回 `table`。
+- 传了 `--fields` / `--view` 时,还会附带 `fields` / `views`。
+
+## 工作流
+
+
+1. 先只传 `--name` 建空表。
+2. 字段或视图参数较复杂时,先精简到最小必需字段,再以内联 JSON 传参。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ CLI 会用 `--fields` 的第一个元素更新系统默认首列,后续元素才是新增字段。
+- ⚠️ 不要并行改同一张表,避免状态竞争。
+
+## 参考
+
+- [lark-base-table.md](lark-base-table.md) — table 索引页
+- [lark-base-field-create.md](lark-base-field-create.md) — 建字段
+- [lark-base-view-create.md](lark-base-view-create.md) — 建视图

+ 51 - 0
.agents/skills/lark-base/references/lark-base-table-delete.md

@@ -0,0 +1,51 @@
+# base +table-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+删除一张表。
+
+## 推荐命令
+
+```bash
+lark-cli base +table-delete \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --yes
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+DELETE /open-apis/base/v3/bases/:base_token/tables/:table_id
+```
+
+## 返回重点
+
+- 返回 `deleted: true` 以及删除目标的 `table_id / table_name`。
+
+## 工作流
+
+> 这是**高风险写入操作**。CLI 层要求显式传 `--yes`;如果用户已经明确要求删除且目标明确,直接执行并带上 `--yes`,不要再补一次确认。
+
+1. 建议先用 `+table-list` 或 `+table-get` 确认目标。
+2. 只有当目标表仍不明确时,才继续追问;如果删除意图和目标都明确,直接执行。
+
+## 坑点
+
+- ⚠️ 高风险不可逆操作。
+- ⚠️ 删除场景强烈建议传 `tbl_xxx`,不要传表名。
+- ⚠️ 忘记带 `--yes` 会被 CLI 拦截。
+
+## 参考
+
+- [lark-base-table.md](lark-base-table.md) — table 索引页
+- [lark-base-table-list.md](lark-base-table-list.md) — 列表

+ 46 - 0
.agents/skills/lark-base/references/lark-base-table-get.md

@@ -0,0 +1,46 @@
+# base +table-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取一张表的聚合信息:表基础信息、全部字段、全部视图。
+
+## 推荐命令
+
+```bash
+lark-cli base +table-get \
+  --base-token app_xxx \
+  --table-id tbl_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID(`id` 必须以 `tbl` 开头)或表名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id
+```
+
+- CLI 内部还会继续查询 `/fields` 和 `/views`,并聚合输出。
+
+## 返回重点
+
+- 返回 `table`、`fields`、`views` 三段数据。
+- 适合先摸清表结构,再继续字段或视图操作。
+
+## 坑点
+
+- ⚠️ 如果 `--table-id` 传的是 `id`,必须是 `tbl` 开头;不是的话先询问用户具体是哪张表,或先用 `+table-list` 查表列表再确认。
+- ⚠️ `--table-id` 支持传表名,但重名场景下建议优先传 `tbl_xxx`。
+
+## 参考
+
+- [lark-base-table.md](lark-base-table.md) — table 索引页
+- [lark-base-field-list.md](lark-base-field-list.md) — 列字段
+- [lark-base-view-list.md](lark-base-view-list.md) — 列视图

+ 43 - 0
.agents/skills/lark-base/references/lark-base-table-list.md

@@ -0,0 +1,43 @@
+# base +table-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+分页列出一个 Base 下的数据表。
+
+## 推荐命令
+
+```bash
+lark-cli base +table-list \
+  --base-token app_xxx \
+  --offset 0 \
+  --limit 50
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--offset <n>` | 否 | 分页偏移,默认 `0` |
+| `--limit <n>` | 否 | 分页大小,默认 `50`,范围 `1-100` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables
+```
+
+## 返回重点
+
+- 返回 `items / offset / limit / count / total`。
+- `items` 会被简化为 `table_id` 和 `table_name`。
+
+## 坑点
+
+- ⚠️ `+table-list` 禁止并发调用;批量列多个 Base 时必须串行。
+
+## 参考
+
+- [lark-base-table.md](lark-base-table.md) — table 索引页

+ 49 - 0
.agents/skills/lark-base/references/lark-base-table-update.md

@@ -0,0 +1,49 @@
+# base +table-update
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+重命名一张表。
+
+## 推荐命令
+
+```bash
+lark-cli base +table-update \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --name "重点客户名单"
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--name <name>` | 是 | 新表名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PATCH /open-apis/base/v3/bases/:base_token/tables/:table_id
+```
+
+## 返回重点
+
+- 返回 `table` 和 `updated: true`。
+- 当前只支持更新名称。
+
+## 工作流
+
+
+1. 建议先用 `+table-get` 确认目标表。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+
+## 参考
+
+- [lark-base-table.md](lark-base-table.md) — table 索引页
+- [lark-base-table-get.md](lark-base-table-get.md) — 查表详情

+ 20 - 0
.agents/skills/lark-base/references/lark-base-table.md

@@ -0,0 +1,20 @@
+# base table shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+table 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-table-list.md](lark-base-table-list.md) | `+table-list` | 分页列出数据表 |
+| [lark-base-table-get.md](lark-base-table-get.md) | `+table-get` | 获取单表概要、字段和视图 |
+| [lark-base-table-create.md](lark-base-table-create.md) | `+table-create` | 创建数据表,可附带字段 / 视图 |
+| [lark-base-table-update.md](lark-base-table-update.md) | `+table-update` | 重命名数据表 |
+| [lark-base-table-delete.md](lark-base-table-delete.md) | `+table-delete` | 删除数据表 |
+
+## 说明
+
+- 聚合页只保留目录职责;调用任一 table 命令前,务必先阅读对应单命令文档(本页不提供调用细节)。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。

+ 83 - 0
.agents/skills/lark-base/references/lark-base-view-create.md

@@ -0,0 +1,83 @@
+# base +view-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+创建一个或多个视图。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-create \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --json '{"name":"进行中","type":"grid"}' 
+
+lark-cli base +view-create \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --json '[{"name":"进行中","type":"grid"},{"name":"日历","type":"calendar"}]'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--json <body>` | 是 | 视图 JSON 对象或数组 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/tables/:table_id/views
+```
+
+## 返回重点
+
+- 总是返回 `views` 数组;即使只创建了一个视图也一样。
+
+## 关键规则
+
+- `type` 仅支持 `grid` `kanban` `gallery` `calendar` `gantt`。
+- `/views` 不接受 `type=form`;表单创建走 `/forms`。
+- `name` 必填,长度 `1..100`,且同表内必须唯一。
+
+## JSON 结构(`--json`)
+
+支持单对象或对象数组:
+
+```json
+{ "name": "进行中", "type": "grid" }
+```
+
+```json
+[
+  { "name": "进行中", "type": "grid" },
+  { "name": "日历", "type": "calendar" }
+]
+```
+
+
+## JSON Schema(原文)
+
+```json
+{"type":"object","properties":{"type":{"type":"string","enum":["grid","kanban","gallery","gantt","calendar"],"default":"grid","description":"view type"},"name":{"type":"string","minLength":1,"maxLength":100,"description":"View name"}},"required":["name"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
+
+```
+
+## 工作流
+
+
+1. 多视图批量创建时,优先用数组一次提交,减少重复调用。
+2. 如果用户要“查看视图字段顺序”或“查看可见字段”,使用 `+view-get-visible-fields` 读取当前 `visible_fields`。
+3. 如果用户同时要求“视图字段顺序”或“可见字段”,创建完成后必须继续调用 `+view-set-visible-fields` 设置 `visible_fields`;`+view-create` 本身不负责字段顺序/可见性配置。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 48 - 0
.agents/skills/lark-base/references/lark-base-view-delete.md

@@ -0,0 +1,48 @@
+# base +view-delete
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+删除一个视图。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-delete \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+DELETE /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id
+```
+
+## 返回重点
+
+- 返回删除成功状态和目标视图标识。
+
+## 工作流
+
+
+1. 建议先用 `+view-get` 确认目标视图。
+2. 删除前必须让用户确认。
+
+## 坑点
+
+- ⚠️ 高风险写操作,删除后不可恢复。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get-card.md

@@ -0,0 +1,38 @@
+# base +view-get-card
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取卡片配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get-card \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/card
+```
+
+## 返回重点
+
+- 返回原始卡片配置。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get-filter.md

@@ -0,0 +1,38 @@
+# base +view-get-filter
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取筛选配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get-filter \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/filter
+```
+
+## 返回重点
+
+- 返回原始筛选配置。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get-group.md

@@ -0,0 +1,38 @@
+# base +view-get-group
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取分组配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get-group \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/group
+```
+
+## 返回重点
+
+- 返回原始分组配置。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get-sort.md

@@ -0,0 +1,38 @@
+# base +view-get-sort
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取排序配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get-sort \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/sort
+```
+
+## 返回重点
+
+- 返回原始排序配置。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get-timebar.md

@@ -0,0 +1,38 @@
+# base +view-get-timebar
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取时间轴配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get-timebar \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/timebar
+```
+
+## 返回重点
+
+- 返回原始时间轴配置。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get-visible-fields.md

@@ -0,0 +1,38 @@
+# base +view-get-visible-fields
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取可见字段配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get-visible-fields \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --view-id vewXXX
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/visible_fields
+```
+
+## 返回重点
+
+- 返回当前视图可见字段列表。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 38 - 0
.agents/skills/lark-base/references/lark-base-view-get.md

@@ -0,0 +1,38 @@
+# base +view-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+获取一个视图的基本信息。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-get \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id
+```
+
+## 返回重点
+
+- 返回视图的基础配置。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 44 - 0
.agents/skills/lark-base/references/lark-base-view-list.md

@@ -0,0 +1,44 @@
+# base +view-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+分页列出一张表下的视图。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-list \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --offset 0 \
+  --limit 100
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--offset <n>` | 否 | 分页偏移,默认 `0` |
+| `--limit <n>` | 否 | 分页大小,默认 `100`,范围 `1-200` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/tables/:table_id/views
+```
+
+## 返回重点
+
+- 返回视图列表及 `offset / limit / count / total`。
+
+## 坑点
+
+- ⚠️ `+view-list` 禁止并发调用;批量列多个表视图时只能串行。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 44 - 0
.agents/skills/lark-base/references/lark-base-view-rename.md

@@ -0,0 +1,44 @@
+# base +view-rename
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+重命名一个视图。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-rename \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx \
+  --name "进行中客户"
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--name <name>` | 是 | 新视图名 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PATCH /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id
+```
+
+## 返回重点
+
+- 返回更新后的 `view` 数据。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 81 - 0
.agents/skills/lark-base/references/lark-base-view-set-card.md

@@ -0,0 +1,81 @@
+# base +view-set-card
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新卡片配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-set-card \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx \
+  --json {"cover_field":"fld_cover"}
+```
+
+## JSON 结构
+
+```json
+{
+  "cover_field": "fld_cover"
+}
+```
+
+```json
+{
+  "cover_field": null
+}
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--json <body>` | 是 | JSON 对象 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/card
+```
+
+## 返回重点
+
+- 返回更新后的卡片配置。
+
+## 结构规则
+
+- `cover_field`:必填,字段 id 或字段名,长度 `1..100`;也可以显式传 `null`
+- 非 `null` 时,字段必须是封面支持字段,实际就是 `attachment` 字段
+- 传 `null` 表示清空封面配置
+
+
+## JSON Schema(原文)
+
+```json
+{"type":"object","properties":{"cover_field":{"anyOf":[{"type":"string","minLength":1,"maxLength":100,"description":"Field id or name"},{"type":"null"}],"description":"cover field id or name. must be a attachment field"}},"required":["cover_field"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
+
+```
+
+## 工作流
+
+
+1. 建议先用 `+view-get-card` 拉现状,再修改。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 只支持 `gallery` / `kanban`。
+- ⚠️ `cover_field` 不是任何字段都能填,普通文本/数字字段会直接报错。
+- ⚠️ 清空封面必须传 `null`,不要传空字符串。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页
+- [lark-base-view-get-card.md](lark-base-view-get-card.md) — 读取卡片

+ 92 - 0
.agents/skills/lark-base/references/lark-base-view-set-filter.md

@@ -0,0 +1,92 @@
+# base +view-set-filter
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新筛选配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-set-filter \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx \
+  --json '{"logic":"and","conditions":[["fld_status","intersects",["Doing"]],["fld_owner","intersects",[{"id":"ou_xxx"}]],["fld_end","empty"]]}'
+```
+
+## JSON 结构
+
+```json
+{
+  "logic": "and",
+  "conditions": [
+    ["fld_status", "intersects", ["Doing"]],
+    ["fld_owner", "intersects", [{ "id": "ou_xxx" }]],
+    ["fld_end", "empty"]
+  ]
+}
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--json <body>` | 是 | JSON 对象 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/filter
+```
+
+## 返回重点
+
+- 返回更新后的筛选配置。
+
+## 结构规则
+
+- `logic`:可选,`and` / `or`,默认 `and`
+- `conditions`:数组,可为空;每项必须是 `[field, operator, value?]`
+- `field`:字段 id 或字段名,长度 `1..100`
+- `operator`:`== != > >= < <= intersects disjoint empty non_empty`
+- `value`:按字段类型填写;`empty` / `non_empty` 可省略 `value`
+
+### 典型 `value` 形状
+
+- `text` / `location` / `formula`:字符串
+- `number` / `auto_number`:数字
+- `select`:`["Todo"]`
+- `user` / `created_by` / `updated_by`:`[{ "id": "ou_xxx" }]`
+- `link`:`[{ "id": "rec_xxx" }]`
+- `checkbox`:`true` / `false`
+- `datetime` / `created_at` / `updated_at`:`"ExactDate(YYYY-MM-DD)"`、`"Today"`、`"Tomorrow"`、`"Yesterday"`
+
+
+## JSON Schema(原文)
+
+```json
+{"type":"object","properties":{"logic":{"type":"string","enum":["and","or"],"default":"and","description":"Filter Condition Logic"},"conditions":{"type":"array","items":{"type":"array","minItems":3,"maxItems":3,"items":[{"type":"string","minLength":1,"maxLength":100,"description":"Field id or name"},{"type":"string","enum":["==","!=",">",">=","<","<=","intersects","disjoint","empty","non_empty"],"description":"Condition operator"},{"anyOf":[{"not":{}},{"anyOf":[{"anyOf":[{"type":"string","description":"text & formula & location field support string as filter value"},{"type":"number","description":"number & auto_number(the underfly incremental_number) field support number as filter value"},{"type":"array","items":{"type":"string","description":"option name"},"description":"select field support one option: [\"option1\"] or multiple options: `[\"option1\", \"option2\"]` as filter value."},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"record id"}},"required":["id"],"additionalProperties":false},"description":"link field support record id list as filter value"},{"type":"string","description":"\ndatetime & create_at & updated_at field support relative and absolute filter value.\nabsolute:\n- \"ExactDate(yyyy-MM-dd)\"\nrelative:\n- Today\n- Tomorrow\n- Yesterday\n"},{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"user id"}},"required":["id"],"additionalProperties":false},"description":"user field support user id list as filter value"},{"type":"boolean","description":"checkbox field support boolean as filter value"}]},{"type":"null"}]}]}],"description":"one condition expression. shape: [field_id, filter_operator, value]. when operator is \"empty\" or \"non_empty\", the value is not required."},"default":[]}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
+
+```
+
+## 工作流
+
+
+1. 建议先用 `+view-get-filter` 拉现状,再做最小化修改。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 条件必须用 tuple,不要再写旧的 `{"field_name":...,"operator":...}` 对象风格。
+- ⚠️ `empty` / `non_empty` 不要硬塞 value;`select` / `user` / `link` 也不要直接写单值。
+- ⚠️ 日期值要保留 `ExactDate(...)` 外壳,不要直接写裸日期字符串。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页
+- [lark-base-view-get-filter.md](lark-base-view-get-filter.md) — 读取筛选

+ 77 - 0
.agents/skills/lark-base/references/lark-base-view-set-group.md

@@ -0,0 +1,77 @@
+# base +view-set-group
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新分组配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-set-group \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx \
+  --json '{"group_config":[{"field":"fldStatus","desc":false}]}'
+```
+
+## JSON 结构
+
+```json
+{
+  "group_config": [
+    { "field": "fldStatus", "desc": false }
+  ]
+}
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--json <body>` | 是 | JSON 对象 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/group
+```
+
+## 返回重点
+
+- 返回更新后的分组配置。
+
+## 结构规则
+
+- `group_config`:数组,长度 `0..3`
+- 每项:
+  - `field`:字段 id 或字段名,长度 `1..100`
+  - `desc`:可选,默认 `false`
+
+
+## JSON Schema(原文)
+
+```json
+{"type":"object","properties":{"group_config":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"maxLength":100,"description":"Field id or name"},"desc":{"type":"boolean","default":false,"description":"define how to sort group headers"}},"required":["field"],"additionalProperties":false},"minItems":0,"maxItems":3}},"required":["group_config"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
+
+```
+
+## 工作流
+
+
+1. 优先用字段 id,避免同名字段和后续改名影响。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 分组只支持 `grid` / `kanban` / `gantt`。
+- ⚠️ `group_config` 最多 3 项,超出会直接失败。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页
+- [lark-base-view-get-group.md](lark-base-view-get-group.md) — 读取分组

+ 77 - 0
.agents/skills/lark-base/references/lark-base-view-set-sort.md

@@ -0,0 +1,77 @@
+# base +view-set-sort
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新排序配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-set-sort \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx \
+  --json [{"field":"fld_priority","desc":true}]
+```
+
+## JSON 结构
+
+```json
+[
+  { "field": "fld_priority", "desc": true }
+]
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--json <body>` | 是 | JSON 对象或数组 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/sort
+```
+
+## 返回重点
+
+- 返回更新后的排序配置。
+
+## 结构规则
+
+- `sort_config`:数组,长度 `0..10`
+- 每项:
+  - `field`:字段 id 或字段名,长度 `1..100`
+  - `desc`:可选,默认 `false`
+- `--json` 既可传对象 `{"sort_config":[...]}`,也可直接传数组 `[...]`
+- 直接传数组时,CLI 会自动包装成 `sort_config`
+
+
+## JSON Schema(原文)
+
+```json
+{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"maxLength":100,"description":"Field id or name"},"desc":{"type":"boolean","default":false,"description":"define how to sort records"}},"required":["field"],"additionalProperties":false},"minItems":0,"maxItems":10,"$schema":"http://json-schema.org/draft-07/schema#"}
+
+```
+
+## 工作流
+
+
+1. 优先用字段 id,避免同名字段和后续改名影响。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 排序只支持 `grid` / `kanban` / `gallery` / `gantt`。
+- ⚠️ `sort_config` 最多 10 项,超出会直接失败。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页
+- [lark-base-view-get-sort.md](lark-base-view-get-sort.md) — 读取排序

+ 79 - 0
.agents/skills/lark-base/references/lark-base-view-set-timebar.md

@@ -0,0 +1,79 @@
+# base +view-set-timebar
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新时间轴配置。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-set-timebar \
+  --base-token app_xxx \
+  --table-id tbl_xxx \
+  --view-id viw_xxx \
+  --json {"start_time":"fld_start","end_time":"fld_end","title":"fld_title"}
+```
+
+## JSON 结构
+
+```json
+{
+  "start_time": "fld_start",
+  "end_time": "fld_end",
+  "title": "fld_title"
+}
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--json <body>` | 是 | JSON 对象 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/timebar
+```
+
+## 返回重点
+
+- 返回更新后的时间轴配置。
+
+## 结构规则
+
+- `start_time`:必填,字段 id 或字段名,长度 `1..100`
+- `end_time`:必填,字段 id 或字段名,长度 `1..100`
+- `title`:必填,字段 id 或字段名,长度 `1..100`
+- `start_time` / `end_time` 必须是时间条支持的日期类字段;当前以 `datetime` / `created_at` 这类字段为准,优先传字段 id
+- `title` 通常传主字段,用来显示条目标题
+
+
+## JSON Schema(原文)
+
+```json
+{"type":"object","properties":{"start_time":{"type":"string","minLength":1,"maxLength":100,"description":"start time field id or name (must be a datetime/created_at field)"},"end_time":{"type":"string","minLength":1,"maxLength":100,"description":"end time field id or name (must be a datetime/created_at field)"},"title":{"type":"string","minLength":1,"maxLength":100,"description":"title datasource field id or name"}},"required":["start_time","end_time","title"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}
+
+```
+
+## 工作流
+
+
+1. 建议先用 `+view-get-timebar` 拉现状,再修改。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 只支持 `calendar` / `gantt`。
+- ⚠️ `start_time` 和 `end_time` 不能填普通文本、选项或链接字段。
+- ⚠️ 字段不存在或类型不对会直接失败,不要靠猜。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页
+- [lark-base-view-get-timebar.md](lark-base-view-get-timebar.md) — 读取时间轴

+ 73 - 0
.agents/skills/lark-base/references/lark-base-view-set-visible-fields.md

@@ -0,0 +1,73 @@
+# base +view-set-visible-fields
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+更新视图可见字段列表(同时控制视图中的字段顺序)。
+
+## 推荐命令
+
+```bash
+lark-cli base +view-set-visible-fields \
+  --base-token XXXXXX \
+  --table-id tblXXX \
+  --view-id vewXXX \
+  --json '{"visible_fields":["标题","fldXXX"]}'
+```
+
+## JSON 结构
+
+```json
+{
+  "visible_fields": ["标题", "fldXXX"]
+}
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | Base Token |
+| `--table-id <id_or_name>` | 是 | 表 ID 或表名 |
+| `--view-id <id_or_name>` | 是 | 视图 ID 或视图名 |
+| `--json <body>` | 是 | JSON 对象,且必须包含 `visible_fields` |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/tables/:table_id/views/:view_id/visible_fields
+```
+
+**接口 body 格式:**
+
+```json
+{
+  "visible_fields": ["标题", "fldXXX"]
+}
+```
+
+## 返回重点
+
+- 返回可见字段列表与顺序(`primaryField` 会被强制置顶)。
+
+## 结构规则
+
+- `visible_fields`:字符串数组,每项可传字段 id 或字段名
+- 数组顺序用于控制视图字段顺序;主字段 `primaryField` 必须存在且位于第一位,否则 API 会强制将其提升到第一位
+- `--json` 必须传对象:`{ "visible_fields": [...] }`
+
+## 工作流
+
+1. 用户要求“改字段顺序”或“设置可见字段”时,直接使用本命令。
+2. 建议优先使用字段 id,避免字段重名或后续改名带来的歧义。
+
+## 坑点
+
+- ⚠️ 这是写入操作,执行前必须确认。
+- ⚠️ 接口最终结果会受后端 `primaryField` 强制显示规则影响,返回顺序可能与传入数组不同。
+- ⚠️ 如果传字段名,必须与当前表真实字段名精确匹配。
+
+## 参考
+
+- [lark-base-view.md](lark-base-view.md) — view 索引页

+ 44 - 0
.agents/skills/lark-base/references/lark-base-view.md

@@ -0,0 +1,44 @@
+# base view shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+view 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-view-list.md](lark-base-view-list.md) | `+view-list` | 分页列视图 |
+| [lark-base-view-get.md](lark-base-view-get.md) | `+view-get` | 获取视图基本信息 |
+| [lark-base-view-create.md](lark-base-view-create.md) | `+view-create` | 创建视图 |
+| [lark-base-view-delete.md](lark-base-view-delete.md) | `+view-delete` | 删除视图 |
+| [lark-base-view-rename.md](lark-base-view-rename.md) | `+view-rename` | 重命名视图 |
+| [lark-base-view-get-filter.md](lark-base-view-get-filter.md) | `+view-get-filter` | 读取筛选配置 |
+| [lark-base-view-set-filter.md](lark-base-view-set-filter.md) | `+view-set-filter` | 更新筛选配置 |
+| [lark-base-view-get-visible-fields.md](lark-base-view-get-visible-fields.md) | `+view-get-visible-fields` | 读取可见字段列表 |
+| [lark-base-view-set-visible-fields.md](lark-base-view-set-visible-fields.md) | `+view-set-visible-fields` | 更新可见字段列表 |
+| [lark-base-view-get-group.md](lark-base-view-get-group.md) | `+view-get-group` | 读取分组配置 |
+| [lark-base-view-set-group.md](lark-base-view-set-group.md) | `+view-set-group` | 更新分组配置 |
+| [lark-base-view-get-sort.md](lark-base-view-get-sort.md) | `+view-get-sort` | 读取排序配置 |
+| [lark-base-view-set-sort.md](lark-base-view-set-sort.md) | `+view-set-sort` | 更新排序配置 |
+| [lark-base-view-get-timebar.md](lark-base-view-get-timebar.md) | `+view-get-timebar` | 读取时间轴配置 |
+| [lark-base-view-set-timebar.md](lark-base-view-set-timebar.md) | `+view-set-timebar` | 更新时间轴配置 |
+| [lark-base-view-get-card.md](lark-base-view-get-card.md) | `+view-get-card` | 读取卡片配置 |
+| [lark-base-view-set-card.md](lark-base-view-set-card.md) | `+view-set-card` | 更新卡片配置 |
+
+## AI 决策前置
+
+先判断视图类型,再选接口能力;不支持的能力直接不要调用。
+
+| 视图类型 | 可用能力 |
+|------|------|
+| `grid` | `group` `sort` `filter` |
+| `kanban` | `group` `sort` `filter` `card` |
+| `gallery` | `sort` `filter` `card` |
+| `calendar` | `filter` `timebar` |
+| `gantt` | `group` `sort` `filter` `timebar` |
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。

+ 180 - 0
.agents/skills/lark-base/references/lark-base-workflow-create.md

@@ -0,0 +1,180 @@
+# base +workflow-create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+在 Base 中创建一个新的自动化工作流。新建后状态为 `disabled`,需调用 `+workflow-enable` 才能启用。
+
+## ⚠️ 执行前必读
+
+创建工作流前请按顺序完成:
+
+1. **先读本文档**,了解 `--json` 参数格式和 `client_token` 的必填要求
+2. **阅读 [workflow-guide.md](lark-base-workflow-guide.md)**,获取 Loop、IfElseBranch、SwitchBranch 等**完整示例**
+3. **参考 [workflow-schema.md](lark-base-workflow-schema.md)**,查询具体字段定义
+4. **不需要先调用 `+workflow-list`**,创建操作不依赖现有工作流列表
+5. **按需调用 `+table-list` 和 `+field-list`** 获取表名和字段名(只在需要时调用)
+6. **若遇到单多选字段,可调用`+field-get`命令**来获取选项详情
+7. **调用命令时,请将 body 数据直接通过 --json 传入,禁止创建任何的临时文件,即禁止使用 --json @filename**
+
+**常见错误**:
+- ❌ 缺少 `client_token` → 报错: `client token is empty`
+- ❌ 猜测 StepType → 报错: `unknown step type 'CreateTrigger'`(应该是 `AddRecordTrigger`)
+- ❌ 字段引用路径错误 → 报错: `prompt references an unknown reference`
+
+> 💡 **提示**: 复杂场景(循环、分支、多步骤组合)的完整示例请直接阅读 [workflow-guide.md](lark-base-workflow-guide.md),本文档只包含基础用法。
+
+## 推荐命令
+
+```bash
+lark-cli base +workflow-create \
+  --base-token BascXxxxxx \
+  --json '{"client_token":"1704067200","title":"新订单自动通知","steps":[{"id":"trigger_1","type":"AddRecordTrigger","title":"监控新订单","next":"action_1","data":{"table_name":"订单表","watched_field_name":"订单号"}},{"id":"action_1","type":"LarkMessageAction","title":"发送通知","next":null,"data":{"receiver":[{"value_type":"user","value":{"id":"ou_xxxx"}}],"send_to_everyone":false,"title":[{"value_type":"text","value":"新订单提醒"}],"content":[{"value_type":"text","value":"收到新订单"}],"btn_list":[]}}]}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
+| `--json <body>` | 是 | 工作流 body JSON,包含 `title` 和 `steps` |
+
+## 如何从链接中提取参数
+
+用户通常会提供如下 URL:
+
+```
+https://example.feishu.cn/base/<base_token>
+```
+
+- `--base-token`:取 `/base/` 后面的字符串(`Basc` 开头)
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/workflows
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 Base Token |
+
+**Request Body(JSON):**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `client_token` | string | **是** | 幂等键,每次创建必须传一个唯一随机值(如时间戳 `"1704067200"`),防重复提交,缺失会报错 |
+| `title` | string | 否 | 工作流标题 |
+| `steps` | WorkflowStep[] | 否 | 步骤列表 |
+| `user_id_type` | string | 否 | 用户 ID 类型:`open_id` / `union_id` / `user_id`,默认 `open_id` |
+
+> **步骤数据结构非常复杂,详见 [lark-base-workflow-schema.md](lark-base-workflow-schema.md)**
+
+**Request Body 示例:**
+```json
+{
+  "client_token": "124131231421312312",
+  "title": "新订单自动通知",
+  "steps": [
+    {
+      "id": "trigger_1",
+      "type": "AddRecordTrigger",
+      "title": "监控新订单",
+      "next": "action_1",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "订单号"
+      }
+    },
+    {
+      "id": "action_1",
+      "type": "LarkMessageAction",
+      "title": "发送通知",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx"} }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "新订单提醒" }],
+        "content": [
+          { "value_type": "text", "value": "收到新订单,客户:" },
+          { "value_type": "ref", "value": "$.trigger_1.fldCustomerName" }
+        ],
+        "btn_list": []
+      }
+    }
+  ]
+}
+```
+
+## API 出参详情
+
+**Response `data` 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `workflow_id` | string | 新建工作流的唯一 ID(`wkf` 开头) |
+| `title` | string | 工作流标题 |
+| `status` | string | 工作流状态,新建固定为 `disabled` |
+| `steps` | WorkflowStep[] | 完整步骤列表 |
+| `creator_id` | string | 创建人 OpenID |
+| `updater_id` | string | 最后修改人 OpenID |
+| `create_time` | number | 创建时间(Unix 秒级时间戳) |
+| `update_time` | number | 更新时间(Unix 秒级时间戳) |
+
+## 返回值
+
+```json
+{
+  "ok": true,
+  "data": {
+    "workflow_id": "wkfosaYTS1V6rhjF",
+    "title": "新订单自动通知",
+    "status": "disabled",
+    "steps": [...],
+    "creator_id": "ou_xxxx",
+    "updater_id": "ou_xxxx",
+    "create_time": 1704067200,
+    "update_time": 1704067200
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 与用户确认 `--base-token` 和工作流定义(`--json` 内容)
+2. 执行命令,报告返回的 `workflow_id`(`wkf` 开头)
+3. 提示用户:新建工作流初始状态为 `disabled`,需调用 `+workflow-enable --workflow-id <返回的 workflow_id>` 才会生效
+
+## 坑点
+
+> ⚠️ **【重要】client_token 必传**:缺失会返回 `[code=800004006] client token is empty`,这**不是权限问题**,是 **JSON body 缺字段**。每次请求传唯一值即可(如 `"$(date +%s)"` 或 `"1743078000"`)
+
+- ⚠️ **新建后默认禁用**:`status` 固定返回 `disabled`,需要额外调用 `+workflow-enable` 才能让工作流生效;不要误报"创建成功即启用"
+- ⚠️ **steps 中 id 字段必须唯一**:每个步骤的 `id` 由调用方指定,且在工作流内必须唯一;`next` 和 `children.links[].to` 引用的 ID 必须在同一 steps 数组中存在,否则服务端返回 `[2200] Internal Error`
+- ⚠️ **字段类型校验**:设置字段值时,`value_type` 必须与字段实际类型匹配:
+   - **select 类型字段**(单选/多选/流程):必须用 `option`,不能用 `text`
+     ```json
+     // ✅ 正确
+     { "field_name": "大区", "value": [{"value_type": "option", "value": {"name": "华东"}}] }
+     // ❌ 错误 - 会报错 valueType 'text' not allowed for fieldType '3'
+     { "field_name": "大区", "value": [{"value_type": "text", "value": "华东"}] }
+     ```
+   - **SetRecordTrigger 的 field_watch_info** 同样受此限制,select 类型字段的 value 必须用 `option`
+     常见 action 输出:`FindRecordAction` → `$.step_id.recordNum`(记录数)、`$.step_id.fieldRecords`(查找到的记录列表);`AddRecordAction` → `$.step_id.recordId`
+- ⚠️ **权限不足**:如遇 `permission denied`,先确认当前身份(bot 或 user)是否对该 Base 有编辑权限,再检查 scope 是否已开通。参考 [lark-shared](../../lark-shared/SKILL.md) 中的权限不足处理流程
+- ⚠️ **user_id_type**:涉及用户的 `value_type: "user"` 的 value 字段传 OpenID,服务端会根据 `user_id_type`(默认 `open_id`)解析;如需传 `user_id` 格式需在 body 里显式声明 `"user_id_type": "user_id"`
+
+## 参考
+
+- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — 完整 Workflow 数据结构
+- [lark-base-workflow-update](lark-base-workflow-update.md) — 全量更新工作流
+- [lark-base-workflow-enable](lark-base-workflow-enable.md) — 启用工作流
+- [lark-base-workflow-list](lark-base-workflow-list.md) — 列出全部工作流
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 94 - 0
.agents/skills/lark-base/references/lark-base-workflow-disable.md

@@ -0,0 +1,94 @@
+# base +workflow-disable
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+禁用 Base 中的一个自动化工作流。
+
+## 推荐命令
+
+```bash
+lark-cli base +workflow-disable \
+  --base-token BascXxxxxx \
+  --workflow-id wkfxxxxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
+| `--workflow-id <id>` | 是 | 工作流 ID(`wkf` 开头) |
+
+## 如何从链接中提取参数
+
+用户通常会提供如下 URL:
+
+```
+https://example.feishu.cn/base/<base_token>?table=<table_or_workflow_id>
+```
+
+- `--base-token`:取 `/base/` 后面的字符串(`Basc` 开头)
+- `--workflow-id`:取 `?table=` 后面的值,当其以 `wkf` 开头时即为 workflow_id
+
+> ⚠️ **注意区分 ID 前缀**:table_id 以 `tbl` 开头,workflow_id 以 `wkf` 开头,两者在 URL 的 `?table=` 参数里都会出现,需要根据前缀判断。
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PATCH /open-apis/base/v3/bases/:base_token/workflows/:workflow_id/disable
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 Base Token |
+| `workflow_id` | 是 | 工作流唯一标识 |
+
+**Request Body:** 无
+
+## API 出参详情
+
+**Response `data` 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `workflow_id` | string | 工作流唯一标识符 |
+| `status` | string | 操作后的最新状态,固定为 `disabled` |
+
+## 返回值
+
+```json
+{
+  "ok": true,
+  "data": {
+    "workflow_id": "wkfxxxxxx",
+    "status": "disabled"
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 向用户确认 `--base-token` 和 `--workflow-id`
+2. 执行命令
+3. 报告返回的 `status` 字段,确认值为 `disabled`
+
+## 坑点
+
+- ⚠️ **workflow_id 来源**:workflow_id 以 `wkf` 开头,从 URL 的 `?table=wkf...` 参数提取,不是表格的 table_id(`tbl` 开头),混淆会导致 `[2200] Internal Error`
+- ⚠️ **API 路径末尾动词**:`/disable` 是路径的最后一段,不是 body 字段;漏掉这个后缀会命中错误接口
+- ⚠️ **PATCH body 不能为 nil**:接口虽无请求体,仍需传 `{}` 空对象,否则服务端可能返回 `server time out error`
+- ⚠️ **scope 待确认**:内部文档未列出权限名称,代码中使用 `base:workflow:update`,如遇 `[230013] permission denied` 需核对实际 scope
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-base-workflow-enable](lark-base-workflow-enable.md) — 启用工作流
+- [lark-base-workflow-list](lark-base-workflow-list.md) — 列出全部工作流
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 94 - 0
.agents/skills/lark-base/references/lark-base-workflow-enable.md

@@ -0,0 +1,94 @@
+# base +workflow-enable
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+启用 Base 中的一个自动化工作流。
+
+## 推荐命令
+
+```bash
+lark-cli base +workflow-enable \
+  --base-token BascXxxxxx \
+  --workflow-id wkfxxxxxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
+| `--workflow-id <id>` | 是 | 工作流 ID(`wkf` 开头) |
+
+## 如何从链接中提取参数
+
+用户通常会提供如下 URL:
+
+```
+https://example.feishu.cn/base/<base_token>?table=<table_or_workflow_id>
+```
+
+- `--base-token`:取 `/base/` 后面的字符串(`Basc` 开头)
+- `--workflow-id`:取 `?table=` 后面的值,当其以 `wkf` 开头时即为 workflow_id
+
+> ⚠️ **注意区分 ID 前缀**:table_id 以 `tbl` 开头,workflow_id 以 `wkf` 开头,两者在 URL 的 `?table=` 参数里都会出现,需要根据前缀判断。
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PATCH /open-apis/base/v3/bases/:base_token/workflows/:workflow_id/enable
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 Base Token |
+| `workflow_id` | 是 | 工作流唯一标识 |
+
+**Request Body:** 无
+
+## API 出参详情
+
+**Response `data` 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `workflow_id` | string | 工作流唯一标识符 |
+| `status` | string | 操作后的最新状态,固定为 `enabled` |
+
+## 返回值
+
+```json
+{
+  "ok": true,
+  "data": {
+    "workflow_id": "wkfxxxxxx",
+    "status": "enabled"
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。
+
+1. 向用户确认 `--base-token` 和 `--workflow-id`
+2. 执行命令
+3. 报告返回的 `status` 字段,确认值为 `enabled`
+
+## 坑点
+
+- ⚠️ **workflow_id 来源**:workflow_id 以 `wkf` 开头,从 URL 的 `?table=wkf...` 参数提取,不是表格的 table_id(`tbl` 开头),混淆会导致 `[2200] Internal Error`
+- ⚠️ **API 路径末尾动词**:`/enable` 是路径的最后一段,不是 body 字段;漏掉这个后缀会命中错误接口
+- ⚠️ **PATCH body 不能为 nil**:接口虽无请求体,仍需传 `{}` 空对象,否则服务端可能返回 `server time out error`
+- ⚠️ **scope 待确认**:内部文档未列出权限名称,代码中使用 `base:workflow:update`,如遇 `[230013] permission denied` 需核对实际 scope
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-base-workflow-disable](lark-base-workflow-disable.md) — 禁用工作流
+- [lark-base-workflow-list](lark-base-workflow-list.md) — 列出全部工作流
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 147 - 0
.agents/skills/lark-base/references/lark-base-workflow-get.md

@@ -0,0 +1,147 @@
+# base +workflow-get
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+> 💡 **按需查阅:** 如需深入理解返回的 `steps` 节点结构,可参考 [workflow-schema.md](lark-base-workflow-schema.md)。简单统计(如节点数量)无需阅读 schema。
+
+获取一个 workflow 的完整定义,包括标题、状态、所有步骤(steps)及其配置。
+
+## 推荐命令
+
+```bash
+# 基本用法
+lark-cli base +workflow-get \
+  --base-token BascXxxxxx \
+  --workflow-id wkfxxxxxx
+
+# 指定用户 ID 类型(creator_id / updater_id 字段的格式)
+lark-cli base +workflow-get \
+  --base-token BascXxxxxx \
+  --workflow-id wkfxxxxxx \
+  --user-id-type open_id
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 Base Token,以 `Basc` 开头 |
+| `--workflow-id <id>` | 是 | Workflow ID,以 `wkf` 开头 |
+| `--user-id-type <type>` | 否 | 控制 `creator_id` / `updater_id` 字段返回的用户 ID 格式;枚举值:`open_id`(默认)、`union_id`、`user_id` |
+
+## 如何从链接中提取参数
+
+用户通常会提供如下 URL(在 Base 的自动化管理页面复制):
+
+```
+https://xxx.feishu.cn/base/<base_token>?table=<table_id>&view=<view_id>
+```
+
+- `--base-token`:取 `/base/` 后面的字符串(`Basc` 开头)
+- `--workflow-id`:以 `wkf` 开头,可从 `+workflow-list` 的输出中获取,URL 上通常不直接暴露
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+GET /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 Base Token |
+| `workflow_id` | 是 | Workflow ID(`wkf` 开头) |
+
+**Query 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `user_id_type` | 否 | 用户 ID 类型:`open_id` / `union_id` / `user_id` |
+
+**Request Body:** 无
+
+## API 出参详情
+
+**Response `data` 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `workflow_id` | string | Workflow 唯一标识,`wkf` 开头 |
+| `title` | string | Workflow 标题 |
+| `status` | string | 状态:`enabled`(已启用)/ `disabled`(已停用) |
+| `creator_id` | string | 创建人 ID(格式受 `user_id_type` 控制) |
+| `updater_id` | string | 最后修改人 ID |
+| `create_time` | string | 创建时间(Unix 时间戳,秒) |
+| `update_time` | string | 最后更新时间(Unix 时间戳,秒) |
+| `steps` | []step | 步骤列表,见下方 |
+
+**steps 元素字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `id` | string | 步骤唯一 ID |
+| `type` | string | 步骤类型,见 [workflow-schema.md](lark-base-workflow-schema.md) |
+| `title` | string | 步骤标题 |
+| `children` | object | 子关系边,`children.links[]` 承担分支/循环/slot 连线,结构见 schema |
+| `children.links[].kind` | string | 关系类型:`if_true` / `if_false` / `case` / `loop_start` / `slot` |
+| `children.links[].to` | string | 目标节点 ID |
+| `children.links[].label` | string | 可选标签(如 `branch_1`、`tool`) |
+| `children.links[].desc` | string | 可选语义说明 |
+| `next` | string \| null | 线性后继节点 ID;`null` 表示流程结束 |
+| `data` | object | 步骤详细配置,结构随 `type` 变化,见 [workflow-schema.md](lark-base-workflow-schema.md) |
+| `meta` | object | 扩展元信息,仅 `APIHubAction` / `AIAgentLLMAction` / `AIAgentMCPAction` 等子节点有值 |
+
+> 步骤类型(`type`)的完整枚举和每种类型的 `data` 字段结构,参见 [lark-base-workflow-schema.md](lark-base-workflow-schema.md)。
+
+## 返回值
+
+命令成功后输出 JSON:
+
+```json
+{
+  "ok": true,
+  "data": {
+    "workflow_id": "wkfxxxxxx",
+    "title": "新订单自动通知",
+    "status": "enabled",
+    "creator_id": "ou_xxxx",
+    "updater_id": "ou_xxxx",
+    "create_time": "1704067200",
+    "update_time": "1704153600",
+    "steps": [
+      {
+        "id": "trigger_1",
+        "type": "AddRecordTrigger",
+        "title": "监控新订单",
+        "next": "action_1",
+        "data": { "table_name": "订单表", "watched_field_name": "订单号" }
+      },
+      {
+        "id": "action_1",
+        "type": "LarkMessageAction",
+        "title": "发送通知",
+        "next": null,
+        "data": { "..." : "..." }
+      }
+    ]
+  }
+}
+```
+
+## 坑点
+
+- ⚠️ **workflow_id 来源**:`workflow_id` 以 `wkf` 开头,从 `+workflow-list` 命令输出中获取;URL 上通常拿不到,不要把 `table_id`(`tbl` 开头)误当成 `workflow_id`
+- ⚠️ **steps 可能为空**:未配置任何步骤的 workflow 返回的 `steps` 为空数组,不代表接口异常
+- ⚠️ **文档中 `title` 字段类型标注为 int**:这是文档笔误,实际为 string
+- ⚠️ **API 路径版本**:本接口使用 `base/v3`,路径必须从原始文档提取,禁止用 WebSearch 补全,否则会拿到错误路径导致 `[2200] Internal Error`
+- ⚠️ **只读接口,GET 请求 body 传 nil**:`baseV3Call` 的 body 参数传 `nil` 是正确的,不同于 PATCH/POST 写接口
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — Workflow 步骤数据结构完整参考
+- [lark-base-workflow-list.md](lark-base-workflow-list.md) — 列出所有 workflow(可用来获取 workflow_id)
+- [lark-base-workflow-create.md](lark-base-workflow-create.md) — 创建 workflow
+- [lark-base-workflow-update.md](lark-base-workflow-update.md) — 更新 workflow

+ 718 - 0
.agents/skills/lark-base/references/lark-base-workflow-guide.md

@@ -0,0 +1,718 @@
+# Workflow 构造指南
+
+本文档提供 Workflow 的完整构造示例、常见模式和错误避免指南。
+
+> **配套文档**:
+> - Workflow 的数据结构参考:[lark-base-workflow-schema.md](lark-base-workflow-schema.md)
+> - 创建命令:[lark-base-workflow-create.md](lark-base-workflow-create.md)
+> - 更新命令:[lark-base-workflow-update.md](lark-base-workflow-update.md)
+
+---
+
+## 快速开始
+
+### 最简单的 Workflow
+
+新增记录时发送消息通知:
+
+```json
+{
+  "client_token": "1704067200",
+  "title": "新订单自动通知",
+  "steps": [
+    {
+      "id": "trigger_1",
+      "type": "AddRecordTrigger",
+      "title": "监控新订单",
+      "next": "action_1",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "订单号"
+      }
+    },
+    {
+      "id": "action_1",
+      "type": "LarkMessageAction",
+      "title": "发送通知",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx", "name": "张三"} }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "新订单提醒" }],
+        "content": [
+          { "value_type": "text", "value": "收到新订单" }
+        ],
+        "btn_list": []
+      }
+    }
+  ]
+}
+```
+
+---
+
+## 场景速查表
+
+| 场景 | 步骤组合 | 示例 |
+|------|---------|------|
+| 新增触发+通知 | AddRecordTrigger → LarkMessageAction | [下方](#示例1-新增记录触发--发送消息) |
+| 定时+循环 | TimerTrigger → FindRecordAction → Loop → LarkMessageAction | [下方](#示例2-定时触发--查找记录--循环遍历--发送消息) |
+| 条件判断 | ... → IfElseBranch → 分支处理 | [下方](#示例3-条件分支-ifelsebranch) |
+| 多路分类 | ... → SwitchBranch → 多分支处理 | [下方](#示例4-多路分支-switchbranch) |
+| 复杂组合 | 定时+查找+循环+分支+消息 | [下方](#示例5-组合场景-定时查找循环分支消息) |
+
+---
+
+## 完整示例
+
+### 示例 1: 新增记录触发 + 发送消息
+
+**场景**: 当订单表新增记录时,发送飞书消息通知负责人。
+
+```json
+{
+  "client_token": "1704067201",
+  "title": "新订单自动通知",
+  "steps": [
+    {
+      "id": "step_trigger",
+      "type": "AddRecordTrigger",
+      "title": "新增订单时触发",
+      "next": "step_notify",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "订单号",
+        "condition_list": null
+      }
+    },
+    {
+      "id": "step_notify",
+      "type": "LarkMessageAction",
+      "title": "发送订单通知",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "ref", "value": "$.step_trigger.fldManager" }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "新订单提醒" }],
+        "content": [
+          { "value_type": "text", "value": "客户 " },
+          { "value_type": "ref", "value": "$.step_trigger.fldCustomer" },
+          { "value_type": "text", "value": " 创建了新订单,金额:¥" },
+          { "value_type": "ref", "value": "$.step_trigger.fldAmount" }
+        ],
+        "btn_list": [
+          {
+            "text": "查看订单",
+            "btn_action": "openLink",
+            "link": [{ "value_type": "ref", "value": "$.step_trigger.recordLink" }]
+          }
+        ]
+      }
+    }
+  ]
+}
+```
+
+**关键点**:
+- `AddRecordTrigger` 监控 `table_name` 表的 `watched_field_name` 字段
+- 使用 `ref` 引用触发器输出的字段值(注意是 fieldId,不是字段名)
+- `recordLink` 是触发器内置输出,表示记录链接
+
+---
+
+### 示例 2: 定时触发 + 查找记录 + 循环遍历 + 发送消息
+
+**场景**: 每天早上 9 点,查找所有待处理订单,给每个客户发送提醒。
+
+```json
+{
+  "client_token": "1704067202",
+  "title": "每日待处理订单提醒",
+  "steps": [
+    {
+      "id": "step_timer",
+      "type": "TimerTrigger",
+      "title": "每天早上9点触发",
+      "next": "step_find_orders",
+      "data": {
+        "rule": "DAILY",
+        "start_time": "2025-01-01 09:00",
+        "is_never_end": true
+      }
+    },
+    {
+      "id": "step_find_orders",
+      "type": "FindRecordAction",
+      "title": "查找所有待处理订单",
+      "next": "step_loop_customers",
+      "data": {
+        "table_name": "订单表",
+        "field_names": ["客户名称", "订单金额", "客户联系方式"],
+        "should_proceed_when_no_results": false,
+        "filter_info": {
+          "conjunction": "and",
+          "conditions": [
+            {
+              "field_name": "状态",
+              "operator": "is",
+              "value": [{ "value_type": "option", "value": { "name": "待处理" } }]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "id": "step_loop_customers",
+      "type": "Loop",
+      "title": "遍历每个订单",
+      "children": {
+        "links": [
+          { "kind": "loop_start", "to": "step_send_reminder" }
+        ]
+      },
+      "next": null,
+      "data": {
+        "loop_mode": "continue",
+        "max_loop_times": 100,
+        "data": [{
+          "value_type": "ref",
+          "value": "$.step_find_orders.fieldRecords"
+        }]
+      }
+    },
+    {
+      "id": "step_send_reminder",
+      "type": "LarkMessageAction",
+      "title": "发送催办消息",
+      "next": null,
+      "data": {
+        "receiver": [{
+          "value_type": "ref",
+          "value": "$.step_loop_customers.item.fldContact"
+        }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "订单处理提醒" }],
+        "content": [
+          { "value_type": "text", "value": "您好,您的订单 " },
+          { "value_type": "ref", "value": "$.step_loop_customers.item.fldName" },
+          { "value_type": "text", "value": " 金额 ¥" },
+          { "value_type": "ref", "value": "$.step_loop_customers.item.fldAmount" },
+          { "value_type": "text", "value": " 正在处理中。" }
+        ],
+        "btn_list": []
+      }
+    }
+  ]
+}
+```
+
+**关键点**:
+- `Loop.data` 必须传入 `ref` 类型的数据源(通常是 FindRecordAction 的 `fieldRecords`)
+- `Loop.children.links` 必须包含 `kind: "loop_start"` 的链接指向循环体
+- 循环体内用 `$.{loopStepId}.item.{fieldId}` 引用当前遍历记录的字段
+- `$.{loopStepId}.index` 获取当前索引(从 0 开始)
+
+---
+
+### 示例 3: 条件分支(IfElseBranch)
+
+**场景**: 根据订单金额判断,大额订单通知主管审批,小额订单自动通过。
+
+```json
+{
+  "client_token": "1704067203",
+  "title": "订单金额自动判断",
+  "steps": [
+    {
+      "id": "step_trigger",
+      "type": "AddRecordTrigger",
+      "title": "新增订单时触发",
+      "next": "step_check_amount",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "订单金额"
+      }
+    },
+    {
+      "id": "step_check_amount",
+      "type": "IfElseBranch",
+      "title": "判断是否为大额订单",
+      "children": {
+        "links": [
+          { "kind": "if_true", "to": "step_notify_manager", "label": "high", "desc": "金额>=10000" },
+          { "kind": "if_false", "to": "step_auto_approve", "label": "normal", "desc": "金额<10000" }
+        ]
+      },
+      "next": "step_log",
+      "data": {
+        "condition": {
+          "conjunction": "or",
+          "conditions": [
+            {
+              "conjunction": "and",
+              "conditions": [
+                {
+                  "left_value": { "value_type": "ref", "value": "$.step_trigger.fldAmount" },
+                  "operator": "isGreaterEqual",
+                  "right_value": [{ "value_type": "number", "value": 10000 }]
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "id": "step_notify_manager",
+      "type": "LarkMessageAction",
+      "title": "通知主管审批大额订单",
+      "next": "step_log",
+      "data": {
+        "receiver": [{ "value_type": "user", "value": {"id": "ou_manager", "name": "主管"} }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "大额订单待审批" }],
+        "content": [
+          { "value_type": "text", "value": "有大额订单 ¥" },
+          { "value_type": "ref", "value": "$.step_trigger.fldAmount" },
+          { "value_type": "text", "value": " 需要您审批" }
+        ],
+        "btn_list": []
+      }
+    },
+    {
+      "id": "step_auto_approve",
+      "type": "SetRecordAction",
+      "title": "自动标记小额订单为已审核",
+      "next": "step_log",
+      "data": {
+        "table_name": "订单表",
+        "ref_info": { "step_id": "step_trigger" },
+        "field_values": [
+          {
+            "field_name": "审批状态",
+            "value": [{ "value_type": "option", "value": { "name": "已自动审核" } }]
+          }
+        ]
+      }
+    },
+    {
+      "id": "step_log",
+      "type": "GenerateAiTextAction",
+      "title": "生成订单处理日志",
+      "next": null,
+      "data": {
+        "prompt": [
+          { "value_type": "text", "value": "请生成订单处理日志,金额:" },
+          { "value_type": "ref", "value": "$.step_trigger.fldAmount" }
+        ]
+      }
+    }
+  ]
+}
+```
+
+**关键点**:
+- `IfElseBranch.children.links` 必须包含 `if_true` 和 `if_false` 两个分支
+- `next` 指向两个分支汇合后的步骤(可选,为 null 则分支结束)
+- `condition` 使用 OrGroup 结构,支持 `(A and B) or (C and D)` 的复杂条件
+- 分支内可以用 `ref_info` 引用触发记录,用 `filter_info` 批量筛选记录
+
+---
+
+### 示例 4: 多路分支(SwitchBranch)
+
+**场景**: 根据订单优先级(P0/P1/P2)执行不同的处理流程。
+
+```json
+{
+  "client_token": "1704067204",
+  "title": "按优先级分类处理订单",
+  "steps": [
+    {
+      "id": "step_trigger",
+      "type": "AddRecordTrigger",
+      "title": "新增订单时触发",
+      "next": "step_classify",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "优先级"
+      }
+    },
+    {
+      "id": "step_classify",
+      "type": "SwitchBranch",
+      "title": "按优先级分类",
+      "children": {
+        "links": [
+          { "kind": "case", "to": "step_p0_handler", "label": "p0", "desc": "P0-紧急" },
+          { "kind": "case", "to": "step_p1_handler", "label": "p1", "desc": "P1-高优先级" },
+          { "kind": "case", "to": "step_p2_handler", "label": "p2", "desc": "P2-普通" },
+          { "kind": "case", "to": "step_other_handler", "label": "other", "desc": "其他" }
+        ]
+      },
+      "next": null,
+      "data": {
+        "mode": "exclusive",
+        "no_match_action": "classifyToOther",
+        "child_branch_list": [
+          {
+            "name": "P0-紧急",
+            "condition": {
+              "conjunction": "or",
+              "conditions": [
+                {
+                  "conjunction": "and",
+                  "conditions": [
+                    {
+                      "left_value": { "value_type": "ref", "value": "$.step_trigger.fldPriority" },
+                      "operator": "is",
+                      "right_value": [{ "value_type": "option", "value": { "name": "P0" } }]
+                    }
+                  ]
+                }
+              ]
+            }
+          },
+          {
+            "name": "P1-高优先级",
+            "condition": {
+              "conjunction": "or",
+              "conditions": [
+                {
+                  "conjunction": "and",
+                  "conditions": [
+                    {
+                      "left_value": { "value_type": "ref", "value": "$.step_trigger.fldPriority" },
+                      "operator": "is",
+                      "right_value": [{ "value_type": "option", "value": { "name": "P1" } }]
+                    }
+                  ]
+                }
+              ]
+            }
+          },
+          {
+            "name": "P2-普通",
+            "condition": {
+              "conjunction": "or",
+              "conditions": [
+                {
+                  "conjunction": "and",
+                  "conditions": [
+                    {
+                      "left_value": { "value_type": "ref", "value": "$.step_trigger.fldPriority" },
+                      "operator": "is",
+                      "right_value": [{ "value_type": "option", "value": { "name": "P2" } }]
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+        ]
+      }
+    },
+    {
+      "id": "step_p0_handler",
+      "type": "LarkMessageAction",
+      "title": "P0紧急处理",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "user", "value": {"id": "ou_director", "name": "总监"} }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "🚨 P0 紧急订单" }],
+        "content": [{ "value_type": "text", "value": "有新的 P0 紧急订单需要立即处理" }],
+        "btn_list": []
+      }
+    },
+    {
+      "id": "step_p1_handler",
+      "type": "SetRecordAction",
+      "title": "标记高优先级",
+      "next": null,
+      "data": {
+        "table_name": "订单表",
+        "ref_info": { "step_id": "step_trigger" },
+        "field_values": [
+          { "field_name": "处理状态", "value": [{ "value_type": "text", "value": "高优先级待处理" }] }
+        ]
+      }
+    },
+    {
+      "id": "step_p2_handler",
+      "type": "Delay",
+      "title": "普通订单延迟处理",
+      "next": null,
+      "data": { "duration": 60 }
+    },
+    {
+      "id": "step_other_handler",
+      "type": "SetRecordAction",
+      "title": "标记其他订单",
+      "next": null,
+      "data": {
+        "table_name": "订单表",
+        "ref_info": { "step_id": "step_trigger" },
+        "field_values": [
+          { "field_name": "处理状态", "value": [{ "value_type": "text", "value": "待分类" }] }
+        ]
+      }
+    }
+  ]
+}
+```
+
+**关键点**:
+- `SwitchBranch` 适合 3 路及以上的分支场景(少于 3 路用 `IfElseBranch` 更简洁)
+- `children.links` 中 `kind: "case"` 的 `label` 对应 `child_branch_list` 中的条件
+- `mode: "exclusive"` 表示排他执行(第一个匹配的分支执行后停止)
+- `no_match_action: "classifyToOther"` 表示无匹配时走最后一个 `case`(兜底分支)
+
+---
+
+### 示例 5: 组合场景(定时+查找+循环+分支+消息)
+
+**场景**: 每天早上 9 点,查找昨天的订单,按金额分级,给不同级别的销售发送不同的通知。
+
+```json
+{
+  "client_token": "1704067205",
+  "title": "每日订单分级通知",
+  "steps": [
+    {
+      "id": "step_timer",
+      "type": "TimerTrigger",
+      "title": "每天早上9点触发",
+      "next": "step_find_orders",
+      "data": {
+        "rule": "DAILY",
+        "start_time": "2025-01-01 09:00",
+        "is_never_end": true
+      }
+    },
+    {
+      "id": "step_find_orders",
+      "type": "FindRecordAction",
+      "title": "查找昨天所有订单",
+      "next": "step_loop",
+      "data": {
+        "table_name": "订单表",
+        "field_names": ["订单号", "客户名称", "金额", "销售负责人"],
+        "should_proceed_when_no_results": false,
+        "filter_info": {
+          "conjunction": "and",
+          "conditions": [
+            { "field_name": "创建时间", "operator": "isGreaterEqual", "value": [{ "value_type": "date", "value": "yesterday" }] }
+          ]
+        }
+      }
+    },
+    {
+      "id": "step_loop",
+      "type": "Loop",
+      "title": "遍历每个订单",
+      "children": {
+        "links": [
+          { "kind": "loop_start", "to": "step_classify" }
+        ]
+      },
+      "next": "step_summary",
+      "data": {
+        "loop_mode": "continue",
+        "max_loop_times": 500,
+        "data": [{ "value_type": "ref", "value": "$.step_find_orders.fieldRecords" }]
+      }
+    },
+    {
+      "id": "step_classify",
+      "type": "SwitchBranch",
+      "title": "按金额分类",
+      "children": {
+        "links": [
+          { "kind": "case", "to": "step_vip_notify", "label": "vip", "desc": "VIP >= 10万" },
+          { "kind": "case", "to": "step_normal_notify", "label": "normal", "desc": "普通 < 10万" }
+        ]
+      },
+      "next": null,
+      "data": {
+        "mode": "exclusive",
+        "no_match_action": "fail",
+        "child_branch_list": [
+          {
+            "name": "VIP订单",
+            "condition": {
+              "conjunction": "or",
+              "conditions": [
+                {
+                  "conjunction": "and",
+                  "conditions": [
+                    {
+                      "left_value": { "value_type": "ref", "value": "$.step_loop.item.fldAmount" },
+                      "operator": "isGreaterEqual",
+                      "right_value": [{ "value_type": "number", "value": 100000 }]
+                    }
+                  ]
+                }
+              ]
+            }
+          },
+          {
+            "name": "普通订单",
+            "condition": {
+              "conjunction": "or",
+              "conditions": [
+                {
+                  "conjunction": "and",
+                  "conditions": [
+                    {
+                      "left_value": { "value_type": "ref", "value": "$.step_loop.item.fldAmount" },
+                      "operator": "isLess",
+                      "right_value": [{ "value_type": "number", "value": 100000 }]
+                    }
+                  ]
+                }
+              ]
+            }
+          }
+        ]
+      }
+    },
+    {
+      "id": "step_vip_notify",
+      "type": "LarkMessageAction",
+      "title": "VIP订单通知",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "ref", "value": "$.step_loop.item.fldSales" }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "🌟 VIP大额订单" }],
+        "content": [
+          { "value_type": "text", "value": "恭喜!您有一笔 VIP 订单 ¥" },
+          { "value_type": "ref", "value": "$.step_loop.item.fldAmount" },
+          { "value_type": "text", "value": ",客户:" },
+          { "value_type": "ref", "value": "$.step_loop.item.fldCustomer" }
+        ],
+        "btn_list": []
+      }
+    },
+    {
+      "id": "step_normal_notify",
+      "type": "LarkMessageAction",
+      "title": "普通订单通知",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "ref", "value": "$.step_loop.item.fldSales" }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "新订单通知" }],
+        "content": [
+          { "value_type": "text", "value": "您有一笔新订单 ¥" },
+          { "value_type": "ref", "value": "$.step_loop.item.fldAmount" }
+        ],
+        "btn_list": []
+      }
+    },
+    {
+      "id": "step_summary",
+      "type": "GenerateAiTextAction",
+      "title": "生成日报",
+      "next": null,
+      "data": {
+        "prompt": [
+          { "value_type": "text", "value": "请生成昨日订单处理日报" }
+        ]
+      }
+    }
+  ]
+}
+```
+
+---
+
+## 构造技巧
+
+### Loop 构造要点
+
+1. **数据源**: `Loop.data` 必须传入 `ref` 类型,通常是 `FindRecordAction` 的 `fieldRecords`
+2. **循环体**: `children.links` 必须包含 `kind: "loop_start"` 指向循环体入口
+3. **引用**: 循环体内用 `$.{loopStepId}.item.{fieldId}` 引用当前元素
+4. **索引**: 用 `$.{loopStepId}.index` 获取当前索引(从 0 开始)
+
+### 分支构造要点
+
+1. **IfElseBranch**:
+   - 适合二元判断(是/否、大于/小于)
+   - `children.links` 必须包含 `if_true` 和 `if_false`
+   - 可以用 `next` 指向汇合点
+
+2. **SwitchBranch**:
+   - 适合多路分类(3路及以上)
+   - `label` 对应 `child_branch_list` 中的条件顺序
+   - 建议加一个兜底分支(其他)
+
+### 字段值构造
+
+| 字段类型 | value_type | 示例 |
+|---------|------------|------|
+| 文本 | `text` | `{"value_type": "text", "value": "张三"}` |
+| 数字 | `number` | `{"value_type": "number", "value": 100}` |
+| 单选 | `option` | `{"value_type": "option", "value": {"name": "已完成"}}` |
+| 人员 | `user` | `{"value_type": "user", "value": {"id": "ou_xxxx"}}` |
+| 引用 | `ref` | `{"value_type": "ref", "value": "$.step_1.fldxxx"}` |
+
+---
+
+## 常见错误避免
+
+### Top 10 高频错误
+
+| # | 错误信息 | 原因 | 解决方案 |
+|---|---------|------|---------|
+| 1 | `path "xxx" does not exist in the output path tree` | ref 引用路径错误或 stepId 不存在 | 检查 stepId 是否在 steps 数组中;使用 fieldId 而非字段名;确保路径以 `$.` 开头 |
+| 2 | `recordInfo.conditions must be non-empty` | `condition_list` 为空数组 `[]` | 改用 `null` 或省略该字段 |
+| 3 | `At least one of filter info and ref info is required` | SetRecordAction/FindRecordAction 缺少定位条件 | 必须提供 `filter_info` 或 `ref_info` 之一 |
+| 4 | `client token is empty` | 缺少 `client_token` | 每次请求传入唯一值(时间戳或随机字符串) |
+| 5 | `valueType 'text' not allowed for fieldType '3'` | select 类型字段值格式错误 | 改用 `option` 类型 |
+| 6 | `Undefined Step Type` | 使用了不支持的 StepType | 使用 `AddRecordTrigger` 而非 `CreateRecordTrigger` |
+| 7 | `prompt references an unknown reference from step` | 引用的 stepId 不存在 | 确保引用的 step 在同一 workflow 的 steps 数组中 |
+| 8 | `[2200] Internal Error` | 1. steps[].id 重复 2. next/children.links 引用了不存在的 step | 确保所有 step id 唯一;检查引用关系 |
+| 9 | 工作流结构不完整 | Branch/Loop 节点缺少 `children` | 仅 Branch(IfElseBranch/SwitchBranch)和 Loop 节点需要 `children`,Trigger/Action 节点无需设置 |
+| 10 | 嵌套分支过于复杂 | 多层 IfElseBranch 嵌套 | 3+ 路分支用 SwitchBranch 替代嵌套 IfElseBranch |
+
+### 其他常见错误
+
+**1. condition_list 为空数组**
+```json
+// ❌ 错误
+{ "condition_list": [] }
+
+// ✅ 正确
+{ "condition_list": null }
+// 或省略该字段
+```
+
+**2. filter_info 和 ref_info 同时提供**
+```json
+// ❌ 错误
+{ "filter_info": {...}, "ref_info": {...} }
+
+// ✅ 正确(二选一)
+{ "filter_info": {...}, "ref_info": null }
+{ "filter_info": null, "ref_info": {...} }
+```
+
+**3. 使用字段名而非 fieldId**
+```json
+// ❌ 错误
+{ "value": "$.step_1.客户名称" }
+
+// ✅ 正确
+{ "value": "$.step_1.fldXXXXXXXX" }
+```
+
+---
+
+## 参考
+
+- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — 字段定义参考
+- [lark-base-workflow-create.md](lark-base-workflow-create.md) — 创建命令
+- [lark-base-workflow-update.md](lark-base-workflow-update.md) — 更新命令

+ 123 - 0
.agents/skills/lark-base/references/lark-base-workflow-list.md

@@ -0,0 +1,123 @@
+# base +workflow-list
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+列出 Base 中所有自动化工作流,自动分页获取全量数据。
+
+## 推荐命令
+
+```bash
+# 列出全部工作流
+lark-cli base +workflow-list \
+  --base-token BascXxxxxx
+
+# 只看已启用的工作流
+lark-cli base +workflow-list \
+  --base-token BascXxxxxx \
+  --status enabled
+
+# 只看已禁用的工作流
+lark-cli base +workflow-list \
+  --base-token BascXxxxxx \
+  --status disabled
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
+| `--status <value>` | 否 | 过滤状态:`enabled` 或 `disabled`;不传则返回全部 |
+| `--page-size <n>` | 否 | 每页大小,默认 100,最大 100 |
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+POST /open-apis/base/v3/bases/:base_token/workflows/list
+```
+
+> ⚠️ **注意:列表接口用 POST**,不是 GET。
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 Base Token |
+
+**Request Body(JSON):**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `page_size` | int | 否 | 分页大小,默认 20,最大 100 |
+| `page_token` | string | 否 | 分页标记,首次请求不填,翻页时传上一页返回的 `page_token` |
+| `status` | string | 否 | 过滤状态:`enabled` / `disabled` |
+
+## API 出参详情
+
+**Response `data` 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `has_more` | boolean | 是否还有更多数据 |
+| `page_token` | string | 下一页 token(`has_more` 为 true 时返回) |
+| `total` | int | 符合条件的工作流总数 |
+| `items` | []object | 工作流列表 |
+| `items[].workflow_id` | string | 工作流唯一标识(`wkf` 开头) |
+| `items[].title` | string | 工作流标题 |
+| `items[].status` | string | 当前状态:`enabled` / `disabled` |
+| `items[].trigger_type` | string | 触发器类型,如 `AddRecordTrigger` |
+| `items[].creator_id` | string | 创建人的 open_id |
+| `items[].updater_id` | string | 最后修改人的 open_id |
+| `items[].create_time` | int | 创建时间,Unix 秒级时间戳 |
+| `items[].update_time` | int | 最后更新时间,Unix 秒级时间戳 |
+
+## 返回值
+
+命令成功后输出 JSON(已合并所有分页):
+
+```json
+{
+  "ok": true,
+  "data": {
+    "items": [
+      {
+        "workflow_id": "wkfxxxxxx",
+        "title": "自动发送通知",
+        "status": "enabled",
+        "trigger_type": "AddRecordTrigger",
+        "creator_id": "ou_xxxxx",
+        "updater_id": "ou_yyyyy",
+        "create_time": 1704067200,
+        "update_time": 1704153600
+      }
+    ],
+    "total": 1
+  }
+}
+```
+
+## ⚡ 性能提示
+### 场景适用性
+**✅ 需要先 list 的场景**:
+- 批量操作:启用/停用多个工作流(先 list,再批量 enable/disable)
+- 查询统计:统计定时触发的工作流数量(先 list,再筛选)
+- 修改操作:修改指定名称的工作流(先 list ,从列表中找到对应名称工作流的 workflow_id,再 get/update)
+  **❌ 不需要先 list 的场景**:
+- **创建工作流**:直接调用 `+workflow-create`,不需要先 list
+- 查看指定工作流详情:如果已知 workflow_id,直接 `+workflow-get`
+### 缓存策略
+同一会话中处理多个工作流时,只需调用一次 `+workflow-list` 获取全部结果,然后从中筛选所需的工作流,避免重复查询。
+
+## 坑点
+
+- ⚠️ **列表用 POST 不用 GET**:`/workflows/list` 是 POST 接口,`page_token` 放在 Request Body 里而不是 Query 参数,常见误区
+- ⚠️ **workflow_id 前缀 `wkf`**:返回的 `workflow_id` 以 `wkf` 开头,传给 `+workflow-enable` / `+workflow-disable` 时直接使用即可,不要和 table_id(`tbl` 开头)混淆
+- ⚠️ **scope 待确认**:内部文档未列出权限名,代码使用 `base:workflow:read`,如遇 `[230013] permission denied` 需核对实际 scope
+
+## 参考
+
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-base-workflow-enable-disable](lark-base-workflow-enable-disable.md) — 启用/禁用工作流
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 935 - 0
.agents/skills/lark-base/references/lark-base-workflow-schema.md

@@ -0,0 +1,935 @@
+# Workflow 数据结构参考
+
+本文档定义 Workflow 的完整数据结构,适用于:
+- **查询场景**:理解 `+workflow-get` 返回的 `steps` 结构
+- **创建/修改场景**:构造 `+workflow-create` / `+workflow-update` 的 `--json` body
+> 💡 **本文档是纯字段参考**。如需**创建/修改**工作流的完整示例,请阅读 [workflow-guide.md](lark-base-workflow-guide.md)。
+---
+## 📖 快速导航
+
+根据你的需求跳转到对应章节:
+
+| 需求 | 章节 |
+|------|------|
+| 了解 Step 基础结构 | [WorkflowStep 基础结构](#workflowstep-基础结构) |
+| 查询 Trigger 类型及 data 字段 | [Trigger data](#trigger-data-详细结构) |
+| 查询 Action 类型及 data 字段 | [Action data](#action-data-详细结构) |
+| 查询 Branch/Loop 结构 | [Branch data](#branch-data-详细结构) / [System data](#system-data-详细结构) |
+| 查询 ValueInfo/Condition 等公共类型 | [公共类型](#公共类型) |
+
+---
+
+## WorkflowStep 基础结构
+
+每个步骤(Trigger / Action / Branch / System)共享以下字段:
+
+```json
+{
+  "id": "step_xxx",
+  "type": "AddRecordTrigger",
+  "title": "监控新订单",
+  "next": "step_yyy",
+  "data": {}
+}
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `id` | string | 是 | 步骤唯一 ID(用户自定义,被 `next` 和 `children.links[].to` 引用) |
+| `type` | string | 是 | 步骤类型,见下方枚举 |
+| `title` | string | 否 | 步骤标题 |
+| `children` | StepChildren | 否 | 子关系边,承担所有分支/循环 |
+| `next` | string | null | 否 | 线性后继节点 ID;`null` 表示流程结束 |
+| `data` | object | 是 | 步骤详细配置,按 `type` 区分,见后续各节 |
+
+> **总原则**:连线写 `children`,扩展标识写 `meta`,输入参数写 `data`。
+
+---
+
+## StepChildren 与 ChildLink
+
+### StepChildren
+
+```json
+{
+  "links": [ /* ChildLink[] */ ]
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `links` | ChildLink[] | 子关系边列表;无子关系时为空数组 `[]` |
+
+### ChildLink
+
+每条关系边描述从当前节点到目标节点的有向连线:
+
+```json
+{ "kind": "if_true", "to": "step_4", "label": "branch_1", "desc": "金额大于1000" }
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `kind` | string | 是 | 关系类型:`if_true` / `if_false` / `case` / `loop_start` / `slot` |
+| `to` | string | 是 | 目标节点 ID |
+| `label` | string | 否 | 可选标签(如 `branch_1`、`tool`、`llm`、`memory`) |
+| `desc` | string | 否 | 可选语义说明(如"销售部门"、"积极情绪") |
+
+`kind` 使用场景:
+
+| kind | 使用节点 | 说明 |
+|------|---------|------|
+| `if_true` | IfElseBranch | 条件为真时跳转 |
+| `if_false` | IfElseBranch | 条件为假时跳转 |
+| `case` | SwitchBranch / AIClassificationBranch | 多路分支,`label` 建议用 `branch_1` 等中性标签,`desc` 写语义 |
+| `loop_start` | Loop | 循环体入口 |
+| `slot` | AIAgentAction | 挂载 LLM / 工具 / 记忆子节点,`label` 为 `llm` / `tool` / `memory` |
+
+---
+
+## StepType 枚举
+
+### Trigger 类型
+
+| type | 说明 |
+|------|------|
+| `AddRecordTrigger` | 新增记录时触发 |
+| `SetRecordTrigger` | 记录被修改时触发 |
+| `ChangeRecordTrigger` | 记录满足条件时触发 |
+| `TimerTrigger` | 定时触发 |
+| `ReminderTrigger` | 日期提醒触发 |
+| `LarkMessageTrigger` | 接收飞书消息触发 |
+
+> 所有 Trigger 节点**请勿设置** `children` ,通过 `next` 串联后继。
+
+### 触发器选型指南
+
+| 需求描述 | 触发器 |
+|---------|--------|
+| 新增记录时 | `AddRecordTrigger` |
+| 字段变为特定值时(**仅修改**) | `SetRecordTrigger` |
+| **新增或修改**都触发 | `ChangeRecordTrigger` |
+| 拿不准用哪个 | `ChangeRecordTrigger` |
+
+> ⚠️ `SetRecordTrigger` 仅监听修改,`ChangeRecordTrigger` 同时监听新增 + 修改。
+
+### Action 类型
+
+| type | 说明 |
+|------|------|
+| `AddRecordAction` | 新增记录 |
+| `SetRecordAction` | 更新记录 |
+| `FindRecordAction` | 查找记录 |
+| `Delay` | 延迟 |
+| `LarkMessageAction` | 发送飞书消息 |
+| `GenerateAiTextAction` | AI 生成文本 |
+
+> 所有 Action 节点**请勿设置** `children` ,通过 `next` 串联后继。
+
+### Branch 类型
+
+| type | 说明 |
+|------|------|
+| `IfElseBranch` | 条件分支,`children.links` 含 `if_true` 和 `if_false` |
+| `SwitchBranch` | 多路分支,`children.links` 含多个 `case` |
+
+### System 类型
+
+| type | 说明 |
+|------|------|
+| `Loop` | 循环,`children.links` 含 `loop_start` 指向循环体入口 |
+
+---
+
+## Trigger data 详细结构
+
+
+### AddRecordTrigger
+
+```json
+{
+  "table_name": "订单表",
+  "watched_field_name": "状态",
+  "trigger_control_list": ["pasteUpdate", "automationBatchUpdate"],
+  "condition_list": [] /* AndCondition 数组 */ 
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `table_name` | 是 | 监控的数据表名 |
+| `watched_field_name` | 是 | 监控的字段名 |
+| `trigger_control_list` | 否 | 触发控制,可选值:`pasteUpdate` / `automationBatchUpdate` / `syncUpdate` / `appendImport` / `openAPIBatchUpdate` |
+| `condition_list` | 否 | 过滤条件数组,数组中每个元素为 AndCondition 结构,多个 AndCondition 之间为 OR 关系 |
+
+### ChangeRecordTrigger
+
+```json
+{
+  "table_name": "任务表",
+  "trigger_control_list": [],
+  "condition": null
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `table_name` | 是 | 监控的数据表名 |
+| `trigger_control_list` | 否 | 触发控制,可选值:`pasteUpdate` / `automationBatchUpdate` / `syncUpdate` / `appendImport` |
+| `condition_list` | 否 | 过滤条件数组,数组中每个元素为 AndCondition 结构,多个 AndCondition 之间为 OR 关系 |
+
+### SetRecordTrigger
+
+```json
+{
+  "table_name": "订单表",
+  "record_watch_conjunction": "and",
+  "record_watch_info": [ /* FieldCondition[] */ ],
+  "field_watch_info": [
+    { "field_name": "状态", "operator": "is", "value": [{ "value_type": "text", "value": "已发货" }] }
+  ],
+  "trigger_control_list": [],
+  "condition_list": null
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|----|------|
+| `table_name` | 是  | 监控的数据表名 |
+| `record_watch_conjunction` | 否  | 记录筛选组合方式:`and` / `or`,默认 `and` |
+| `record_watch_info` | 否  | 记录级过滤条件(修改前值匹配),为空则监听全部 |
+| `field_watch_info` | 是  | 字段级监控条件列表,至少一个 |
+| `trigger_control_list` | 否  | 触发控制,可选值:`pasteUpdate` / `automationBatchUpdate` / `syncUpdate` / `appendImport` |
+| `condition_list` | 否  | 过滤条件数组,数组中每个元素为 AndCondition 结构,多个 AndCondition 之间为 OR 关系 |
+
+`FieldWatchItem`:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `field_name` | string | 监听字段名称 |
+| `operator` | string | 操作符(仅明确要求字段满足条件时填) |
+| `value` | ValueInfo[] | 触发值 |
+
+### TimerTrigger
+
+```json
+{
+  "rule": "WEEKLY",
+  "start_time": "2025-01-01 09:00",
+  "sub_unit": [1, 3, 5],
+  "is_never_end": true
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `rule` | 是 | `NO_REPEAT` / `DAILY` / `WEEKLY` / `MONTHLY` / `YEARLY` / `WORKDAY` / `CUSTOM` |
+| `start_time` | 否 | 开始时间,格式 `yyyy-MM-dd HH:mm` |
+| `interval` | 否 | 自定义间隔 [1,30](仅 CUSTOM) |
+| `unit` | 否 | 自定义单位:`SECOND` / `MINUTE` / `HOUR` / `DAY` / `WEEK` / `MONTH` / `YEAR` |
+| `sub_unit` | 否 | 子单位(`WEEKLY` 时为星期几数组 0-6,`MONTHLY` 时为几号数组 1-31) |
+| `end_time` | 否 | 结束时间 |
+| `is_never_end` | 否 | 是否永不结束 |
+
+### ReminderTrigger
+
+```json
+{
+  "table_name": "项目表",
+  "field_name": "截止日期",
+  "offset": 1,
+  "unit": "DAY",
+  "hour": 9,
+  "minute": 0,
+  "condition_list": null
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `table_name` | 是 | 数据表名 |
+| `field_name` | 是 | 日期字段名(必须为 DateTime / CreatedTime / Formula / Lookup 类型) |
+| `unit` | 是 | 偏移单位:`MINUTE` / `HOUR` / `DAY` / `WEEK` / `MONTH` |
+| `offset` | 是 | 提前/延后的偏移量(正数=提前,负数=延后;范围由 `unit` 决定):`MINUTE` ∈ {0, 5, 15, 30, -5, -15, -30};`HOUR` ∈ [-6, -1] ∪ [1, 6];`DAY` ∈ [-7, 7];`WEEK` ∈ [-7, -1] ∪ [1, 7];`MONTH` ∈ [-7, -1] ∪ [1, 7] |
+| `hour` | 是 | 触发小时 (0-23),默认 9 |
+| `minute` | 是 | 触发分钟 (0-59),默认 0 |
+| `condition_list` | 否 | 过滤条件数组,数组中每个元素为 AndCondition 结构,多个 AndCondition 之间为 OR 关系  | 
+
+
+### LarkMessageTrigger
+
+```json
+{
+  "receive_scene": "group",
+  "receiver": [{ "value_type": "group", "value": {"id": "oc_xxxx", "name": "测试群"} }],
+  "scope": "all",
+  "filter": {
+    "conjunction": "and",
+    "content_contains": ["关键词"],
+    "sender_contains": [{ "value_type": "user", "value": {"id": "ou_xxxx", "name": ""} }],
+    "is_new_message": true,
+    "is_message_contain_attachment": false
+  }
+}
+```
+
+| 字段 | 必填 | 说明|
+|------|------|---|
+| `receive_scene` | 是 | 接收场景:`group`(群聊)/ `chat`(单聊)|
+| `receiver` | 是 | 触发来源,支持 `user` / `group` / `ref`。在单聊场景下,该字段指“可以和机器人单聊的用户”;在群聊场景下,该字段指“接收信息的群组”|
+| `scope` | 是 | 触发范围:`at`(@提及)/ `all`(所有消息)。该参数仅在群聊场景有效,单聊场景请勿指定该参数|
+| `filter` | 是 | MessageFilter 消息过滤条件|
+
+`MessageFilter`:
+
+| 字段 | 类型 | 说明 |
+|------|------|----|
+| `conjunction` | string | `and` 满足所有条件 / `or` 任一条件|
+| `content_contains` | string[] | 关键词列表|
+| `sender_contains` | ValueInfo[] | 筛选发送人(仅群聊+群组来源时生效,单聊场景请勿指定该参数)|
+| `is_new_message` | boolean | 仅新话题消息(仅群聊时有效,单聊场景请勿指定该参数)|
+| `is_message_contain_attachment` | boolean | 是否仅附件消息触发|
+
+## Action data 详细结构
+
+### AddRecordAction
+
+```json
+{
+  "table_name": "订单表",
+  "field_values": [
+    { "field_name": "客户名称", "value": [{ "value_type": "text", "value": "张三" }] },
+    { "field_name": "金额", "value": [{ "value_type": "number", "value": 100 }] },
+    { "field_name": "创建人", "value": [{ "value_type": "ref", "value": "$.trigger_1.fieldIdxxx" }] }
+  ]
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `table_name` | 是 | 目标数据表名 |
+| `field_values` | 是 | RecordFieldValue[] |
+
+### SetRecordAction
+
+```json
+{
+  "table_name": "订单表",
+  "max_set_record_num": 10,
+  "field_values": [
+    { "field_name": "状态", "value": [{ "value_type": "option", "value": { "id": "opt1", "name": "已完成" } }] }
+  ],
+  "filter_info": { /* RecordFilterInfo */ },
+  "ref_info": { "step_id": "step_trigger" }
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `table_name` | 是 | 目标数据表名 |
+| `max_set_record_num` | 否 | 最大更新记录数,默认 100,范围 1-15000 |
+| `field_values` | 是 | RecordFieldValue[] |
+| `filter_info` | 否* | RecordFilterInfo 过滤条件(与 `ref_info` 互斥) |
+| `ref_info` | 否* | RefInfo 引用前置步骤的记录(与 `filter_info` 互斥) |
+
+### FindRecordAction
+
+```json
+{
+  "table_name": "客户表",
+  "field_names": ["客户名称", "联系方式", "等级"],
+  "should_proceed_when_no_results": true,
+  "filter_info": { /* RecordFilterInfo */ }
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `table_name` | 是 | 目标数据表名 |
+| `field_names` | 是 | 要检索的字段名列表,至少一个 |
+| `should_proceed_when_no_results` | 否 | 无结果时是否继续后续步骤,默认 `true` |
+| `filter_info` | 否* | RecordFilterInfo(与 `ref_info` 互斥) |
+| `ref_info` | 否* | RefInfo(与 `filter_info` 互斥) |
+
+### Delay
+
+```json
+{ "duration": 30 }
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `duration` | 是 | 延迟时长(分钟),范围 [1, 120] |
+
+### LarkMessageAction
+
+```json
+{
+  "receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx"} }],
+  "send_to_everyone": false,
+  "title": [{ "value_type": "text", "value": "新订单通知" }],
+  "content": [
+    { "value_type": "text", "value": "客户 " },
+    { "value_type": "ref", "value": "$.trigger_1.fldCustomerName" },
+    { "value_type": "text", "value": " 创建了新订单" }
+  ],
+  "btn_list": [
+    { "text": "查看详情", "btn_action": "openLink", "link": [{ "value_type": "text", "value": "https://example.com" }] }
+  ]
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `receiver` | 是 | ValueInfo[] |
+| `send_to_everyone` | 是 | 是否发送给所有人 |
+| `title` | 否 | TextRefItem[] 消息标题 |
+| `content` | 是 | TextRefItem[] 消息内容 |
+| `btn_list` | 是 | 按钮列表,不需要时为空数组 |
+
+`ButtonConfig`:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `text` | string | 按钮文字 |
+| `btn_action` | string | `addRecord` / `setRecord` / `openLink` |
+| `link` | ValueInfo[] | 跳转链接(`openLink` 时使用) |
+| `table_name` | string | 操作表名(`addRecord` 时使用) |
+| `record_values` | RecordFieldValue[] | 记录赋值(`addRecord` / `setRecord` 时使用) |
+
+### GenerateAiTextAction
+
+```json
+{
+  "prompt": [
+    { "value_type": "text", "value": "请总结以下内容:" },
+    { "value_type": "ref", "value": "$.step_1.fieldxxx" }
+  ]
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `prompt` | 是 | TextRefItem[] 提示词,支持 `text` / `ref` |
+
+
+## Branch data 详细结构
+
+### IfElseBranch
+
+`children.links` 包含 `if_true` 和 `if_false` 两条边,`next` 指向两个分支汇合后的后继节点。
+
+**如果涉及到复杂的多分支场景(分支数目 >= 3时),你应该采用 SwitchBranch,而不是嵌套的 IfElseBranch**
+
+```json
+{
+  "condition": {
+    "conjunction": "or",
+    "conditions": [
+      {
+        "conjunction": "and",
+        "conditions": [
+          {
+            "left_value": { "value_type": "ref", "value": "$.step_1.fieldxxx" },
+            "operator": "isGreater",
+            "right_value": [{ "value_type": "number", "value": 1000 }]
+          }
+        ]
+      }
+    ]
+  }
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `condition` | 是 | OrGroup 判断条件,结构为 `(A and B) or (C and D)` |
+
+### SwitchBranch
+
+`children.links` 包含多个 `case` 边(`label` 建议用 `branch_1`、`branch_2`,语义写在 `desc`)。
+
+```json
+{
+  "mode": "exclusive",
+  "no_match_action": "classifyToOther",
+  "child_branch_list": [
+    {
+      "name": "高优先级",
+      "condition": {
+        "conjunction": "or",
+        "conditions": [
+          {
+            "conjunction": "and",
+            "conditions": [
+              {
+                "left_value": { "value_type": "ref", "value": "$.step_1.fieldxxx" },
+                "operator": "is",
+                "right_value": [{ "value_type": "text", "value": "P0" }]
+              }
+            ]
+          }
+        ]
+      }
+    }
+  ]
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `mode` | 否 | 分支模式。`exclusive`:排他模式,仅执行一个满足条件的子分支;`parallel`:并行模式,执行所有满足条件的子分支。默认 `exclusive` |
+| `no_match_action` | 否 | `mode=exclusive` 时使用,无匹配时的处理策略。`classifyToOther`:归类到其他分支;`fail`:报错终止。默认 `classifyToOther` |
+| `fail_mode` | 否 | `mode=parallel` 时使用,部分分支出错时策略。`partialSuccess`:部分成功即继续;`fail`:任一失败即终止。默认 `partialSuccess` |
+| `match_mode` | 否 | `mode=parallel` 时使用,所有分支不满足时策略。`noneMatchSkip`:跳过继续;`noneMatchFail`:报错终止。默认 `noneMatchSkip` |
+| `child_branch_list` | 是 | BranchItem[],1-10 个条件分支 |
+
+`BranchItem`:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `name` | string | 分支名称 |
+| `condition` | OrGroup | 分支条件 |
+
+
+## System data 详细结构
+
+### Loop
+
+`children.links` 包含 `loop_start` 边指向循环体入口,`next` 指向循环结束后的后继节点。
+
+```json
+{
+  "loop_mode": "continue",
+  "max_loop_times": 100,
+  "data": [{ "value_type": "ref", "value": "$.find_record_stepIdxxx.fieldRecords" }]
+}
+```
+
+| 字段 | 必填 | 说明 |
+|------|------|------|
+| `data` | 是 | ValueInfo[](仅支持 `ref` 类型),循环数据源,只能填一个 |
+| `loop_mode` | 否 | 单次错误时是否继续:`end`(终止)/ `continue`(继续) |
+| `max_loop_times` | 否 | 最大循环次数 |
+
+---
+
+
+## 公共类型
+
+### ValueInfo
+
+所有值的基础类型,通过 `value_type` 区分:
+
+| value_type | value 类型 | 说明 | 示例 |
+|------------|-----------|------|------|
+| `text` | string | 文本 | `"张三"` |
+| `number` | number | 数字 | `100` |
+| `boolean` | boolean | 布尔值 | `true` |
+| `date` | string | 日期,可以是具体时间字符串,或者相对时间值 | `"2025/01/01"`、`"2025/01/01 11:00"`、`"now"`、`"now 11:00"`、`"today"`、`"today 11:00"`、`"yesterday"`、`"yesterday 11:00"`、`"lastWeek"`、`"currentMonth"`、`"lastMonth"`、`"theLastWeek"`、`"theNextWeek"`、`"theLastMonth"`、`"theNextMonth"` |
+| `option` | `{ id, name }` | 选项 | `{ "id": "opt1", "name": "已完成" }` |
+| `link` | `{ text, link }` | 链接(含文字和 URL), 文字和 URL 的格式可以是 ValueInfo 中的 text/ref 类型 | `{ "text": [{ "value_type": "text", "value": "查看详情" }], "link": [{ "value_type": "text", "value": "https://example.com" }] }`、`{ "text": [{ "value_type": "text", "value": "查看详情" }], "link": [{ "value_type": "ref", "value": "$.step_1.fldXXX" }] }` |
+| `user` | `{ id, name }` | 用户 OpenID、名字 | `{ "id": "ou_xxxx", "name": "张三" }` |
+| `group` | `{ id, name }` | 群 Chat ID、名字 | `{ "id": "oc_xxx", "name": "测试群" }` |
+| `ref` | `string` | 引用前置节点输出的路径 | 参考 ref 引用变量详解 章节 |
+
+> ⚠️ **所有涉及用户的 value 中的 id 统一使用 OpenID(`ou_xxxx` 格式)**,由 CLI 层来完成转换
+> ⚠️ **所有涉及群的 value 中的 id 统一使用 ChatID(`oc_xxxx` 格式)**,由 CLI 层来完成转换
+
+### ref 引用变量详解
+
+`ref` 类型是工作流中节点间数据传递的核心机制。当 `value_type` 为 `ref` 时,`value` 指向前置节点的某个输出变量。本节详细描述每个节点可供引用的输出变量定义。
+
+#### 引用路径格式
+
+```
+$.{stepId}
+$.{stepId}.{pathId}
+$.{stepId}.{pathId}.{childPathId}
+$.{stepId}.{pathId}.{childPathId}.{grandChildPathId}
+```
+
+- `{stepId}`:前置节点的 `id`(即 WorkflowStep 中的 `id` 字段)
+- `{pathId}`:节点输出的路径标识符
+- 支持多层下钻,如引用字段的属性:`$.step_1.fldXXX.name`
+
+---
+
+#### 触发器节点输出
+
+##### 记录触发器(AddRecordTrigger / ChangeRecordTrigger / SetRecordTrigger / ReminderTrigger)
+
+这 4 个触发器的输出结构完全一致:
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| `{fieldId}` | 字段id,从配置表的所有字段或者指定字段id生成,可下钻字段属性 | `$.{stepId}.{fieldId}` |
+| `{fieldId}.fieldId` | 字段id属性 | `$.{stepId}.{fieldId}.fieldId}` |
+| `{fieldId}.fieldName` | 字段名属性 | `$.{stepId}.{fieldId}.fieldName}` |
+| `startTime` | 触发时间戳 | `$.{stepId}.startTime` |
+| `recordId` | 记录 ID | `$.{stepId}.recordId` |
+| `recordLink` | 记录链接 | `$.{stepId}.recordLink` |
+| `recordCreatedUser` | 记录创建者 | `$.{stepId}.recordCreatedUser` |
+| `recordCreatedTime` | 记录创建时间 | `$.{stepId}.recordCreatedTime` |
+| `recordModifiedUser` | 最后修改者 | `$.{stepId}.recordModifiedUser` |
+| `recordModifiedTime` | 最后修改时间 | `$.{stepId}.recordModifiedTime` |
+
+**动态字段输出规则**:
+
+- 读取触发器所配置的数据表的所有字段
+- 每个字段生成一条输出:`pathId` = fieldId
+- 若字段为关联字段,children 为关联表所有字段(单层下钻,不再递归)
+- 每个字段可下钻特定的字段属性(见「字段属性下钻」)
+
+**recordLink 的 children**:如果配置了数据表,则为该表所有视图的列表,每个视图 `{ pathId: viewId, pathName: viewName, pathType: 'string' }`。引用示例:`$.{stepId}.recordLink.{viewId}`。
+
+##### TimerTrigger(定时触发器)
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| `scheduleTime` | 定时触发时间 | `$.{stepId}.scheduleTime` |
+
+##### LarkMessageTrigger(飞书消息触发器)
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| `Sender` | 消息发送者 | `$.{stepId}.Sender` |
+| `AtUser` | 消息中被@的用户 | `$.{stepId}.AtUser` |
+| `SenderGroup` | 消息所在群(仅群聊场景) | `$.{stepId}.SenderGroup` |
+| `MessageSendTime` | 消息发送时间 | `$.{stepId}.MessageSendTime` |
+| `MessageContent` | 消息正文 | `$.{stepId}.MessageContent` |
+| `MessageType` | 消息类型标识 | `$.{stepId}.MessageType` |
+| `MessageID` | 消息唯一标识 | `$.{stepId}.MessageID` |
+| `MessageLink` | 消息链接(仅群聊场景) | `$.{stepId}.MessageLink` |
+| `ParentID` | 回复的消息 ID | `$.{stepId}.ParentID` |
+| `ThreadID` | 所在话题消息 ID | `$.{stepId}.ThreadID` |
+| `Attachments` | 消息中的附件 | `$.{stepId}.Attachments` |
+
+条件限制:
+
+- 若场景为单聊(`receive_scene = "Chat"`),则 `SenderGroup` 和 `MessageLink` 不可用
+
+---
+
+#### 操作节点输出
+
+##### FindRecordAction(查找记录)
+
+| pathId | 说明 | 引用示例|
+|--------|------|-------|
+| `fieldRecords` | 所有找到的记录的引用(可用于 Loop 遍历) | `$.{stepId}.fieldRecords`|
+| `firstfieldsRecord` | 第一条匹配记录 | `$.{stepId}.firstfieldsRecord`|
+| `firstfieldsRecord.{fieldId}` | 首条记录的字段值,可下钻字段属性 | `$.{stepId}.firstfieldsRecord.{fieldId}`|
+| `firstfieldsRecord.recordId` | 记录 ID 数组 | `$.{stepId}.firstfieldsRecord.recordId`|
+| `fields` | 查找到的所有记录某列值 | 不支持引用|
+| `fields.{fieldId}` | 用户选择的字段 | `$.{stepId}.fields.{fieldId}`|
+| `fields.{fieldId}.fieldId` | 用户选择的字段id数组 | `$.{stepId}.fields.{fieldId}.fieldId`|
+| `fields.{fieldId}.fieldName` | 用户选择的字段名数组 | `$.{stepId}.fields.{fieldId}.fieldName`|
+| `fields.recordId` | 记录 ID 数组 | `$.{stepId}.fields.recordId`|
+| `recordNum` | 找到记录总数 | `$.{stepId}.recordNum`|
+
+##### AddRecordAction(新增记录)
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| `{fieldId}` | 用户配置的字段值,可下钻字段属性 | `$.{stepId}.{fieldId}` |
+| `{fieldId}.fieldId` | 用户配置的字段id | `$.{stepId}.{fieldId}.fieldId}` |
+| `{fieldId}.fieldName` | 用户配置的字段名 | `$.{stepId}.{fieldId}.fieldName}` |
+| `recordId` | 新增的记录 ID | `$.{stepId}.recordId` |
+| `recordLink` | 新增的记录 URL | `$.{stepId}.recordLink` |
+
+##### SetRecordAction(更新记录)
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| `{fieldId}` | 用户配置的字段值,可下钻字段属性 | `$.{stepId}.{fieldId}` |
+| `{fieldId}.fieldId` | 用户配置的字段id | `$.{stepId}.{fieldId}.fieldId}` |
+| `{fieldId}.fieldName` | 用户配置的字段名 | `$.{stepId}.{fieldId}.fieldName}` |
+| `recordId` | 记录 ID 数组(因可能更新多条记录) | `$.{stepId}.recordId` |
+
+##### GenerateAiTextAction(AI 生成文本)
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| (整体出参) | AI 生成的文本内容(不支持下钻,只能引用 `$.{stepId}`) | `$.{stepId}` |
+
+##### 无输出的操作节点
+
+以下节点不产生任何可引用的输出数据:
+
+- **Delay**(延时等待)
+- **LarkMessageAction**(发送飞书消息)
+
+---
+
+#### 分支节点输出
+
+以下分支节点均不产生任何可引用的输出数据:
+
+- **IfElseBranch**(条件分支)
+- **SwitchBranch**(多条件分支)
+
+---
+
+#### 系统节点输出
+
+##### Loop(循环)
+
+| pathId | 说明 | 引用示例 |
+|--------|------|----------|
+| `item` | 当前循环元素 | `$.{stepId}.item` |
+| `index` | 从 0 开始的循环索引 | `$.{stepId}.index` |
+
+**`item` 的类型推断规则**(由循环数据源决定):
+
+**场景一:遍历组合记录** — 数据源为 `record` 类型时(如 FindRecordAction 的 `fieldRecords`),`item` 类型为 `record`,可向下选择具体字段:
+
+| 说明 | 引用示例 |
+|------|----------|
+| 当前遍历的记录(record) | `$.{loopStepId}.item` |
+| 记录的具体字段 | `$.{loopStepId}.item.{fieldId}` |
+| 从 0 开始的索引(number) | `$.{loopStepId}.index` |
+
+**场景二:遍历字段** — 数据源为某个多值类型字段时,比如附件字段、人员字段,`item` 继承该字段的类型并可继续下钻字段属性:
+
+| 说明 | 引用示例 |
+|------|----------|
+| 当前遍历的元素(类型继承数据源字段类型,例如人员字段) | `$.{loopStepId}.item` |
+| 用户姓名 | `$.{loopStepId}.item.name` |
+| 从 0 开始的索引(number) | `$.{loopStepId}.index` |
+
+---
+
+#### 字段属性下钻
+
+每个字段变量都可以进一步下钻选择字段的属性。所有字段至少支持 `fieldId` 和 `fieldName` 两个基础属性,部分字段还支持额外属性:
+
+| 字段类型 | 属性名称 | 属性 pathId | 属性 pathType | 说明 |
+|----------|---------|-------------|--------------|------|
+| **所有字段(基础)** | 字段 ID | `fieldId` | `string` | 字段的唯一标识 |
+| | 字段名称 | `fieldName` | `string` | 字段的显示名称 |
+| **人员字段**(User / CreatedUser / ModifiedUser) | 姓名 | `name` | `string` | 用户姓名 |
+| **日期字段**(DateTime / CreatedTime / ModifiedTime) | 时间戳 | `timestamp` | `number` | 时间戳数值 |
+| **附件字段**(Attachment) | 文件名 | `fileName` | `string` | 附件文件名 |
+| | 文件类型 | `fileType` | `string` | MIME 类型 |
+| | 文件大小 | `size` | `number` | 文件字节数 |
+| | 文件 Token | `fileToken` | `string` | 附件 token |
+| **超链接字段**(URL) | 文本 | `text` | `string` | 链接文本部分 |
+| | 链接 | `link` | `string` | 链接 URL 部分 |
+| **自动编号字段**(AutoNumber) | 序号 | `sequence` | `number` | 编号的纯数字序号 |
+| **关联字段**(SingleLink / DuplexLink) | 字段下钻 | `{fieldId}` | - | 可下钻到关联表的字段 |
+
+> 其他字段类型(如文本、数字、复选框、单选/多选、电话、地理位置、进度、公式、引用查找等)仅支持 `fieldId` 和 `fieldName` 两个基础属性。
+
+下钻引用示例:
+
+```
+$.{stepId}.{fieldId}              → 字段值本身
+$.{stepId}.{fieldId}.fieldId      → 字段 ID(string)
+$.{stepId}.{fieldId}.fieldName    → 字段名称(string)
+$.{stepId}.{fieldId}.name         → 人员姓名列表(array<string>,仅人员字段)
+$.{stepId}.{fieldId}.unionId      → 人员 unionId 列表(array<string>,仅人员字段)
+$.{stepId}.{fieldId}.timestamp    → 时间戳(array<number>,仅日期字段)
+$.{stepId}.{fieldId}.fileName     → 文件名列表(array<string>,仅附件字段)
+$.{stepId}.{fieldId}.fileToken    → 文件 Token 列表(array<string>,仅附件字段)
+```
+
+---
+
+#### 节点输出能力总览
+
+| 节点 | 类型 | 有输出 | 输出特性 |
+|------|------|--------|---------|
+| AddRecordTrigger | 触发器 | ✅ | 动态(表字段 + 记录属性) |
+| ChangeRecordTrigger | 触发器 | ✅ | 动态(表字段 + 记录属性) |
+| SetRecordTrigger | 触发器 | ✅ | 动态(表字段 + 记录属性) |
+| ReminderTrigger | 触发器 | ✅ | 动态(表字段 + 记录属性) |
+| TimerTrigger | 触发器 | ✅ | 静态(仅 scheduleTime) |
+| LarkMessageTrigger | 触发器 | ✅ | 静态(消息属性列表) |
+| FindRecordAction | 动作 | ✅ | 动态(用户选择的字段) |
+| AddRecordAction | 动作 | ✅ | 动态(用户配置的字段) |
+| SetRecordAction | 动作 | ✅ | 动态(用户配置的字段) |
+| GenerateAiTextAction | 动作 | ✅ | 静态(单 string) |
+| Delay | 动作 | ❌ | 无输出 |
+| LarkMessageAction | 动作 | ❌ | 无输出 |
+| IfElseBranch | 分支 | ❌ | 无输出 |
+| SwitchBranch | 分支 | ❌ | 无输出 |
+| Loop | 系统 | ✅ | 动态(取决于数据源) |
+
+---
+
+### TextRefItem
+
+文本与引用混排,用于消息内容等动态拼接场景:
+
+```json
+[
+  { "value_type": "text", "value": "客户 " },
+  { "value_type": "ref", "value": "$.step_1.fieldxxx" },
+  { "value_type": "text", "value": " 创建了新订单" }
+]
+```
+
+### RecordFieldValue
+
+```json
+{ "field_name": "客户名称", "value": [{ "value_type": "text", "value": "张三" }] }
+```
+
+### AndCondition(Trigger 过滤条件)
+
+```json
+{
+  "conjunction": "and",
+  "conditions": [
+    { "field_name": "状态", "operator": "is", "value": [{ "value_type": "text", "value": "进行中" }] }
+  ]
+}
+```
+
+### OrGroup(Branch 分支条件)
+
+```json
+{
+  "conjunction": "or",
+  "conditions": [
+    {
+      "conjunction": "and",
+      "conditions": [
+        {
+          "left_value": { "value_type": "ref", "value": "$.step_1.fieldxxx" },
+          "operator": "isGreater",
+          "right_value": [{ "value_type": "number", "value": 1000 }]
+        }
+      ]
+    }
+  ]
+}
+```
+
+**operator 可选值:** `is` / `isNot` / `containsAny` / `doesNotContainAny` / /`containsAll`/ `isEmpty` / `isNotEmpty` / `isGreater` / `isGreaterEqual` / `isLess` / `isLessEqual`
+
+### RecordFilterInfo
+** 由于 conjunction 只支持 and,若需要实现 字段X 等于 A 或 B,你可以使用 containsAny
+```json
+{
+  "conjunction": "and",
+  "conditions": [
+    { "field_name": "状态", "operator": "is", "value": [{ "value_type": "text", "value": "进行中" }] }
+  ]
+}
+```
+
+### Select / MultiSelect 字段多值匹配
+
+| 操作 | operator | 正确写法 |
+|------|---------|---------|
+| 等于单个值 | `is` | `[{"value_type": "option", "value": {"name": "L2"}}]` |
+| 匹配多个值(L2 或 L3) | `containsAny` | `[{"value_type": "option", "value": {"name": "L2"}}, {"value_type": "option", "value": {"name": "L3"}}]` |
+
+> ⚠️ 不要用多个 `is` 条件(会被当作 OR,无法实现 AND)。推荐使用 `containsAny` 操作符匹配多个值。
+
+> ⚠️ **Select 字段条件**:`value_type` 必须为 `option`,`value` 对象可只传 `name`(如 `{"name": "L2"}`),无需提供选项 ID。
+
+### RefInfo
+
+```json
+{ "step_id": "step_trigger" }
+```
+
+---
+
+## 完整示例:条件分支 + 发送消息
+
+```json
+{
+  "title": "新订单自动通知",
+  "steps": [
+    {
+      "id": "step_1",
+      "type": "AddRecordTrigger",
+      "title": "当「订单表」新增记录时触发",
+      "next": "step_2",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "订单编号"
+      }
+    },
+    {
+      "id": "step_2",
+      "type": "IfElseBranch",
+      "title": "判断订单金额是否大于 1000",
+      "children": {
+        "links": [
+          { "kind": "if_true", "to": "step_3" },
+          { "kind": "if_false", "to": "step_4" }
+        ]
+      },
+      "next": "step_5",
+      "data": {
+        "condition": {
+          "conjunction": "or",
+          "conditions": [{
+            "conjunction": "and",
+            "conditions": [{
+              "left_value": { "value_type": "ref", "value": "$.step_1.fieldxxx" },
+              "operator": "isGreater",
+              "right_value": [{ "value_type": "number", "value": 1000 }]
+            }]
+          }]
+        }
+      }
+    },
+    {
+      "id": "step_3",
+      "type": "LarkMessageAction",
+      "title": "通知主管审批大额订单",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "ref", "value": "$.step_1.fieldxxx" }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "大额订单提醒" }],
+        "content": [
+          { "value_type": "text", "value": "新订单金额为:" },
+          { "value_type": "ref", "value": "$.step_1.fieldxxx" },
+          { "value_type": "text", "value": "元,请及时审批。" }
+        ],
+        "btn_list": []
+      }
+    },
+    {
+      "id": "step_4",
+      "type": "SetRecordAction",
+      "title": "自动标记小额订单为已通过",
+      "next": null,
+      "data": {
+        "table_name": "订单表",
+        "ref_info": { "step_id": "step_1" },
+        "field_values": [
+          { "field_name": "审批状态", "value": [{ "value_type": "text", "value": "已通过" }] }
+        ]
+      }
+    },
+    {
+      "id": "step_5",
+      "type": "GenerateAiTextAction",
+      "title": "AI 生成订单处理日报",
+      "next": null,
+      "data": {
+        "prompt": [
+          { "value_type": "text", "value": "请根据以下订单信息生成一份简要的处理日报:" },
+          { "value_type": "ref", "value": "$.step_1.fieldxxx" }
+        ]
+      }
+    }
+  ]
+}
+```
+
+---
+
+## 参考
+
+- [lark-base-workflow-create](lark-base-workflow-create.md) — 创建工作流命令
+- [lark-base-workflow-update](lark-base-workflow-update.md) — 更新工作流命令
+- [lark-base-workflow-list](lark-base-workflow-list.md) — 列出工作流命令

+ 167 - 0
.agents/skills/lark-base/references/lark-base-workflow-update.md

@@ -0,0 +1,167 @@
+# base +workflow-update
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+全量替换 Base 中一个已有工作流的定义(`title` 和/或 `steps`)。使用 PUT 语义,传入的内容会完整覆盖原有定义。
+
+## ⚠️ 执行前必读
+
+更新工作流前请按顺序完成:
+
+1. **先读本文档**,了解 `--json` 参数格式和 PUT 全量覆盖的语义
+2. **阅读 [workflow-guide.md](lark-base-workflow-guide.md)**,获取 Loop、IfElseBranch、SwitchBranch 等**完整示例**(与创建场景共用相同的步骤结构)
+3. **参考 [workflow-schema.md](lark-base-workflow-schema.md)**,查询具体字段定义
+4. **按需调用 `+workflow-list`** 获取工作流 ID(`wkf` 开头)
+5. **如需基于现有工作流修改**,先调用 `+workflow-get` 导出当前定义,在此基础上修改
+
+## 推荐命令
+
+```bash
+lark-cli base +workflow-update \
+  --base-token BascXxxxxx \
+  --workflow-id wkfosaYTS1V6rhjF \
+  --json '{"title":"新标题","steps":[{"id":"trigger_1","type":"AddRecordTrigger","title":"监控新订单","next":"action_1","data":{"table_name":"订单表","watched_field_name":"订单号"}},{"id":"action_1","type":"LarkMessageAction","title":"发送通知","next":null,"data":{"receiver":[{"value_type":"user","value":{"id":"ou_xxxx"}}],"send_to_everyone":false,"title":[{"value_type":"text","value":"新订单提醒"}],"content":[{"value_type":"text","value":"收到新订单"}],"btn_list":[]}}]}'
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--base-token <token>` | 是 | 多维表格 Base Token(`Basc` 开头) |
+| `--workflow-id <id>` | 是 | 工作流 ID(`wkf` 开头),可从 `+workflow-list` 获取 |
+| `--json <body>` | 是 | 工作流 body JSON,包含 `title` 和/或 `steps`|
+
+## 如何从链接中提取参数
+
+用户通常会提供如下 URL:
+
+```
+https://example.feishu.cn/base/<base_token>?table=<table_or_workflow_id>
+```
+
+- `--base-token`:取 `/base/` 后面的字符串(`Basc` 开头)
+- `--workflow-id`:取 `?table=` 后面的值,当其以 `wkf` 开头时即为 workflow_id
+
+> ⚠️ **注意区分 ID 前缀**:table_id 以 `tbl` 开头,workflow_id 以 `wkf` 开头。
+
+## API 入参详情
+
+**HTTP 方法和路径:**
+
+```
+PUT /open-apis/base/v3/bases/:base_token/workflows/:workflow_id
+```
+
+**Path 参数:**
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `base_token` | 是 | 多维表格 Base Token |
+| `workflow_id` | 是 | 工作流唯一标识(`wkf` 开头) |
+
+**Request Body(JSON):**
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `title` | string | 否 | 工作流标题 |
+| `steps` | WorkflowStep[] | 否 | 步骤列表(PUT 语义,全量替换) |
+| `user_id_type` | string | 否 | 用户 ID 类型:`open_id` / `union_id` / `user_id`,默认 `open_id` |
+
+> **步骤数据结构非常复杂,详见 [lark-base-workflow-schema.md](lark-base-workflow-schema.md)**
+
+**Request Body 示例:**
+
+```json
+{
+  "title": "新订单自动通知(更新版)",
+  "steps": [
+    {
+      "id": "trigger_1",
+      "type": "AddRecordTrigger",
+      "title": "监控新订单",
+      "next": "action_1",
+      "data": {
+        "table_name": "订单表",
+        "watched_field_name": "订单号"
+      }
+    },
+    {
+      "id": "action_1",
+      "type": "LarkMessageAction",
+      "title": "发送通知",
+      "next": null,
+      "data": {
+        "receiver": [{ "value_type": "user", "value": {"id": "ou_xxxx"} }],
+        "send_to_everyone": false,
+        "title": [{ "value_type": "text", "value": "新订单提醒" }],
+        "content": [
+          { "value_type": "text", "value": "收到新订单,客户:" },
+          { "value_type": "ref", "value": "$.trigger_1.fldCustomerName" }
+        ],
+        "btn_list": []
+      }
+    }
+  ]
+}
+```
+
+> **注意**:Trigger 和 Action 节点不应设置 `children` 字段,只有 Branch(如 IfElseBranch、SwitchBranch)和 System(如 Loop)节点才需要 `children` 来描述分支或循环结构。
+
+## API 出参详情
+
+**Response `data` 字段:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `workflow_id` | string | 工作流唯一 ID(`wkf` 开头) |
+| `title` | string | 更新后的工作流标题 |
+| `status` | string | 当前状态:`enabled` / `disabled` |
+| `steps` | WorkflowStep[] | 完整步骤列表(更新后) |
+| `creator_id` | string | 创建人 OpenID |
+| `updater_id` | string | 最后修改人 OpenID |
+| `create_time` | number | 创建时间(Unix 秒级时间戳) |
+| `update_time` | number | 更新时间(Unix 秒级时间戳) |
+
+## 返回值
+
+```json
+{
+  "ok": true,
+  "data": {
+    "workflow_id": "wkfosaYTS1V6rhjF",
+    "title": "新订单自动通知(更新版)",
+    "status": "disabled",
+    "steps": [...],
+    "creator_id": "ou_xxxx",
+    "updater_id": "ou_yyyy",
+    "create_time": 1704067200,
+    "update_time": 1704153600
+  }
+}
+```
+
+## 工作流
+
+> [!CAUTION]
+> 这是**写入操作** — 执行前必须向用户确认。PUT 语义,会**完整覆盖**原有工作流定义。
+
+1. 确认 `--base-token` 和 `--workflow-id`(建议先用 `+workflow-list` 查出 ID)
+2. 确认 `--json` 的完整内容 — PUT 会全量覆盖,漏传 `steps` 会清空所有步骤
+3. 执行命令,报告返回的 `workflow_id` 和 `update_time`
+
+## 坑点
+
+- ⚠️ **PUT 是全量覆盖**:传什么就写什么;如果只传 `title` 不传 `steps`,原有 steps 会被清空;如需只改标题,使用 PATCH 接口(目前无对应 shortcut,可参考 API 文档直接调用)
+- ⚠️ **workflow_id 前缀**:以 `wkf` 开头,从 URL 的 `?table=wkf...` 提取;和 table_id(`tbl` 开头)混淆会导致 `[2200] Internal Error`
+- ⚠️ **steps 中 id 字段必须唯一**:每个步骤的 `id` 在同一工作流内必须唯一;`next` 和 `children.links[].to` 引用的 ID 必须在 steps 数组中存在
+- ⚠️ **更新不影响 enabled 状态**:`+workflow-update` 不会改变工作流的 `enabled/disabled` 状态;需要另外调用 `+workflow-enable` / `+workflow-disable`
+
+## 参考
+
+- [lark-base-workflow-schema.md](lark-base-workflow-schema.md) — Workflow 数据结构参考
+- [lark-base-workflow-guide.md](lark-base-workflow-guide.md) — **完整示例、构造技巧、常见错误**
+- [lark-base-workflow-create](lark-base-workflow-create.md) — 创建工作流
+- [lark-base-workflow-enable](lark-base-workflow-enable.md) — 启用工作流
+- [lark-base-workflow-list](lark-base-workflow-list.md) — 列出全部工作流
+- [lark-base](../SKILL.md) — 多维表格全部命令
+- [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数

+ 23 - 0
.agents/skills/lark-base/references/lark-base-workflow.md

@@ -0,0 +1,23 @@
+# base workflow shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+workflow 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-workflow-list.md](lark-base-workflow-list.md) | `+workflow-list` | 列出 Base 中所有自动化工作流 |
+| [lark-base-workflow-get.md](lark-base-workflow-get.md) | `+workflow-get` | 获取单工作流的详情和完整结构 |
+| [lark-base-workflow-create.md](lark-base-workflow-create.md) | `+workflow-create` | 创建一个新的自动化工作流 |
+| [lark-base-workflow-update.md](lark-base-workflow-update.md) | `+workflow-update` | 全量替换已有工作流的定义 |
+| [lark-base-workflow-enable.md](lark-base-workflow-enable.md) | `+workflow-enable` | 启用一个自动化工作流 |
+| [lark-base-workflow-disable.md](lark-base-workflow-disable.md) | `+workflow-disable` | 禁用一个自动化工作流 |
+| [lark-base-workflow-schema.md](lark-base-workflow-schema.md) | (数据结构参考) | Workflow 的创建和更新结构规范 |
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- **配置前置依赖**:在创建或更新 workflow 之前,大概率需要获取数据表(table)或字段(field)的真实 ID 等信息作为工作流节点的参数。建议按需先查阅 [table 命令索引](lark-base-table.md) 或 [field 命令索引](lark-base-field.md) 获取结构。
+- **Schema 结构必读**:在创建或更新 workflow 前,必须仔细阅读 [lark-base-workflow-schema.md](lark-base-workflow-schema.md) 了解各触发器和节点组件的具体结构。

+ 18 - 0
.agents/skills/lark-base/references/lark-base-workspace.md

@@ -0,0 +1,18 @@
+# base / workspace shortcuts
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+base / workspace 相关命令索引。
+
+## 命令导航
+
+| 文档 | 命令 | 说明 |
+|------|------|------|
+| [lark-base-base-create.md](lark-base-base-create.md) | `+base-create` | 创建 Base |
+| [lark-base-base-get.md](lark-base-base-get.md) | `+base-get` | 获取 Base 详情 |
+| [lark-base-base-copy.md](lark-base-base-copy.md) | `+base-copy` | 复制 Base |
+
+## 说明
+
+- 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。
+- `+base-*` 负责 Base 生命周期动作。

+ 508 - 0
.agents/skills/lark-base/references/lookup-field-guide.md

@@ -0,0 +1,508 @@
+# Base Lookup Field Configuration Guide
+
+## Mandatory Read Acknowledgement
+
+When creating or updating a lookup field with `lark-cli base +field-create/+field-update --json ...` and `type` is `lookup`, you should read this guide first and only then add `--i-have-read-guide` to the command.
+
+Do **not** proactively add `--i-have-read-guide` before reading this guide. Without it, the CLI will fail fast and direct you back to this guide.
+
+## Default strategy
+
+**Use Formula fields by default for cross-table references and aggregations.** Only use Lookup fields when the user explicitly requests a Lookup field. Formula is a strict superset of Lookup — anything Lookup can do, Formula can do with a single expression.
+
+## Usage
+
+When creating a lookup field, the Agent should:
+
+1. Get all table names: `lark-cli base +table-list --base-token <base>` — returns `items[].table_name`
+2. Get table structure: `lark-cli base +table-get --base-token <base> --table-id <table>` — returns `fields[]`
+3. If the lookup references other tables, also get those tables' structures
+4. Determine the four elements: from (source table), select (source field), where (filter), aggregate (aggregation)
+5. Construct the Lookup field JSON and submit it to create or update the field
+
+**Key constraints**:
+
+- Table names and field names must **exactly match** those returned by `+table-list` / `+table-get`
+- The `from` table must be in the same Base
+
+---
+
+## Section 1: Core Concepts — Four-Element Model
+
+A Lookup field is defined by five fields:
+
+| Field | Meaning | JSON key | Required |
+|-------|---------|----------|----------|
+| **type** | Must be `"lookup"` | `type` | Yes |
+| **from** | Source table to pull data from | `from` | Yes |
+| **select** | Field in the source table to retrieve | `select` | Yes |
+| **where** | Filter conditions on the source table | `where` | Yes (at least one condition) |
+| **aggregate** | How to aggregate multiple matching records | `aggregate` | No (default: `raw_value`) |
+
+**SQL analogy**:
+
+```
+SELECT  [select field]
+FROM    [from table]
+WHERE   [filter conditions]
+GROUP BY [aggregate function]
+```
+
+**Row-level matching (most important concept)**:
+
+A Lookup field is computed row-by-row — for each row in the current table, it filters the source table to find "related" records. **The filter defines what "related" means.**
+
+```
+Current table row 1 → filter source table → matching records → select field → aggregate → result
+Current table row 2 → filter source table → matching records → select field → aggregate → result
+...
+```
+
+**Rule: Whenever the current table and the source table have a row-level correspondence (matching by some field value), you must specify a filter.**
+
+---
+
+## Section 2: Lookup vs Link vs Formula
+
+Lookup and Link serve **different purposes**. Creating a Lookup does NOT require a Link field to exist first.
+
+| Dimension | Link | Lookup | Formula |
+|-----------|------|--------|---------|
+| Purpose | Establish record relationships (read-write) | Pull and aggregate data from another table (read-only) | Compute values from expressions (read-only) |
+| When to use | "link" / "associate" / "bind" two tables | "look up" / "reference" / "aggregate" / "count" from another table | Calculations, text manipulation, conditional logic |
+
+**Common mistake**: Creating a Link field just to create a Lookup. If two tables share a matching text/number field, Lookup can match directly — no Link required.
+
+**Selection decision tree**:
+
+```
+What does the user need?
+├─ "Link"/"associate"/"bind" records between tables → Link
+├─ "Look up"/"reference"/"aggregate"/"count" from another table → Lookup
+│   ├─ Needs aggregation (sum/count/average)? → Lookup + aggregate
+│   └─ Just reference a value? → Lookup (aggregate = null)
+├─ Calculations/text manipulation within current table → Formula
+└─ Access linked record's field → Prefer Lookup (more intuitive), or Formula chain access
+```
+
+---
+
+## Section 3: Filter Condition Rules
+
+**You must provide a `where` with at least one condition.** Improper conditions cause every row to pull all records from the source table.
+
+### The Iron Rule: field belongs to source table
+
+```
+filter condition:
+  field   → must be a field in the FROM table (source table)
+  value   → constant or reference to a field in the CURRENT table
+```
+
+### How to find the matching field pair
+
+**With a Link field (most common)**: The match is between the **Link field** and the **target table's primary field**.
+
+```
+Link is in the source table   → source.linkField matches current.primaryField
+Link is in the current table  → source.primaryField matches current.linkField
+```
+
+**Without a Link field**: Two tables share a field with the same meaning — match directly.
+
+### Where condition structure
+
+Each condition is a **tuple** (array) of 2 or 3 elements: `[field, operator, value?]`
+
+```json
+{
+  "logic": "and",
+  "conditions": [
+    ["<source table field>", "<operator>", { "type": "constant", "value": "<val>" }]
+  ]
+}
+```
+
+For `empty` / `non_empty`, the value can be omitted (2-element tuple):
+
+```json
+["<source table field>", "empty"]
+```
+
+### Two value formats
+
+**Constant value** — for fixed conditions (e.g., "status is completed"):
+
+```json
+["状态", "==", { "type": "constant", "value": "已完成" }]
+```
+
+**Field reference** — for dynamic per-row matching (e.g., "match current row's project"):
+
+```json
+["项目名", "==", { "type": "field_ref", "field": "项目名" }]
+```
+
+**Decision guide**: Fixed condition (e.g., "status is completed") → `constant`. Dynamic condition (e.g., "match current record's project ID") → `field_ref`.
+
+### Constant value format by field type
+
+The `value` inside `{ "type": "constant", "value": ... }` varies by field type:
+
+| Field type | Constant value format | Example |
+|-----------|----------------------|---------|
+| Text / Phone / Email / Url | String | `"已完成"` |
+| Number / Currency / Progress / Rating | Number | `100`, `0.8` |
+| DateTime / CreatedTime / ModifiedTime | Duration tuple | `["ExactDate", "2025-01-01"]`, `["Today"]`, `["Yesterday"]`, `["Tomorrow"]` |
+| SingleSelect / MultiSelect | Option ID or ID array | `"opt_xxx"`, `["opt_xxx", "opt_yyy"]` |
+| Link (SingleLink / DuplexLink) | Record ID or ID array | `"rec_xxx"`, `["rec_xxx", "rec_yyy"]` |
+| User | User ID or ID array | `"123"`, `["123", "456"]` |
+| Checkbox | Boolean | `true`, `false` |
+| Attachment / Location | Only `empty` / `non_empty` | value must be `null` or omitted |
+| AutoNumber | Not supported for constant comparison | Use dynamic field\_ref instead |
+| Formula / Lookup (exact type) | Follow the underlying type rules | — |
+| Formula / Lookup (fuzzy type) | String | `"some text"` |
+
+**DateTime notes**:
+- Only `ExactDate`, `Today`, `Yesterday`, `Tomorrow` are supported as duration formats
+- `["ExactDate", "2025-01-01"]` means the exact moment `2025-01-01 00:00:00`, NOT the entire day
+- For complex or relative date filtering, consider using a Formula field instead
+
+### Dynamic field reference — set comparison semantics
+
+When using `{ "type": "field_ref", "field": "..." }`, values from both sides are first **converted to sets** at runtime, then compared using set operations:
+
+- **`==`**: Sets are exactly equal (strict matching)
+- **`intersects`**: Sets have a non-empty intersection (most commonly used)
+
+**Conversion rules by field type**:
+
+| Field type | Converted to |
+|-----------|-------------|
+| Text / Phone / Email / Url | Single-element string set |
+| Number / Currency / AutoNumber / DateTime | Single-element number set |
+| SingleSelect / MultiSelect | Set of option name strings |
+| User | Set of user name strings |
+| Link (SingleLink / DuplexLink) | Set of linked records' primary field string representations |
+| Formula / Lookup | The computed value set |
+
+**Examples**:
+- User field `["name1", "name2"]` **intersects** text `"name1"` → true; **==** text `"name1"` → false (sets not equal)
+- User field `["name1"]` **==** text `"name1"` → true (single-element sets are equal)
+- Link field referencing records → converted to primary field strings, then compared
+
+### Supported operators
+
+| Operator | Meaning | Applicable types |
+|----------|---------|-----------------|
+| `==` | Equal (exact match) | All types |
+| `!=` | Not equal | All types |
+| `>` | Greater than | Number, DateTime |
+| `>=` | Greater than or equal | Number, DateTime |
+| `<` | Less than | Number, DateTime |
+| `<=` | Less than or equal | Number, DateTime |
+| `intersects` | Has intersection (non-empty overlap) | All types (most commonly used for dynamic field\_ref) |
+| `disjoint` | No intersection | All types |
+| `empty` | Field is empty | All types (value must be null or omitted) |
+| `non_empty` | Field is not empty | All types (value must be null or omitted) |
+
+### Constraints
+
+- **Only one level of and/or** — nesting (e.g., `{ and: [{ or: [...] }] }`) is not supported
+- **At least one condition** — empty conditions array will error
+
+---
+
+## Section 4: Aggregate Rules
+
+| Aggregate | Common user phrasing | Select field should be | Result type |
+|-----------|---------------------|----------------------|-------------|
+| `sum` | "total" / "sum" / "cumulative amount" | Numeric field (e.g., amount) | Number |
+| `average` | "average" / "mean" | Numeric field | Number |
+| `max` | "maximum" / "latest" / "most recent" | Numeric / DateTime field | Same as source |
+| `min` | "minimum" / "earliest" | Numeric / DateTime field | Same as source |
+| `counta` | "count" / "how many" / "total number" | Any field | Number |
+| `unique_counta` | "count distinct" / "how many different" | Field to deduplicate | Number |
+| `unique` | "list distinct" / "which ones" / "show different" | Field to display | List |
+| `raw_value` | "list all" / "show all values" (default) | Field to display | List |
+
+**Common confusion**: `unique` returns a **deduplicated list**, `unique_counta` returns a **count**. "Which categories are involved" → `unique`; "How many categories" → `unique_counta`.
+
+**Important**:
+- Enum values are **snake_case lowercase**: `sum` not `Sum`, `average` not `Average`
+- **Count is `counta`, NOT `count`** — this is the most common enum mistake
+
+---
+
+## Section 5: Hard Constraints
+
+1. **Always write a filter**: The `where` field is required with at least one condition. Whenever the current table and source table have row-level correspondence, the condition should express that relationship.
+2. **Lookup fields are read-only**: Cell values cannot be manually set.
+3. **Create Lookup after all dependent fields exist**: The source table and referenced fields must exist before creating the Lookup field.
+4. **Source table must be in the same Base**: Cross-Base lookups are not supported.
+5. **Changing `from` requires changing `select`**: Updating the source table without updating the select field will error.
+
+---
+
+## Section 6: Decision Trees
+
+### How to build the filter
+
+```
+Step 1: Analyze the filtering semantics in the user's request
+  "Count artworks per exhibition" → filter: belongs to exhibition = current exhibition
+  "Sum completed order amounts"   → filter: status = completed AND project = current project
+
+Step 2: Find the matching field pair
+  ├─ Tables have a Link relationship?
+  │   ├─ Link is in source table → source.linkField matches current.primaryField
+  │   └─ Link is in current table → source.primaryField matches current.linkField
+  ├─ Tables share same-meaning text/number field? → source.field matches current.field
+  └─ Also need constant filtering? → AND combination
+```
+
+### Which aggregate?
+
+```
+How to handle multiple matching records?
+├─ Show all values as-is → raw_value (default)
+├─ Show deduplicated list → unique
+├─ Sum → sum
+├─ Average → average
+├─ Maximum / minimum → max / min
+├─ Count records → counta
+└─ Count distinct → unique_counta
+```
+
+---
+
+## Section 7: Common Configuration Patterns
+
+> Patterns are categorized by **filter matching method**. Aggregate choice is independent — see Section 4.
+
+### Pattern 1: Aggregate from a linked table (Link is in the source table)
+
+**Scenario**: "Count artworks per exhibition", "Sum order amounts per project"
+
+When the source table has a Link pointing to the current table:
+
+```
+Exhibition table: ExhibitionName (primaryField)           ← current table
+Artwork table:    ArtworkName (primaryField),             ← source table (Link is here)
+                  Exhibition (Link → Exhibition table)
+```
+
+```json
+{
+  "type": "lookup",
+  "name": "Artwork Count",
+  "from": "Artwork table",
+  "select": "ArtworkName",
+  "aggregate": "counta",
+  "where": {
+    "logic": "and",
+    "conditions": [
+      ["Exhibition", "intersects", { "type": "field_ref", "field": "ExhibitionName" }]
+    ]
+  }
+}
+```
+
+### Pattern 2: Reference a linked record's field (Link is in the current table)
+
+**Scenario**: "Show supplier's contact person", "Display warehouse manager"
+
+When the current table has a Link pointing to the source table:
+
+```
+Supplier table:  SupplierName (primaryField), Contact (Text)       ← source table
+Inventory table: ProductName (primaryField),                        ← current table (Link is here)
+                 Supplier (Link → Supplier table)
+```
+
+```json
+{
+  "type": "lookup",
+  "name": "Supplier Contact",
+  "from": "Supplier table",
+  "select": "Contact",
+  "where": {
+    "logic": "and",
+    "conditions": [
+      ["SupplierName", "intersects", { "type": "field_ref", "field": "Supplier" }]
+    ]
+  }
+}
+```
+
+### Pattern 3: Match by same-meaning field (no Link)
+
+**Scenario**: "Sum order amounts per project" (tables share a "ProjectName" field but no Link)
+
+```
+Project table: ProjectName (primaryField)                          ← current table
+Order table:   OrderID (primaryField), ProjectName (Text),         ← source table
+               Amount (Number)
+```
+
+```json
+{
+  "type": "lookup",
+  "name": "Order Total",
+  "from": "Order table",
+  "select": "Amount",
+  "aggregate": "sum",
+  "where": {
+    "logic": "and",
+    "conditions": [
+      ["ProjectName", "==", { "type": "field_ref", "field": "ProjectName" }]
+    ]
+  }
+}
+```
+
+### Pattern 4: Dynamic matching + constant filtering
+
+**Scenario**: "Only count completed orders", "Only sum approved budgets"
+
+Combine row-level matching with fixed-value filtering using `logic: "and"`:
+
+```json
+{
+  "type": "lookup",
+  "name": "Completed Order Amount",
+  "from": "Order table",
+  "select": "Amount",
+  "aggregate": "sum",
+  "where": {
+    "logic": "and",
+    "conditions": [
+      ["Manager", "==", { "type": "field_ref", "field": "EmployeeName" }],
+      ["Status", "==", { "type": "constant", "value": "Completed" }]
+    ]
+  }
+}
+```
+
+### Pattern 5: Date filtering with constant value
+
+**Scenario**: "Look up orders created after 2025-01-01", "Sum today's sales"
+
+```json
+{
+  "type": "lookup",
+  "name": "Recent Orders",
+  "from": "Order table",
+  "select": "Amount",
+  "aggregate": "sum",
+  "where": {
+    "logic": "and",
+    "conditions": [
+      ["ProjectName", "==", { "type": "field_ref", "field": "ProjectName" }],
+      ["CreatedDate", ">=", { "type": "constant", "value": ["ExactDate", "2025-01-01"] }]
+    ]
+  }
+}
+```
+
+---
+
+## Section 8: Anti-Pattern Collection
+
+### Mistake 1: Omitting where (most common)
+
+```json
+// Wrong: no where, every row pulls all records
+{ "type": "lookup", "name": "Artwork Count", "from": "Artwork table", "select": "ArtworkName", "aggregate": "counta" }
+
+// Correct: where with Link relationship
+{ "type": "lookup", "name": "Artwork Count", "from": "Artwork table", "select": "ArtworkName", "aggregate": "counta",
+  "where": { "logic": "and", "conditions": [
+    ["Exhibition", "intersects", { "type": "field_ref", "field": "ExhibitionName" }]
+  ]}}
+```
+
+### Mistake 2: Wrong value type — confusing constant vs field_ref
+
+```json
+// Wrong: using constant for a dynamic join
+["ProjectName", "==", { "type": "constant", "value": "ProjectName" }]
+
+// Correct: use field_ref for dynamic per-row matching
+["ProjectName", "==", { "type": "field_ref", "field": "ProjectName" }]
+```
+
+### Mistake 3: Using `count` instead of `counta`
+
+```json
+// Wrong
+{ "aggregate": "count" }
+
+// Correct
+{ "aggregate": "counta" }
+```
+
+### Mistake 4: Wrong case for aggregate values
+
+```json
+// Wrong
+{ "aggregate": "SUM" }
+{ "aggregate": "Sum" }
+
+// Correct — snake_case lowercase
+{ "aggregate": "sum" }
+{ "aggregate": "average" }
+```
+
+### Mistake 5: Nested where conditions
+
+```json
+// Wrong: nesting not supported
+{ "logic": "and", "conditions": [
+  { "logic": "or", "conditions": [...] }
+]}
+
+// Correct: only one level
+{ "logic": "and", "conditions": [cond1, cond2, cond3] }
+```
+
+### Mistake 6: Confusing Lookup with Link
+
+The user says "aggregate order amounts" — use Lookup, not Link. Link establishes relationships; Lookup retrieves and aggregates data.
+
+### Mistake 7: Using object format instead of tuple for conditions
+
+```json
+// Wrong: object format
+{ "fieldRef": "Status", "operator": "is", "value": { "type": "constant", "value": "Done" } }
+
+// Correct: tuple format [field, operator, value?]
+["Status", "==", { "type": "constant", "value": "Done" }]
+```
+
+### Mistake 8: Missing `type` field
+
+```json
+// Wrong: no type field
+{ "name": "Total", "from": "Orders", "select": "Amount", "aggregate": "sum", "where": { ... } }
+
+// Correct: must include type
+{ "type": "lookup", "name": "Total", "from": "Orders", "select": "Amount", "aggregate": "sum", "where": { ... } }
+```
+
+---
+
+## Section 9: Constraint Summary
+
+- `type` must be `"lookup"` — this field is required in the request body
+- `where` is required with at least one condition — always specify a filter
+- Conditions use **tuple format**: `[field, operator, value?]` — NOT object format
+- Lookup fields are read-only — values cannot be manually set
+- Source table and referenced fields must exist before creating the Lookup
+- Condition field (first element of tuple) must reference a field in the source table, not the current table
+- Where supports only one level of and/or — no nesting
+- Aggregate values are snake_case lowercase: `sum`, `counta`, `unique_counta` (NOT `count`)
+- Operators: `==`, `!=`, `>`, `>=`, `<`, `<=`, `intersects`, `disjoint`, `empty`, `non_empty`
+- Table and field names must exactly match `+table-get` output
+- DateTime constant values use duration tuple format: `["ExactDate", "2025-01-01"]`, `["Today"]`, `["Yesterday"]`, `["Tomorrow"]`
+- Select/Link/User constant values use IDs, not display names

+ 532 - 0
.agents/skills/lark-base/references/role-config.md

@@ -0,0 +1,532 @@
+# 飞书多维表格角色权限配置详解
+
+> **返回**: [SKILL.md](../SKILL.md) | **相关**: [role-create](lark-base-role-create.md) · [role-update](lark-base-role-update.md) · [role-get](lark-base-role-get.md)
+
+本文档详细说明角色权限(AdvPermBaseRoleConfig)的完整 JSON 结构,供 `+role-create` 和 `+role-update` 构造 `--json` 参数时参考。
+
+## 📋 目录
+
+- [顶层结构 (AdvPermBaseRoleConfig)](#顶层结构-advpermbaseroleconfig)
+- [角色类型 (RoleType)](#角色类型-roletype)
+- [Base 级权限 (BaseRuleMap)](#base-级权限-baserulemap)
+- [仪表盘权限 (DashboardRule)](#仪表盘权限-dashboardrule)
+- [文档权限 (DocxRule)](#文档权限-docxrule)
+- [数据表权限 (TableRule)](#数据表权限-tablerule)
+    - [表级权限 (TablePerm)](#表级权限-tableperm)
+    - [视图权限 (ViewRule)](#视图权限-viewrule)
+    - [字段权限 (FieldRule)](#字段权限-fieldrule)
+    - [记录权限 (RecordRule)](#记录权限-recordrule)
+    - [筛选条件 (FilterRuleGroup)](#筛选条件-filterrulegroup)
+- [默认权限策略与风控规则](#默认权限策略与风控规则)
+    - [默认关闭项](#默认关闭项)
+    - [权限对象选择](#权限对象选择)
+    - [记录操作默认策略](#记录操作默认策略)
+    - [field_perms 构造 SOP](#field_perms-构造-sop)
+    - [视图权限默认策略](#视图权限默认策略)
+
+---
+
+## 顶层结构 (AdvPermBaseRoleConfig)
+
+```json
+{
+  "role_name": "财务审核员",
+  "role_type": "custom_role",
+  "base_rule_map": { "copy": false, "download": false },
+  "table_rule_map": { "订单表": { "perm": "edit", "...": "..." } },
+  "dashboard_rule_map": { "销售看板": { "perm": "read_only" } },
+  "docx_rule_map": { "文档A": { "perm": "edit", "allow_download": true } }
+}
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|----|------|
+| `role_name` | string | 是  | 角色名称,不能为空 |
+| `role_type` | string | 是  | 角色类型,见 [RoleType](#角色类型-roletype) |
+| `base_rule_map` | map\<string, bool\> | 是  | Base 级权限,见 [BaseRuleMap](#base-级权限-baserulemap) |
+| `table_rule_map` | map\<string, TableRule\> | 否  | 数据表权限,key 为表名 |
+| `dashboard_rule_map` | map\<string, DashboardRule\> | 否  | 仪表盘权限,key 为仪表盘名称 |
+| `docx_rule_map` | map\<string, DocxRule\> | 否  | 文档权限(仅单品模式),key 为文档名称 |
+
+---
+
+## 角色类型 (RoleType)
+
+| 值 | 说明 |
+|------|------|
+| `editor` | 系统角色:编辑者 |
+| `reader` | 系统角色:阅读者 |
+| `custom_role` | 自定义角色 |
+
+**注意**:
+- 创建接口(`+role-create`)仅支持 `custom_role`
+- 更新接口(`+role-update`)支持  `editor` / `reader` / `custom_role`
+
+---
+
+## Base 级权限 (BaseRuleMap)
+
+1. 默认值均为 `false`,当需要启用时设置为 `true`。
+2. 在新增角色和修改角色时需要默认带上这个字段,**严禁**在用户未明确要求的情况下将其设置为 `true`。
+
+```json
+{
+  "base_rule_map": {
+    "copy": true,
+    "download": false
+  }
+}
+```
+
+| Key | 说明 |
+|-----|------|
+| `copy` | 允许复制多维表格内容 |
+| `download` | 允许创建副本、下载、打印多维表格 |
+
+---
+
+## 仪表盘权限 (DashboardRule)
+
+```json
+{
+  "dashboard_rule_map": {
+    "销售看板": { "perm": "read_only" },
+    "内部数据": { "perm": "no_perm" }
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `perm` | string | 仪表盘权限 |
+
+**perm 可选值**:
+
+| 值 | 说明 |
+|----|------|
+| `read_only` | 仅可阅读 |
+| `no_perm` | 无权限 |
+
+---
+
+## 文档权限 (DocxRule)
+
+> ⚠️ 仅在单品模式(`is_base_solo = true`)下可用。
+
+```json
+{
+  "docx_rule_map": {
+    "文档A": { "perm": "edit", "allow_download": true },
+    "文档B": { "perm": "read_only" }
+  }
+}
+```
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `perm` | string | 是 | 文档权限 |
+| `allow_download` | bool | 否 | 是否允许下载/导出 |
+
+**perm 可选值**:
+
+| 值 | 说明 |
+|----|------|
+| `edit` | 可编辑 |
+| `read_only` | 仅可阅读 |
+| `no_perm` | 无权限 |
+
+---
+
+## 数据表权限 (TableRule)
+
+```json
+{
+  "table_rule_map": {
+    "订单表": {
+      "perm": "edit",
+      "view_rule": { "..." : "..." },
+      "record_rule": { "..." : "..." },
+      "field_rule": { "..." : "..." }
+    },
+    "用户表": {
+      "perm": "read_only"
+    }
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `perm` | string | 表级权限,见 [TablePerm](#表级权限-tableperm) |
+| `view_rule` | ViewRule | 视图权限配置 |
+| `record_rule` | RecordRule | 记录权限配置 |
+| `field_rule` | FieldRule | 字段权限配置 |
+
+**注意**: 当 `perm` 为 `no_perm` 时,`view_rule`、`record_rule`、`field_rule` 均无须再设置。
+
+---
+
+### 表级权限 (TablePerm)
+
+| 值 | 说明 |
+|----|------|
+| `manage` | 可管理 |
+| `edit` | 可编辑 |
+| `read_only` | 仅可阅读 |
+| `no_perm` | 无权限(此时不能再设置视图、记录和字段的权限) |
+
+---
+
+### 视图权限 (ViewRule)
+
+```json
+{
+  "view_rule": {
+    "allow_edit": true,
+    "visibility": {
+      "all_visible": false,
+      "visible_views": ["表格视图", "看板视图"]
+    }
+  }
+}
+```
+
+| 字段 | 类型 | 说明                         |
+|------|------|----------------------------|
+| `allow_edit` | bool | 可新增、删除、修改视图,未提及默认为 `false` |
+| `visibility` | object | 可见的视图配置                    |
+| `visibility.all_visible` | bool | 是否全部可见                     |
+| `visibility.visible_views` | []string | 可见视图名称 列表                  |
+
+**⚠️ 核心规则:`view_rule` 必须同时包含 `allow_edit` 和 `visibility` 两个字段,缺一不可。**
+
+输出 `view_rule` 时,**必须**使用以下完整结构,根据场景选择对应模板:
+
+```json
+// 情况 A:用户要求可编辑/新增/删除视图 → allow_edit 设为 true
+{
+  "view_rule": {
+    "allow_edit": true,
+    "visibility": {
+      "all_visible": true
+    }
+  }
+}
+
+// 情况 B:用户未提及具体视图,未要求编辑视图 → 全部可见、不可编辑
+{
+  "view_rule": {
+    "allow_edit": false,
+    "visibility": {
+      "all_visible": true
+    }
+  }
+}
+
+// 情况 C:用户提及了具体视图 → 仅指定视图可见
+{
+  "view_rule": {
+    "allow_edit": false,
+    "visibility": {
+      "all_visible": false,
+      "visible_views": ["表格视图", "看板视图"]
+    }
+  }
+}
+```
+
+**注意**:
+- 当 `all_visible` 为 `false` 时,`visible_views` 不可为空,必须指定至少一个可见视图
+- `biz_type` 为 `query_form_view` 的视图不可放在 `visible_views` 中(不能配置可见性)
+
+---
+
+### 字段权限 (FieldRule)
+
+```json
+{
+  "field_rule": {
+    "field_perm_mode": "specify",
+    "field_perms": {
+      "金额": "edit",
+      "备注": "read",
+      "密码": "no_perm"
+    },
+    "allow_edit_and_modify_option_fields": [],
+    "allow_edit_and_download_file_fields": []
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `field_perm_mode` | string | 字段权限模式 |
+| `field_perms` | map\<string, string\> | 字段名 → 权限,仅 `field_perm_mode` 为 `specify` 时有效 |
+| `allow_edit_and_modify_option_fields` | []string | 允许增删改选项的字段名列表 |
+| `allow_edit_and_download_file_fields` | []string | 允许下载附件的字段名列表 |
+
+**field_perm_mode 可选值**:
+
+| 值 | 说明 |
+|----|------|
+| `all_edit` | 所有字段可编辑,但选项不可增删改 |
+| `all_read` | 所有字段可读 |
+| `specify` | 指定字段权限(可进一步设置 `field_perms` 和选项增删改权限) |
+| `no_perm` | 无权限 |
+
+**field_perms 中单个字段的权限值**:
+
+| 值 | 说明 |
+|----|------|
+| `edit` | 可编辑(含新增和阅读权限) |
+| `create` | 可新增(含阅读权限) |
+| `read` | 可阅读 |
+| `no_perm` | 无权限 |
+
+**⚠️ field_perms 重要规则**:
+1. 写入前必须先查看字段的 `type`
+2. Formula / Lookup / AutoNumber 类型字段**必须强制**降级为 `read` 或 `no_perm`,**严禁**设为 `edit`
+3. 必须输出除 4 个系统字段外的所有字段
+4. `allow_edit_and_modify_option_fields`:仅当用户明确要求"允许增删改选项"时才配置,否则必须为空数组 `[]`。仅支持 SingleSelect / MultiSelect 类型,**严禁包含 Stage(流程)类型字段**
+5. `allow_edit_and_download_file_fields`:用户没有要求时不要设置,且仅 `field_perm_mode` 为 `specify` 时才能设置
+
+---
+
+### 记录权限 (RecordRule)
+
+```json
+{
+  "record_rule": {
+    "record_operations": ["add"],
+    "edit_filter_rule_group": {
+      "conjunction": "and",
+      "filter_rules": [
+        {
+          "conjunction": "and",
+          "filters": [
+            {
+              "field_name": "部门",
+              "operator": "is",
+              "filter_values": ["财务部"]
+            }
+          ]
+        }
+      ]
+    },
+    "other_record_all_read": true
+  }
+}
+```
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `record_operations` | []string | 记录操作权限,仅 `TablePerm = edit` 时有效 |
+| `edit_filter_rule_group` | FilterRuleGroup | 可编辑记录的筛选条件,范围为所有记录时此字段为空 |
+| `other_record_all_read` | bool | 是否可阅读所有记录。都可读时为 `true`,其他情况为 `false` |
+| `read_filter_rule_group` | FilterRuleGroup | 可阅读记录的额外筛选规则。仅当可阅读范围与可编辑范围不一致时设置(依赖 `other_record_all_read = false`) |
+
+**record_operations 可选值**:
+
+| 值 | 说明 |
+|----|------|
+| `add` | 可新增记录 |
+| `delete` | 可删除记录 |
+
+---
+
+### 筛选条件 (FilterRuleGroup)
+
+```json
+{
+  "conjunction": "and",
+  "filter_rules": [
+    {
+      "conjunction": "and",
+      "filters": [
+        {
+          "field_name": "部门",
+          "operator": "is",
+          "field_type": "SingleSelect",
+          "filter_values": ["财务部"]
+        }
+      ]
+    }
+  ]
+}
+```
+
+**FilterRuleGroup 结构**:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `conjunction` | string | 逻辑连接词:`and` / `or` |
+| `filter_rules` | []FilterRule | 筛选规则数组 |
+
+**FilterRule 结构**:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `conjunction` | string | 逻辑连接词,默认 `and` |
+| `filters` | []Filter | 筛选条件数组 |
+
+**Filter 结构**:
+
+| 字段 | 类型 | 必填 | 说明 |
+|------|------|------|------|
+| `field_name` | string | 是 | 字段名。仅限 `can_filter` 为 `true` 的字段。`field_type` 为 `CreatedUser` 时必须为空 |
+| `operator` | string | 是 | 操作符,见下表 |
+| `field_type` | string | 是 | 字段类型。仅支持:SingleSelect / MultiSelect / User / CreatedUser / Stage / Number 类字段(含进度条、评分、货币)及部分 Formula / LookUp 字段(以 `can_filter = true` 为准) |
+| `reference_type` | string | 条件 | 引用类型。`field_type` 为公式或引用字段时必须赋值,其他情况不能赋值 |
+| `filter_values` | []string | 条件 | 筛选值。`operator` 为 `isEmpty` / `isNotEmpty` 时不设置,`field_type` 为 `User` 时也无需设置,其他情况必须设置。值为选项的 `name` |
+| `field_ui_type` | string | 条件 | 该字段有值时一定要填 |
+| `is_invalid` | bool | 否 | 判断筛选条件是否有效 |
+
+**operator 可选值**:
+
+| 值 | 说明 |
+|----|------|
+| `is` | 等于 |
+| `isNot` | 不等于 |
+| `contains` | 包含 |
+| `doesNotContain` | 不包含 |
+| `isEmpty` | 为空 |
+| `isNotEmpty` | 不为空 |
+| `isGreater` | 大于 |
+| `isGreaterEqual` | 大于等于 |
+| `isLess` | 小于 |
+| `isLessEqual` | 小于等于 |
+
+**注意**:
+- `field_type`、`field_ui_type`、`reference_type` 在创建/更新角色时由服务端 filterFiller 自动补全,客户端通常只需传 `field_name`、`operator`、`filter_values`
+
+---
+
+## 默认权限策略与风控规则
+
+构造角色配置 JSON 时,采用 **默认拒绝与权限最小化** 策略。用户未明确提及的权限一律不开放,不因"合理猜测""常见做法"主动扩展权限范围。
+
+### 默认关闭项
+
+以下能力在用户未明确说明时**默认关闭**:
+
+| 能力 | 默认值 | 开启条件 |
+|------|--------|----------|
+| 未提及的数据表的任何访问 | `no_perm` | 用户明确提及该表 |
+| 仪表盘访问 | 不配置 | 用户明确提及该仪表盘 |
+| `base_rule_map.copy` | `false` | 用户明确要求"允许复制" |
+| `base_rule_map.download` | `false` | 用户明确要求"允许下载/打印/副本" |
+| `record_operations` 中的 `delete` | 不包含 | 用户明确说"允许删除"或使用强语义("完全管理""可删改") |
+
+---
+
+### Editor / Reader 的权限上限规则
+1. 对 Editor 与 Reader,系统允许修改其权限配置,但同时施加以下封顶约束:
+2. Reader 的任一权限项 不允许超过「仅可阅读」
+3. Reader 不允许拥有任何可编辑、可新增、可删除相关权限; Editor 的权限可被修改,但其能力范围受高级权限能力封顶。
+
+### 权限对象选择
+
+**注意**:
+- 仅对用户明确指向的权限对象生成配置(明确提及的表名、仪表盘名,或可解析为唯一对象的指代如"当前表""这张表")
+- **严禁**基于业务常识、岗位职责、名称相似性或其他角色的历史配置推断或扩展权限对象
+- 用户未明确提及的对象不生成任何权限配置,视为 `no_perm`
+
+---
+
+### 记录操作默认策略
+
+**注意**:
+- 用户未提及时,默认包含 `add`,默认不包含 `delete`
+- 阅读范围默认对齐编辑范围:用户仅描述可编辑范围、未说明阅读范围时,可阅读范围与可编辑范围保持一致,不主动扩大
+- 当可读范围与可编辑范围一致时,**不得**生成 `read_filter_rule_group`;应设置 `other_record_all_read = false` 且 `read_filter_rule_group = null`
+
+**⚠️ 记录操作限制**:
+1. `perm` 为 `read_only` 时,`record_rule.record_operations` **只能为空**
+2. 同步表(`is_sync = true`)**严禁**新增和删除记录
+
+---
+
+### field_perms 构造 SOP
+
+在生成 `field_perms` 时,**严禁**依赖模糊的"继承"概念,必须按以下步骤执行:
+
+| 步骤 | 操作 | 说明 |
+|------|------|------|
+| 1. 基准设定 | `perm = edit` → 全部字段预设 `"edit"`;`perm = read_only` → 全部预设 `"read"` | 基于 `base_table_info` 中的全量字段 |
+| 2. 物理降级 | Formula / Lookup / AutoNumber 及系统字段 → 强制降级为 `"read"` | 不可变字段严禁设为 `edit` |
+| 3. 用户覆盖 | 仅对用户**显式指定**了特定权限的字段应用 `no_perm` / `read` / `create` | 未显式指定的保持基准值 |
+| 4. 反筛选误判 | 用于 `filter_rules` 的字段,若基准为 `"edit"` 且用户未要求降级 → **保持 `"edit"`** | 筛选条件不影响字段可编辑性 |
+| 5. 筛选依赖兜底 | 出现在 `filter_rules` 中的字段**不允许**遗漏,权限至少为 `"read"` | 最终校验步骤 |
+
+**⚠️ field_perm_mode 选择规则**:
+1. 用户以"所有字段""全字段"等整体性表述描述且不要求选项增删改时,**必须**使用 `all_edit` / `all_read`,**严禁**变为逐字段 `specify`
+2. 仅在以下情况使用 `specify`:用户明确提出字段级差异需求、不同字段权限目标存在显著差异、或明确要求配置选项增删改权限
+3. 系统字段硬性约束导致的自动降级**不视为**差异,不触发 `specify`
+4. 对"仅""只能""部分"等约束定语,范围外的字段按定语的反方向设置
+
+**⚠️ 同步表限制**: `is_sync = true` 的表**严禁**设置字段为 `edit` 或 `create`
+
+---
+
+### 视图权限默认策略
+
+**判断流程(必须按顺序执行,命中即停)**:
+
+1. **先判断用户是否提及了具体视图名称**(如"看板视图可见""甘特图不可编辑"等)
+  - **是** → `all_visible = false`,`visible_views` 仅包含用户明确提及为"可见"的视图名称(非 viewID);未提及的视图视为不可见
+  - **否**(用户完全未提及任何视图)→ `all_visible = true`
+2. `allow_edit` 默认为 `false`,仅当用户明确要求"可编辑视图""可新增/删除视图""可管理视图"时才设为 `true`。设为 `true` 时仍**必须**包含 `visibility` 字段(参考视图权限 情况 A)
+3. `all_visible` 为 `false` 时,`visible_views` **不可为空**,必须至少包含一个视图
+
+**❌ 常见错误 — 缺少 `visibility` 字段:**
+```json
+// 错误!缺少 visibility
+{ "view_rule": { "allow_edit": false } }
+```
+**✅ 正确写法:**
+```json
+// 即使全部可见,也必须显式写出 visibility
+{ "view_rule": { "allow_edit": false, "visibility": { "all_visible": true } } }
+```
+
+---
+
+### 字段类型与筛选算子的强约束关系
+
+当字段被用于记录筛选条件时,其字段类型(FieldType)与可用算子(Operator)存在固定绑定关系:
+
+**User / CreatedUser 类型字段:**
+- 仅允许使用 `contains` 算子
+- 不允许使用 `is`、`isNot` 等精确匹配算子
+- 筛选条件中无需填写具体值(由系统自动匹配当前成员)
+
+**SingleSelect、Stage 类型字段:**
+- `is` 与 `isNot` 算子仅允许用于匹配**单一选项**,不得用于多个值
+- 当用户表达"字段值等于/不等于某一个具体选项"(如"出勤状态不等于出勤")时,Agent 必须使用 `is` / `isNot`,且 filter_values 仅包含单一值。
+- 当用户表达"字段值等于/不等于多个选项集合"(如"学历不是专科和其他")时,Agent 必须使用 `contains` / `doesNotContain`,并将多个选项填入 filter_values。
+- `contains` / `doesNotContain`中的filter_values可包含多个值,表示或关系
+
+**MultiSelect 类型字段:**
+- `is` / `isNot`:filter_values 允许填写多个选项
+  - 当 operator = is 且勾选 A、B 时,语义为该字段**同时包含** A 和 B(A&B),不是"等于 A 或等于 B"
+  - 当用户表达"包含任一选项"时,除了可以使用 contains 实现外,也可以使用 is 并且配套通过 filter_rules.conjunction = or 实现
+- `contains` / `doesNotContain`:用于表达"包含任一选项/不包含任一选项",filter_values 可填写多个选项(系统按"任一匹配"处理);若要表达"等于 A 或等于 B",应拆成多条筛选条件并用「或」组合。
+
+**百分比字段**
+- 对于 query 中“数字”的筛选条件时,如果涉及到百分比,要原封不动地还原用户给你的数值(百分比都变成小数)。比如“大于 20%”则变成“大于 0.2”、“xx 率小于 60”则变成“小于 0.6”。
+
+### 被用于筛选的字段的 field_perms 权限强制要求
+
+当某字段(系统字段没有此要求)被用于「满足特定条件的记录」中的筛选条件时,系统将根据当前数据表权限与记录权限,自动施加以下**不可变约束**:
+
+**筛选字段的读写一致性:**
+- 若表权限为 edit,且字段类型属于【可编辑字段】,则筛选字段必须保持 edit 权限,除非用户显式要求降级。
+- 严禁因为字段被用作筛选条件而将其降级为 read。筛选条件仅要求字段可见,不要求字段只读。
+
+**新增记录时的字段最低权限:**
+- 当且仅当记录权限包含「可新增记录」时,字段至少为可新增(create),用于保证在新增记录时筛选条件字段可被正确写入。
+- 若当前记录权限为「仅可阅读」,则不触发该约束。
+
+**字段是否可编辑(edit)不作强制要求**,由具体权限方案决定,不属于 infra 强制约束范围。
+
+上述由系统自动施加的字段权限,不可被手动取消或降级。

+ 143 - 0
.agents/skills/lark-calendar/SKILL.md

@@ -0,0 +1,143 @@
+---
+name: lark-calendar
+version: 1.0.0
+description: "飞书日历(calendar):提供日历与日程(会议)的全面管理能力。核心场景包括:查看/搜索日程、创建/更新日程、管理参会人、查询忙闲状态及推荐空闲时段、查询/搜索与预定会议室。注意:涉及【预约日程/会议】或【查询/预定会议室】时,必须先读取 references/lark-calendar-schedule-meeting.md 工作流!高频操作请优先使用 Shortcuts:+agenda(快速概览今日/近期行程)、+create(创建日程并按需邀请参会人及预定会议室)、+freebusy(查询用户主日历的忙闲信息和rsvp的状态)、+rsvp(回复日程邀请)"
+metadata:
+  requires:
+    bins: ["lark-cli"]
+  cliHelp: "lark-cli calendar --help"
+---
+
+# calendar (v4)
+
+**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),其中包含认证、权限处理**
+**CRITICAL — 所有的 Shortcuts 在执行之前,务必先使用 Read 工具读取其对应的说明文档,禁止直接盲目调用命令。**
+**CRITICAL — 凡涉及【预约日程/会议】或【查询/搜索会议室】,第一步 MUST 强制使用 Read 工具读取 [`references/lark-calendar-schedule-meeting.md`](references/lark-calendar-schedule-meeting.md)。禁止跳过此步直接调用 API 或 Shortcut!**
+**CRITICAL — 术语约束:用户日常表达中常说的“帮我约个日历”、“查一下今天的日历”等,其实际意图通常是针对 日程(Event) 的创建或查询,而非操作 日历(Calendar) 容器本身。请自动将口语化的“日历”意图映射为“日程”操作(如 `+create`, `+agenda`)。**
+**CRITICAL — 会议与日程的意图路由:**
+- **查询过去时间的会议**:如果用户明确查询过去时间的会议(如“昨天的会议”、“上周的会议”),**优先使用 [`../lark-vc/SKILL.md`](../lark-vc/SKILL.md) 搜索会议记录**。因为会议数据不仅包含从日程发起的视频会议,还包含即时会议,仅查询日程数据会导致结果不全。
+- **查询日历/日程或未来时间的会议**:如果用户明确表达的是“日历”、“日程”,或者涉及**未来时间**的安排,则属于本技能(lark-calendar)的业务域,请继续使用本技能处理。
+
+
+**时间与日期推断规范:**
+为确保准确性,在涉及时间推断时,请严格遵循以下规则:
+- **星期的定义**:周一是一周的第一天,周日是一周的最后一天。计算`下周一`等相对日期时,务必基于当前真实日期和星期基准进行推算,避免算错日期。
+- **一天的范围**:当用户提到`明天`、`今天`等泛指某一天时,时间范围应默认覆盖整天时间范围。**切勿**自行缩减查询范围,以免遗漏晚上的时间安排。
+- **历史时间约束**:不能预约已经完全过去的时间。唯一的例外情况是“跨越当前时间”的日程,即日程的开始时间在过去,但结束时间在未来。
+
+## 核心场景
+
+### 1. 预约日程/会议、查询/搜索可用会议室
+**BLOCKING REQUIREMENT (阻塞性要求): 只要用户的意图包含“预约日程/会议”或“查询/搜索可用会议室”,你必须立即停止其他思考,优先使用 Read 工具完整读取 [`references/lark-calendar-schedule-meeting.md`](references/lark-calendar-schedule-meeting.md)!未读取该文件前,绝对禁止执行任何日程创建或会议室查询操作。**
+**CRITICAL: 必须严格按照上述文档中定义的工作流(Workflow)执行后续操作。处理该场景时,默认做“智能助理”,不要做“表单填写机”。能补全的默认值先补全,只有在时间冲突、结果无法唯一确定、时间语义存在歧义时才主动追问。**
+**CRITICAL: 执行顺序必须固定为:先补默认值,再判断时间是否明确,再进入“明确时间”或“模糊时间/无时间信息”分支。不要跳步。**
+**CRITICAL: 明确时间且需要会议室时,先 `+room-find`,再 `+freebusy`;模糊时间或无时间信息时,先 `+suggestion`,如需会议室再批量 `+room-find`。**
+**CRITICAL: 当用户说“查会议室”“找会议室”“搜可用会议室”或“推荐常用会议室”时,默认是查会议室可用性,不是查会议室资源名录,更严禁拉取历史日程做统计分析。完整规则以 [lark-calendar-schedule-meeting.md](references/lark-calendar-schedule-meeting.md) 为准。**
+**BLOCKING REQUIREMENT: 即使用户的核心诉求是“查会议室”,只要【没有提供明确的起止时间】,绝对禁止直接调用 `+room-find`!必须先进入【无时间/模糊时间】分支,调用 `+suggestion` 拿到候选时间块后,再将时间块传给 `+room-find`。**
+**BLOCKING REQUIREMENT: 只要面临时间方案或会议室方案的选择(如模糊时间、无时间或需要会议室),在调用 `+create` 创建日程之前,必须先向用户展示候选方案并等待用户明确确认。绝对禁止擅自替用户做决定。**
+
+## 核心概念
+
+- **日历(Calendar)**:日程的容器。每个用户有一个主日历(primary calendar),也可以创建或订阅共享日历。
+- **日程(Event)**:日历中的单个日程,包含起止时间、地点、标题、参与人等属性。支持单次日程和重复日程,遵循RFC5545 iCalendar国际标准。
+- ***全天日程(All-day Event)***: 只按日期占用、没有具体起止时刻的日程,结束日期是包含在日程时间内的。
+- **日程实例(Instance)**:日程的具体时间实例,本质是对日程的展开。普通日程和例外日程对应1个Instance,重复性日程对应N个Instance。在按时间段查询时,可通过实例视图将重复日程展开为独立的实例返回,以便在时间线上准确展示和管理。
+- **重复规则(Rrule/Recurrence Rule)**:定义重复性日程的重复规则,比如`FREQ=DAILY;UNTIL=20230307T155959Z;INTERVAL=14`表示每14天重复一次。
+- **例外日程(Exception)**:重复性日程中与原重复性日程不一致的日程。
+- **参会人(Attendee)**:日程的参与者,可以是用户、群、会议室资源、外部邮箱地址等。每个参与人有独立的RSVP状态。
+- **响应状态(RSVP)**:参与人对日程邀请的回复状态(接受/拒绝/待定)。
+- **忙闲时间(FreeBusy)**:查询用户在指定时间段的忙闲状态,用于会议时间协调。
+- **会议室(Room)**:“room”不是“房间”,是“会议室”。请在理解和处理意图时将“room”和“房间”准确映射为“会议室”及其相关操作。
+- **时间块(Time Slot / Time Block)**:指一个**具体且确定**的连续时间段(如 `14:00~15:00`)。在文档中,它与泛指的“时间范围/区间”(如“今天下午”、“下周”)有严格区别。在调用预定、查询可用会议室等确切操作时,必须基于确定的“时间块”而非模糊的“时间范围”。
+
+## 资源关系
+
+```
+Calendar (日历)
+└── Event (日程)
+    ├── Attendee (参会人)
+    └── Reminder (提醒)
+```
+
+## Shortcuts(推荐优先使用)
+
+Shortcut 是对常用操作的高级封装(`lark-cli calendar +<verb> [flags]`)。有 Shortcut 的操作优先使用。
+
+| Shortcut | 说明 |
+|----------|------|
+| [`+agenda`](references/lark-calendar-agenda.md) | 查看日程安排(默认今天) |
+| [`+create`](references/lark-calendar-create.md) | 创建日程并邀请参会人(ISO 8601 时间) |
+| [`+freebusy`](references/lark-calendar-freebusy.md) | 查询用户主日历的忙闲信息和rsvp的状态 |
+| [`+room-find`](references/lark-calendar-room-find.md) | 针对一个或多个**明确的**时间块查找可用会议室(**无明确时间时禁止直接调用,需先走 +suggestion**) |
+| [`+rsvp`](references/lark-calendar-rsvp.md) | 回复日程(接受/拒绝/待定) |
+| [`+suggestion`](references/lark-calendar-suggestion.md) | 根据非明确时间或一段时间范围,推荐多个可用时间块方案 |
+
+## 会议室相关规则
+
+- **会议室是日程的一种参与人(resource attendee),不能脱离日程单独存在或单独预定。**
+- **凡是用户意图是“预定/查询/搜索可用会议室”时,都必须进入 `references/lark-calendar-schedule-meeting.md` 工作流处理。**
+- `+room-find` 的时间输入必须是**确定时间块**,不能是时间区间搜索。
+- **强制约束:如果用户仅要求“查询会议室”但未提供明确时间,必须先调用 `+suggestion` 获取可用时间块,然后再将时间块交给 `+room-find` 批量查询。严禁直接猜测时间并盲目调用 `+room-find`。**
+
+## API Resources
+
+```bash
+lark-cli schema calendar.<resource>.<method>   # 调用 API 前必须先查看参数结构
+lark-cli calendar <resource> <method> [flags] # 调用 API
+```
+
+> **重要**:使用原生 API 时,必须先运行 `schema` 查看 `--data` / `--params` 参数结构,不要猜测字段格式。
+
+### calendars
+
+  - `create` — 创建共享日历
+  - `delete` — 删除共享日历
+  - `get` — 查询日历信息
+  - `list` — 查询日历列表
+  - `patch` — 更新日历信息
+  - `primary` — 查询用户主日历
+  - `search` — 搜索日历
+
+### event.attendees
+
+  - `batch_delete` — 删除日程参与人
+  - `create` — 添加日程参与人
+  - `list` — 获取日程参与人列表
+
+### events
+
+  - `create` — 创建日程
+  - `delete` — 删除日程
+  - `get` — 获取日程
+  - `instance_view` — 查询日程视图
+  - `patch` — 更新日程
+  - `search` — 搜索日程
+
+### freebusys
+
+  - `list` — 查询主日历日程忙闲信息
+
+## 权限表
+
+| 方法 | 所需 scope |
+|------|-----------|
+| `calendars.create` | `calendar:calendar:create` |
+| `calendars.delete` | `calendar:calendar:delete` |
+| `calendars.get` | `calendar:calendar:read` |
+| `calendars.list` | `calendar:calendar:read` |
+| `calendars.patch` | `calendar:calendar:update` |
+| `calendars.primary` | `calendar:calendar:read` |
+| `calendars.search` | `calendar:calendar:read` |
+| `event.attendees.batch_delete` | `calendar:calendar.event:update` |
+| `event.attendees.create` | `calendar:calendar.event:update` |
+| `event.attendees.list` | `calendar:calendar.event:read` |
+| `events.create` | `calendar:calendar.event:create` |
+| `events.delete` | `calendar:calendar.event:delete` |
+| `events.get` | `calendar:calendar.event:read` |
+| `events.instance_view` | `calendar:calendar.event:read` |
+| `events.patch` | `calendar:calendar.event:update` |
+| `events.search` | `calendar:calendar.event:read` |
+| `freebusys.list` | `calendar:calendar.free_busy:read` |
+
+**注意(强制性):**
+- 涉及日期(时间)字符串与时间戳的相互转换时,务必调用系统命令或脚本代码等外部工具进行处理,以确保转换的绝对准确。违者将导致严重的逻辑错误!

+ 78 - 0
.agents/skills/lark-calendar/references/lark-calendar-agenda.md

@@ -0,0 +1,78 @@
+
+# calendar +agenda
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+查看近期日程安排。只读操作,不修改任何日程。
+
+需要的scopes: ["calendar:calendar.event:read"]
+
+## 命令
+
+```bash
+# 查看今天日程(默认)
+lark-cli calendar +agenda
+
+# 自定义时间范围(ISO 8601)
+lark-cli calendar +agenda --start "2026-03-10T00:00+08:00" --end "2026-03-17T00:00+08:00"
+
+# 自定义时间范围(仅日期)
+lark-cli calendar +agenda --start 2026-03-10 --end 2026-03-17
+
+# 人类可读格式输出
+lark-cli calendar +agenda --format pretty
+
+# 指定日历
+lark-cli calendar +agenda --calendar-id cal_xxx
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--start <time>` | 否 | 开始时间(ISO 8601 或仅日期,默认当天) |
+| `--end <time>` | 否 | 结束时间(默认与 `--start` 属于同一天,自动取当天结束时间) |
+| `--calendar-id <id>` | 否 | 日历 ID(省略则使用主日历) |
+| `--format` | 否 | 输出格式:json(默认) \| pretty |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 时间格式
+
+`--start` 和 `--end` 支持以下格式:
+
+| 格式 | 示例 | 说明 |
+|------|------|------|
+| ISO 8601 | `2026-03-10T14:00:00+08:00` | 完整格式 |
+| 日期+时间 | `2026-03-10 14:00:00` | 自动补全时区 |
+| 仅日期 | `2026-03-10` | start 取 00:00:00,end 取 23:59:59 |
+| Unix 时间戳 | `1741564800` | 秒级时间戳 |
+
+## 输出格式
+
+**将结果整理为易读的日程表:**
+
+```
+## 2026-03-10 周一
+
+09:00 - 09:30  站会
+10:00 - 11:00  产品评审
+14:00 - 15:00  与 Alice 1:1
+
+## 2026-03-11 周二
+
+(无日程)
+```
+
+**注意:按日期分组,并严格按照开始时间升序(从早到晚的时间线)排序输出。** 显示标题、时长
+
+## 提示
+
+- 已取消的日程会自动过滤,无需额外处理。
+- 如无日程,告知用户"日程清空"。
+- 大于 40 天的时间范围会自动拆分查询并合并结果。
+- 查看多个日历:先用 `lark-cli calendar calendars list --page-all` 列出日历列表,再逐个查询。
+
+## 参考
+
+- [lark-calendar](../SKILL.md) -- 日历全部命令
+- [lark-shared](../../lark-shared/SKILL.md) -- 认证和全局参数

+ 109 - 0
.agents/skills/lark-calendar/references/lark-calendar-create.md

@@ -0,0 +1,109 @@
+
+# calendar +create
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
+
+创建日程并按需邀请参会人。
+
+需要的scopes: ["calendar:calendar.event:create","calendar:calendar.event:update"]
+
+## 推荐命令
+
+```bash
+# 创建日程 + 邀请参会人(ISO 8601 时间)
+lark-cli calendar +create \
+  --summary "产品评审" \
+  --start "2026-03-12T14:00+08:00" \
+  --end "2026-03-12T15:00+08:00" \
+  --attendee-ids ou_aaa,ou_bbb
+
+# 无参会人
+lark-cli calendar +create \
+  --summary "午餐" \
+  --start "2026-03-12T12:00+08:00" \
+  --end "2026-03-12T13:00+08:00"
+
+# 指定日历
+lark-cli calendar +create --summary "..." --start "..." --end "..." \
+  --calendar-id cal_xxx
+```
+
+参数:
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--summary <text>` | 否 | 日程标题。注意:标题中不应该出现时间、地点、人物信息 |
+| `--start <time>` | 是 | 开始时间(ISO 8601,如 `2026-03-12T14:00+08:00`) |
+| `--end <time>` | 是 | 结束时间(ISO 8601) |
+| `--description <text>` | 否 | 日程详细描述。提供会议议程、活动内容、注意事项或链接等。与 summary 配合使用,仅关注当前日程信息 |
+| `--attendee-ids <id_list>` | 否 | 参与人 ID 列表(逗号分隔)。支持用户(`ou_`)、群组(`oc_`)和会议室(`omm_`)。AI 提取时请务必保留对应前缀 |
+| `--calendar-id <id>` | 否 | 日历 ID(省略则使用主日历) |
+| `--rrule <rrule>` | 否 | 重复日程的重复性规则,规则设置方式参考rfc5545。**【⚠️注意:系统绝对不支持 COUNT,如需限制重复次数,必须转为 UNTIL】**。示例值:"FREQ=DAILY;INTERVAL=1" |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+> **⚠️ `rrule` 规则限制:飞书日历系统不支持 `COUNT` 参数。遇到限制重复次数的需求,必须根据开始时间和频率自行推算并转换成 `UNTIL=<具体日期>` 格式。**
+> 自动设置 `attendee_ability: "can_modify_event"`,参会人可查看彼此并编辑日程。
+> 自动设置 `free_busy_status: "busy"`,默认日程忙闲状态为忙碌。
+> 自动设置 `reminders: [{"minutes": 5}]`,默认日程开始前 5 分钟提醒。
+> 自动设置 `vchat: {"vc_type": "vc"}`,默认日程包含飞书视频会议。如需其他视频会议类型或不含视频会议,请使用完整 API 命令。
+> 失败保护:若添加参会人失败(如 open_id 错误),CLI 会自动删除刚创建的空日程(回滚,不通知参会人)。
+
+## 高级用法(完整 API 命令)
+
+如需配置 `location`(地理位置,不含会议室位置)、`visibility`(日程公开范围)、自定义 `reminders`(提醒设置)、自定义 `attendee_ability`(参与人权限)、自定义 `free_busy_status`(日程忙闲状态)、参与人可选参加状态或全天日程等高级参数,请使用完整的 API 命令:
+**注意**:
+- 全天日程的开始日期和结束日期必须分别是日程开始的第一天和结束的最后一天。如果只有一天的话,开始日期和结束日期是相同。
+
+```bash
+# 第一步:创建日程(含高级参数)
+## 查看完整参数定义
+lark-cli schema calendar.events.create
+## 创建日程
+lark-cli calendar events create --calendar-id primary --data '{
+  "summary": "产品评审",
+  "description": "本周分享主题:CLI 架构设计",
+  "start_time": { "timestamp": "1741586400" },
+  "end_time": { "timestamp": "1741593600" },
+  "location": { "name": "5F-大会议室" },
+  "attendee_ability": "can_modify_event",
+  "reminders": [{ "minutes": 15 }]
+}'
+
+# 第二步:添加参会人(使用第一步返回的 calendar_id 和 event_id)
+## 查看完整参数定义
+lark-cli schema calendar.event.attendees.create
+## 添加参会人
+lark-cli calendar event.attendees create \
+  --calendar-id <CALENDAR_ID> --event-id <EVENT_ID> \
+  --data '{"attendees": [{"type": "user", "user_id": "ou_xxx"}]}'
+
+# 可选第三步(推荐):若第二步失败,回滚删除空日程
+## 查看完整参数定义
+lark-cli schema calendar.events.delete
+## 删除空日程
+lark-cli calendar events delete \
+  --calendar-id <CALENDAR_ID> --event-id <EVENT_ID> \
+  --params '{"need_notification":false}'
+
+```
+
+> 完整 API 命令的时间参数是 **Unix 秒字符串**(非 ISO 8601)。
+> 当你手动拆成两步执行时,建议保留“失败后回滚删除”的第三步,避免遗留空日程。
+
+## 参会人类型
+
+| `type` | `user_id` 格式 | 说明 |
+|--------|---------------|------|
+| `user` | `ou_xxx`(open_id) | 飞书用户 |
+| `group` | `oc_xxx` | 飞书群组 |
+| `resource` | `omm_xxx` | 会议室 |
+| `third_party` | 邮箱地址 | 外部参会人 |
+
+> [!CAUTION]
+> 这是**写入操作** -- 执行前必须确认用户意图。
+
+## 参考
+
+- [lark-calendar](../SKILL.md) -- 日历全部命令
+- [lark-shared](../../lark-shared/SKILL.md) -- 认证和全局参数
+- [lark-calendar-suggestion](lark-calendar-suggestion.md) -- 根据非明确时间或一段时间范围,推荐多个可用时间块方案

+ 124 - 0
.agents/skills/lark-calendar/references/lark-calendar-freebusy.md

@@ -0,0 +1,124 @@
+
+# calendar +freebusy
+
+> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md)。
+
+查询用户主日历的忙闲信息,返回指定时间范围内的忙碌时段列表和rsvp的状态。
+
+需要的scopes: ["calendar:calendar.free_busy:read"]
+
+## 命令
+
+```bash
+# 查询当前用户今天的忙闲(默认)
+lark-cli calendar +freebusy
+
+# 自定义时间范围(仅日期)
+lark-cli calendar +freebusy --start 2026-03-11 --end 2026-03-12
+
+# 自定义时间范围(完整 ISO 8601)
+lark-cli calendar +freebusy --start "2026-03-11T08:00:00+08:00" --end "2026-03-11T18:00:00+08:00"
+
+# 查询指定用户的忙闲信息
+lark-cli calendar +freebusy --start 2026-03-11 --end 2026-03-12 --user-id ou_xxx
+
+# 人类可读格式输出
+lark-cli calendar +freebusy --format pretty
+```
+
+## 参数
+
+| 参数 | 必填 | 说明 |
+|------|------|------|
+| `--start <time>` | 否 | 查询开始时间(ISO 8601 或仅日期,默认当天) |
+| `--end <time>` | 否 | 查询结束时间(默认与 `--start` 属于同一天,自动取当天结束时间) |
+| `--user-id <open_id>` | 否 | 目标查询用户 ID(`ou_` 前缀)。省略时默认查询当前登录用户,bot 身份调用时必须明确指定 |
+| `--format` | 否 | 输出格式:json(默认) \| pretty |
+| `--dry-run` | 否 | 预览 API 调用,不执行 |
+
+## 时间格式
+
+`--start` 和 `--end` 支持以下格式:
+
+| 格式 | 示例 | 说明 |
+|------|------|------|
+| ISO 8601 | `2026-03-11T09:00:00+08:00` | 完整格式 |
+| 日期+时间 | `2026-03-11 09:00:00` | 自动补全时区 |
+| 仅日期 | `2026-03-11` | start 取 00:00:00,end 取 23:59:59 |
+| Unix 时间戳 | `1741564800` | 秒级时间戳 |
+
+## 输出示例
+
+### 表格格式
+
+```
+start             end               rsvp_status
+----------------  ----------------  -----------
+2026-03-11 10:00  2026-03-11 10:30  接受
+2026-03-11 14:00  2026-03-11 15:00  待定
+
+共 2 个忙碌时段
+```
+
+### JSON 格式
+
+```json
+[
+  {
+    "start_time": "2026-03-11T10:00:00+08:00",
+    "end_time": "2026-03-11T10:30:00+08:00",
+    "rsvp_status": "accept"
+  },
+  {
+    "start_time": "2026-03-11T14:00:00+08:00",
+    "end_time": "2026-03-11T15:00:00+08:00",
+    "rsvp_status": "tentative"
+  }
+]
+```
+
+## 典型场景
+
+### 1. 查找日程会议空闲时段
+
+```bash
+# 查询今天的忙碌时段
+lark-cli calendar +freebusy
+
+# 查询工作时间段
+lark-cli calendar +freebusy \
+  --start "2026-03-11T08:00:00+08:00" \
+  --end "2026-03-11T18:00:00+08:00"
+```
+
+### 2. 检查团队成员可用性
+
+```bash
+# 查询多个成员,对比找出共同空闲时间
+lark-cli calendar +freebusy --start 2026-03-12 --user-id ou_member_a
+lark-cli calendar +freebusy --start 2026-03-12 --user-id ou_member_b
+```
+
+## 注意事项
+
+1. **只查询主日历** — 此命令只返回用户主日历的忙闲信息,不包括其他订阅日历
+2. **隐私保护** — 只返回忙碌时段的起止时间,不包含日程标题、描述等详细信息
+3. **bot 身份** — bot 必须通过 `--user-id` 指定要查询的用户
+
+## 与其他命令对比
+
+| 命令 | 用途 | 输出内容 |
+|------|------|----------|
+| `calendar +freebusy` | 查询忙闲时段 | 只返回忙碌时段列表(无日程详情) |
+| `calendar +agenda` | 查看日程安排 | 返回完整日程列表(含标题、描述等) |
+
+**选择建议**:
+- **仅需了解是否有空** → 使用 `+freebusy`(更快,隐私保护)
+- **需要查看日程详情** → 使用 `+agenda`
+
+## 参考
+
+- [lark-calendar-agenda](lark-calendar-agenda.md) — 查看日程安排
+- [lark-calendar-create](lark-calendar-create.md) — 创建日程
+- [lark-calendar-suggestion](lark-calendar-suggestion.md) — 根据非明确时间或一段时间范围,推荐多个可用时间块方案
+- [lark-calendar](../SKILL.md) — 日历完整 API

Some files were not shown because too many files changed in this diff