@amaster.ai/pi-lark 0.1.2-beta.42 → 0.1.2-beta.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package.json +3 -3
  2. package/skills/lark-approval/references/lark-approval-initiate.md +2 -5
  3. package/skills/lark-approval/references/lark-approval-instances-initiated.md +6 -0
  4. package/skills/lark-approval/references/lark-approval-tasks-query.md +9 -0
  5. package/skills/lark-approval/references/lark-approval-tasks-rollback.md +8 -2
  6. package/skills/lark-apps/SKILL.md +16 -10
  7. package/skills/lark-apps/references/lark-apps-access-scope-set.md +1 -1
  8. package/skills/lark-apps/references/lark-apps-db-execute.md +185 -1
  9. package/skills/lark-apps/references/lark-apps-db.md +1 -1
  10. package/skills/lark-apps/references/lark-apps-role.md +133 -0
  11. package/skills/lark-base/SKILL.md +6 -2
  12. package/skills/lark-base/references/dashboard-block-data-config.md +28 -2
  13. package/skills/lark-base/references/lark-base-cell-value.md +9 -4
  14. package/skills/lark-base/references/lark-base-dashboard.md +11 -2
  15. package/skills/lark-base/references/lark-base-data-query.md +9 -7
  16. package/skills/lark-base/references/lark-base-field-create.md +4 -2
  17. package/skills/lark-base/references/lark-base-field-json.md +52 -15
  18. package/skills/lark-base/references/lark-base-field-update.md +4 -2
  19. package/skills/lark-base/references/lark-base-view-set-filter.md +3 -1
  20. package/skills/lark-drive/SKILL.md +4 -2
  21. package/skills/lark-drive/references/lark-drive-delete.md +23 -11
  22. package/skills/lark-drive/references/lark-drive-move.md +5 -3
  23. package/skills/lark-drive/references/lark-drive-task-result.md +58 -5
  24. package/skills/lark-event/SKILL.md +2 -1
  25. package/skills/lark-event/references/lark-event-approval.md +170 -0
  26. package/skills/lark-slides/references/slides_xml_schema_definition.xml +7 -2
  27. package/skills/lark-slides/references/xml-format-guide.md +15 -0
  28. package/skills/lark-slides/scripts/xml_text_overlap_lint.py +264 -6
  29. package/skills/lark-slides/scripts/xml_text_overlap_lint_test.py +348 -6
  30. package/skills/lark-vc/SKILL.md +6 -3
  31. package/skills/lark-vc/references/vc-domain-boundaries.md +9 -1
  32. package/skills/lark-vc-agent/SKILL.md +1 -1
  33. package/skills/lark-wiki/SKILL.md +4 -2
  34. package/skills/lark-wiki/references/lark-wiki-move-to-drive.md +122 -0
  35. package/skills/lark-wiki/references/lark-wiki-move.md +5 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/pi-lark",
3
- "version": "0.1.2-beta.42",
3
+ "version": "0.1.2-beta.44",
4
4
  "description": "Pi extension for Lark/Feishu workspace — calendar, docs, drive, sheets, tasks, mail and more via lark-cli.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -56,12 +56,12 @@
56
56
  }
57
57
  },
58
58
  "devDependencies": {
59
- "@earendil-works/pi-coding-agent": "0.80.3",
59
+ "@earendil-works/pi-coding-agent": "0.80.10",
60
60
  "typebox": "*",
61
61
  "vitest": "^4.0.0"
62
62
  },
63
63
  "dependencies": {
64
- "@amaster.ai/pi-shared": "0.1.2-beta.42"
64
+ "@amaster.ai/pi-shared": "0.1.2-beta.44"
65
65
  },
66
66
  "scripts": {
67
67
  "fetch-skills": "node scripts/fetch-skills.mjs",
@@ -69,19 +69,17 @@ lark-cli approval approvals get \
69
69
  |---|---|---|
70
70
  | `--data '{...}'` | 是 | 请求体,使用 JSON 传入 |
71
71
  | `approval_code` | 是 | 审批定义 Code;必须先通过 `approvals search` / `approvals get` 确认 |
72
- | `form` | 是 | 表单值,**JSON 数组字符串**,不是普通对象 |
72
+ | `form` | 否 | 表单值,**JSON 数组字符串**,不是普通对象;API 层非必填,但审批定义存在必填控件或用户需要提交表单值时必须传 |
73
73
  | `node_approver_list` | 否 | 节点审批人列表;仅在定义要求补充审批人时传 |
74
74
  | `node_cc_list` | 否 | 节点抄送人列表;仅在用户明确需要补充节点抄送人时传 |
75
75
  | `uuid` | 否 | 幂等标识;重复重试同一请求时建议显式传入 |
76
- | `--params '{...}'` | 否 | 查询参数,使用 JSON 传入 |
77
- | `user_id_type` | 否 | 用户 ID 类型:`user_id`、`union_id`、`open_id`;涉及人员类 ID 时建议显式传 `open_id` |
78
76
  | `--as user` | 否 | 建议显式指定用户身份;审批发起通常应使用用户身份 |
79
77
  | `--yes` | 是 | 写操作确认;真实执行时必须显式传入 |
80
78
  | `--dry-run` | 否 | 预览 API 调用,不执行 |
81
79
 
82
80
  ### 4. 组装 `form`
83
81
 
84
- `instances create --data.form` 是一个 JSON 数组字符串。组装原则:
82
+ `instances create --data.form` 是可选字段;传入时必须是一个 JSON 数组字符串。无表单或无需填写表单值的审批可省略 `form`,但只要审批定义包含需要提交的控件,就必须按控件结构组装后传入。组装原则:
85
83
 
86
84
  - 先用 `approvals.get.form` 识别有哪些控件、每个控件的 `id` / `type` / 可选值范围,再按本文中的创建参数规则与 [`lark-approval-instance-form-control-parameters.md`](./lark-approval-instance-form-control-parameters.md) 重新组装创建 payload。
87
85
  - 提交时必须至少保证每个控件的 `id`、`type` 与 `value` 符合当前接口要求;不要假设定义快照里出现的其他字段都能直接照搬。
@@ -173,7 +171,6 @@ lark-cli approval instances create \
173
171
  }
174
172
  ]
175
173
  }' \
176
- --params '{"user_id_type":"open_id"}' \
177
174
  --as user \
178
175
  --yes
179
176
  ```
@@ -14,6 +14,9 @@ lark-cli approval instances initiated --params '{"page_size":20}' --as user
14
14
  # 只看某个审批定义下我发起的实例
15
15
  lark-cli approval instances initiated --params '{"definition_code":"<DEFINITION_CODE>","page_size":20}' --as user
16
16
 
17
+ # 按发起时间范围筛选(秒级时间戳)
18
+ lark-cli approval instances initiated --params '{"start_timestamp":"<START_SECONDS>","end_timestamp":"<END_SECONDS>","page_size":20}' --as user
19
+
17
20
  # 使用 page_token 翻页
18
21
  lark-cli approval instances initiated --params '{"page_size":20,"page_token":"example_page_token"}' --as user
19
22
 
@@ -30,6 +33,8 @@ lark-cli approval instances initiated --params '{"page_size":20}' --as user --dr
30
33
  |------|------|------|
31
34
  | `--params '{...}'` | 否 | 查询参数,使用 JSON 传入;不传时使用默认分页与筛选 |
32
35
  | `definition_code` | 否 | 审批定义 Code,用于只查看某个审批定义下我发起的实例 |
36
+ | `start_timestamp` | 否 | 按发起时间筛选,时间范围开始值,秒级时间戳 |
37
+ | `end_timestamp` | 否 | 按发起时间筛选,时间范围结束值,秒级时间戳 |
33
38
  | `locale` | 否 | 返回语言:`zh-CN`、`en-US`、`ja-JP` |
34
39
  | `page_size` | 否 | 分页大小 |
35
40
  | `page_token` | 否 | 翻页标记;首次请求不填,后续使用上一次返回的 `page_token` |
@@ -101,6 +106,7 @@ lark-cli approval instances initiated \
101
106
 
102
107
  - **这是定位“我发起的审批实例”的首选命令**:如果你的目标是撤回、抄送、查看某个已发起审批,优先从这里拿 `instance_code`。
103
108
  - **优先用 `definition_code` 缩小范围**:当你已知审批定义时,先筛掉无关实例,可显著提升可读性。
109
+ - **按时间排查时使用 `start_timestamp` / `end_timestamp`**:这两个值都是秒级时间戳,用于按发起时间缩小结果范围。
104
110
  - **结果很多时优先 `--format table`**:适合人工快速浏览。
105
111
  - **`count` 只在第一页返回**:做分页处理时不要假设后续页还会带总数。
106
112
  - **`instance_status` 可直接判断下一步**:例如状态为 `1` 时通常可继续查看详情或考虑撤回,状态为 `4` 表示已经撤销,无需重复撤回。
@@ -14,6 +14,9 @@ lark-cli approval tasks query --params '{"topic":"1"}' --as user
14
14
  # 查询已办审批
15
15
  lark-cli approval tasks query --params '{"topic":"2"}' --as user
16
16
 
17
+ # 按任务时间范围筛选(秒级时间戳)
18
+ lark-cli approval tasks query --params '{"topic":"1","start_timestamp":"<START_SECONDS>","end_timestamp":"<END_SECONDS>"}' --as user
19
+
17
20
  # 使用 page_token 翻页
18
21
  lark-cli approval tasks query --params '{"topic":"1","page_token":"example_page_token"}' --as user
19
22
 
@@ -28,6 +31,8 @@ lark-cli approval tasks query --params '{"topic":"1"}' --format table --as user
28
31
  | `--params '{"topic":"..."}'` | 是 | 查询参数,使用 JSON 传入 |
29
32
  | `topic` | 是 | 任务分组主题,见下方“topic 枚举” |
30
33
  | `definition_code` | 否 | 审批定义 Code,用于仅查询某个审批定义下的任务 |
34
+ | `start_timestamp` | 否 | 按任务时间筛选,时间范围开始值,秒级时间戳 |
35
+ | `end_timestamp` | 否 | 按任务时间筛选,时间范围结束值,秒级时间戳 |
31
36
  | `locale` | 否 | 返回语言:`zh-CN`、`en-US`、`ja-JP` |
32
37
  | `page_size` | 否 | 分页大小 |
33
38
  | `page_token` | 否 | 翻页标记;首次请求不填,后续使用上一次返回的 `page_token` |
@@ -67,10 +72,14 @@ lark-cli approval tasks query --params '{"topic":"1"}' --format table --as user
67
72
  | `tasks[].summaries` | 表单摘要字段列表 |
68
73
  | `tasks[].support_api_operate` | 是否支持通过 API 同意或拒绝该任务 |
69
74
  | `tasks[].user_id` | 任务所属用户 ID |
75
+ | `tasks[].instance_external_id` | 三方审批实例 ID,仅第三方审批实例存在 |
76
+ | `tasks[].task_external_id` | 三方审批任务 ID,仅第三方审批任务存在 |
77
+ | `tasks[].link` | 三方审批跳转链接 |
70
78
 
71
79
  ## 使用建议
72
80
 
73
81
  - 常见处理链:先用 `tasks query` 拿到 `task_id` 和 `instance_code`,若用户需要查看详情、当前节点、表单内容、流程进度等内容,则调用 `instances get` 查看详情,最后执行 `tasks approve` / `tasks reject` / `tasks transfer` / `tasks add_sign` / `tasks rollback`。
74
82
  - 如果你只想看“已发起的审批实例”,使用 `instances initiated`;`tasks query` 更适合围绕“任务分组”来拉取列表。
83
+ - 按时间排查任务时使用 `start_timestamp` / `end_timestamp` 缩小范围;这两个值都是秒级时间戳。
75
84
  - 需要继续翻页时,直接把上一次返回的 `page_token` 放回 `--params`。
76
85
  - 当结果量较大时,优先使用 `--format table` 提升可读性。
@@ -23,6 +23,12 @@ lark-cli approval tasks rollback \
23
23
  --as user \
24
24
  --yes
25
25
 
26
+ # 退回到发起节点(发起节点 ID 为 START)
27
+ lark-cli approval tasks rollback \
28
+ --data '{"instance_code":"<INSTANCE_CODE>","task_id":"<TASK_ID>","node_ids":["START"],"comment":"退回发起人补充材料"}' \
29
+ --as user \
30
+ --yes
31
+
26
32
  # 传多个候选节点 ID(以实际审批定义支持情况为准)
27
33
  lark-cli approval tasks rollback \
28
34
  --data '{"instance_code":"<INSTANCE_CODE>","task_id":"<TASK_ID>","node_ids":["<NODE_ID_1>","<NODE_ID_2>"],"comment":"退回上一处理节点"}' \
@@ -43,7 +49,7 @@ lark-cli approval tasks rollback \
43
49
  | `--data '{...}'` | 是 | 请求体 JSON,使用 JSON 传入 |
44
50
  | `instance_code` | 是 | 审批实例 Code;通常先通过 `tasks query` 或 `instances initiated` / `instances get` 获取 |
45
51
  | `task_id` | 是 | 审批任务 ID;通常先通过 `tasks query` 获取 |
46
- | `node_ids` | 是 | 退回目标节点 ID 数组;执行前应先确认这些节点确实可作为退回目标 |
52
+ | `node_ids` | 是 | 退回目标节点 ID 数组;发起节点 ID 为 `START`;执行前应先确认这些节点确实可作为退回目标 |
47
53
  | `comment` | 否 | 审批意见或退回说明,例如 `请补充附件后重新提交`、`预算说明不完整,请补充` |
48
54
  | `--as user` | 否 | 建议显式指定用户身份;审批退回通常必须以用户身份执行 |
49
55
  | `--yes` | 否 | 确认执行高风险写操作;未带时可能返回 `confirmation_required` / exit 10 |
@@ -75,7 +81,7 @@ lark-cli approval instances get --params '{"instance_code":"<INSTANCE_CODE>"}' -
75
81
  ## 使用建议
76
82
 
77
83
  - **`instance_code` 和 `task_id` 要成对使用**:仅有实例 ID 或仅有任务 ID 都不足以准确执行退回操作。
78
- - **`node_ids` 是必填项**:退回并不是“自动退回上一步”,而是要明确给出目标节点 ID 数组。
84
+ - **`node_ids` 是必填项**:退回并不是“自动退回上一步”,而是要明确给出目标节点 ID 数组;退回发起节点时传 `START`。
79
85
  - **先确认节点是否可退回**:不同审批定义支持的退回目标可能不同;在不确定时,先通过 `instances get` 或业务侧流程信息核实。
80
86
  - **优先从 `tasks query` 的待办列表拿任务参数**:尤其是 `topic=1` 的待办审批,最适合作为 rollback 的输入来源。
81
87
  - **先检查是否支持 API 操作**:如果 `tasks[].support_api_operate` 为 `false`,说明该任务可能不支持通过 API 执行处理动作,退回前应谨慎验证。
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lark-apps
3
3
  version: 1.0.0
4
- description: "妙搭(Spark/Miaoda)应用开发与托管:应用创建、HTML静态站点发布、本地全栈开发、云端生成迭代、AI相关能力和飞书平台能力或者其他外部能力集成、日志/Trace/监控指标/PV/UV 查询、环境变量管理、自动化触发器(定时/记录变更/Webhook/飞书审批)。当用户要开发/新建一个系统·工具·平台·应用,或要本地开发 / 云端开发 / 修改 / 部署 / 发布 / 上线 / 拿可分享链接,或用 HTML 做页面·网站·部署到妙搭,或提到妙搭/Spark/Miaoda(应用运行时域名形如 *.aiforce.cloud)、应用数据库、应用文件存储、开放 API Key、可见范围、线上日志、接口请求量、错误量、延迟、访问量、环境变量、给妙搭应用配自动化任务/定时触发/审批通过后自动触发时使用。不负责普通云盘文件上传(lark-drive)、飞书文档编辑(lark-doc)、原生幻灯片创建(lark-slides)。"
4
+ description: "妙搭(Spark/Miaoda)应用开发与托管:应用创建、HTML静态站点发布、本地全栈开发、云端生成迭代、AI相关能力和飞书平台能力或者其他外部能力集成、日志/Trace/监控指标/PV/UV 查询、环境变量管理、应用角色与成员管理、自动化触发器(定时/记录变更/Webhook/飞书审批)。当用户要开发/新建一个系统·工具·平台·应用,或要本地开发 / 云端开发 / 修改 / 部署 / 发布 / 上线 / 拿可分享链接,或用 HTML 做页面·网站·部署到妙搭,或提到妙搭/Spark/Miaoda(应用运行时域名形如 *.aiforce.cloud)、应用数据库、应用文件存储、开放 API Key、可见范围、应用角色/角色成员、线上日志、接口请求量、错误量、延迟、访问量、环境变量、给妙搭应用配自动化任务/定时触发/审批通过后自动触发时使用。不负责普通云盘文件上传(lark-drive)、飞书文档编辑(lark-doc)、原生幻灯片创建(lark-slides)。"
5
5
  metadata:
6
6
  requires:
7
7
  bins: ["lark-cli"]
@@ -12,15 +12,15 @@ metadata:
12
12
 
13
13
  妙搭应用属于用户资产。默认用 `--as user`;认证、scope、exit-10、高风险确认、`_notice` 等通用处理只读 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),不要在本 skill 里复制。妙搭应用有三条开发路径:**本地全栈**(拉源码本地写)/ **HTML 托管**(发布静态产物)/ **云端会话**(妙搭 AI 生成)。
14
14
 
15
- ## 身份与一次性授权
15
+ ## 身份与授权
16
16
 
17
- 妙搭应用是用户的个人资产,统一 `--as user`(见开头)。**首次操作前先一次性把本域 scope 全拿到**,避免每条命令首次跑都触发新一轮授权,或未授权直接打到 openapi 导致服务端报错:
17
+ 妙搭应用是用户的个人资产,统一 `--as user`(见开头)。已有用户身份可用时直接执行业务命令,**不要为了预防权限问题主动重新登录**,否则可能中断原任务并触发不必要的设备授权。仅当 CLI 明确返回未登录或缺少本域 scope 时,一次性执行:
18
18
 
19
19
  ```bash
20
20
  lark-cli auth login --domain apps
21
21
  ```
22
22
 
23
- 因缺权限失败(`error.subtype == "missing_scope"`)时的通用处理见 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),同样按 `--domain apps` 授权。
23
+ 因缺权限失败(`error.subtype == "missing_scope"`)时的通用处理见 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),同样按 `--domain apps` 授权;授权成功后只恢复原业务操作,不扩展任务范围。
24
24
 
25
25
  ## 意图路由
26
26
 
@@ -33,15 +33,16 @@ lark-cli auth login --domain apps
33
33
  | 查单个应用详情(类型、名称、发布状态等) | `+get --app-id <app_id>` | [`lark-apps-get.md`](references/lark-apps-get.md) |
34
34
  | 改应用名或描述 | `+update` | [`lark-apps-update.md`](references/lark-apps-update.md) |
35
35
  | 发布本地 `index.html` 或静态目录为可访问 URL | `+html-publish` | [`lark-apps-html-publish.md`](references/lark-apps-html-publish.md) |
36
- | 开发已有应用 / 初始化本地仓库(开发方式已定为本地后;先解析 app_id,勿 `+create` 新建) | `+init`(或手动 `+git-credential-init` + 原生 git)。**执行前必读** [`lark-apps-local-dev.md`](references/lark-apps-local-dev.md),含端到端流程和领域规则 | [`lark-apps-init.md`](references/lark-apps-init.md), [`lark-apps-git-credential.md`](references/lark-apps-git-credential.md) |
36
+ | 开发已有应用 / 初始化本地仓库(开发方式已定为本地后;先解析 app_id,勿 `+create` 新建) | `+init`(或手动 `+git-credential-init` + 原生 git)。**执行前必读** [`lark-apps-local-dev.md`](references/lark-apps-local-dev.md);修改源码还须遵守下方「平台资源与应用源码边界」 | [`lark-apps-init.md`](references/lark-apps-init.md), [`lark-apps-git-credential.md`](references/lark-apps-git-credential.md) |
37
37
  | 本地开发时 `.env.local` 损坏/丢失,重新拉取启动期环境变量 | `+env-pull` | [`lark-apps-env-pull.md`](references/lark-apps-env-pull.md) |
38
38
  | 管理应用环境变量(查看/设置/删除) | `+env-list`, `+env-set`, `+env-delete` | [`lark-apps-env.md`](references/lark-apps-env.md) |
39
39
  | 查线上日志、Trace、请求数、错误率、延迟、CPU、memory、PV/UV/访问量 | `+log-list`, `+log-get`, `+trace-list`, `+trace-get`, `+metric-list`, `+analytics-list` | [`lark-apps-observability.md`](references/lark-apps-observability.md) |
40
40
  | 看表 / 看结构 / 初始化多环境 / 导入导出数据 / 变更追溯 / 行级审计 / dev→online 发布 / 时间点恢复 / 查 DB 用量 | `+db-table-list`、`+db-table-get`、`+db-env-create`、`+db-data-export`/`+db-data-import`、`+db-changelog-list`、`+db-audit-status`/`+db-audit-enable`/`+db-audit-disable`/`+db-audit-list`、`+db-env-diff`/`+db-env-migrate`、`+db-recovery-diff`/`+db-recovery-apply`、`+db-quota-get` | [`lark-apps-db.md`](references/lark-apps-db.md) |
41
- | 逐条执行 SQL(SELECT / DML / DDL) | `+db-execute` | [`lark-apps-db-execute.md`](references/lark-apps-db-execute.md) |
41
+ | 逐条执行 SQL(SELECT / DML / DDL);建表 / 改表 / 写 SQL 的平台规范 | `+db-execute` | [`lark-apps-db-execute.md`](references/lark-apps-db-execute.md)(含「平台 SQL 规范」:审计列 / RLS / `user_profile` / 禁用 SQL / PG 陷阱) |
42
42
  | 管理应用文件存储:上传/下载本地文件、列出/查看/删除已存文件、生成临时分享链接、查存储用量 | `+file-upload`/`+file-download`/`+file-list`/`+file-get`/`+file-sign`/`+file-delete`/`+file-quota-get` | [`lark-apps-file.md`](references/lark-apps-file.md) |
43
43
  | **部署/上线全栈应用**("部署""上线""推上去并部署""发布到云端");查发布状态/历史 | `+release-create`(部署上线动作), `+release-get`(轮询发布结果,finished 给 online_url / failed 给 error_logs), `+release-list` | [`lark-apps-release-create.md`](references/lark-apps-release-create.md), [`lark-apps-release-get.md`](references/lark-apps-release-get.md), [`lark-apps-release-list.md`](references/lark-apps-release-list.md) |
44
44
  | 设置或查看运行时可见范围 | `+access-scope-set`, `+access-scope-get` | 对应 access-scope reference |
45
+ | 管理 `app_...` 应用内角色、角色成员,或查询用户匹配角色 | `+role-list/get/create/update/delete`, `+role-member-list/add/remove`, `+role-match-list` | [`lark-apps-role.md`](references/lark-apps-role.md) |
45
46
  | 云端 Agent 生成/迭代应用(开发方式已定为云端后) | `+session-create` -> `+chat` -> `+session-get` | [`lark-apps-cloud-dev.md`](references/lark-apps-cloud-dev.md) |
46
47
  | 管理妙搭应用开放 API Key(创建/查看/启停/重置/删除凭证;密钥仅 create/reset 一次性返回) | `+openapi-key-list/get/create/update/enable/disable/delete/reset` | [`lark-apps-openapi-key.md`](references/lark-apps-openapi-key.md) |
47
48
  | 管理妙搭应用自动化触发器(定时/记录变更/Webhook/飞书审批四类触发器的查询/创建/更新/启停;Webhook URL·Token 一次性回显、不落盘) | `+automation-list/get/create/update/enable/disable` | [`lark-apps-automation.md`](references/lark-apps-automation.md) |
@@ -78,10 +79,15 @@ lark-cli auth login --domain apps
78
79
  - 发布态链接来源:html → `+html-publish` 的 `data.url`;全栈 → `+release-get` 轮询 `finished` 给 `online_url` / `failed` 给 `error_logs`。
79
80
  - **可见范围**:发布态链接(html 的 `data.url`、全栈的 `online_url`)默认仅**创建者可见**,发给他人对方会无权限打不开。当可分享链接交付给用户前,先告知当前仅本人可见,再询问是否用 `+access-scope-set`(`tenant`/`public`/`specific`)放开(可先 `+access-scope-get` 查当前范围)。
80
81
 
81
- ## 能力边界
82
+ ## 平台资源与应用源码边界
82
83
 
83
- - lark-cli **不支持**配置应用的权限(应用内 RBAC、成员角色、协作者权限)。`+access-scope-*` 只管运行时可见范围(谁能打开应用),不是角色权限。
84
- - 用户要配置权限时,引导其使用开发态链接前往云端开发(妙搭 web)处理。自动化触发器请用 `+automation-*`(见「意图路由」)。
84
+ - `apps +role-*` 只管理平台角色资源;修改已初始化应用的源码(包括当前目录已经是应用项目)时,先查看工作区 `.agents/skills/`,完整读取与任务匹配的领域 skill,再按其路由读取所需 reference。角色鉴权或运行态角色管理读应用内 `authz-guide`,不能用本 skill 的平台命令参考推断运行时合同。
85
+ - `lark-cli` 只用于开发过程中的平台资源核验或变更。应用运行时代码必须使用工程内领域 skill 规定的 SDK,禁止通过 `exec` 或子进程调用 `lark-cli`。
86
+ - 平台回读出的当前资源 ID、名称和成员只用于事实核验,不自动构成业务策略;除非需求或应用内领域 skill 明确定义,禁止把当前样本硬编码成 allowlist、denylist、只读集合或权限规则。
87
+ - 实现领域 SDK 时,以实际包导出的类型和应用内领域 reference 记录的入参、响应路径为准;禁止修改 ambient `.d.ts`、补造宽松类型或强制断言,让猜测的 SDK 结构仅在本地“编译通过”。
88
+ - typecheck/build 成功不等于合同正确。交付前逐项核对每个 SDK 调用的入参、响应取值路径和策略分支;涉及更新、删除等不同动作时,分别验证各自动作所需的完整状态,不能复用更弱的前置判断。
89
+ - 源码任务交付前确认新增页面、Controller、Module 已接入真实 router/bootstrap,并运行项目现有 typecheck/build;只创建未接线文件不算完成。
90
+ - `+access-scope-*` 只管运行时可见范围(谁能打开应用),不是角色权限;应用协作者/开发权限仍需使用妙搭 Web。自动化触发器请用 `+automation-*`(见「意图路由」)。
85
91
 
86
92
  ## app_id 获取
87
93
 
@@ -101,4 +107,4 @@ lark-cli auth login --domain apps
101
107
  ## 高影响动作:确认与预授权
102
108
 
103
109
  - **预授权判定**:判断用户是否表达了"放手做完、不用中途逐步问我"的意图——明确免确认(如"别问 / 直接做 / 自己定"),或要求一气呵成做到完成(如"做完部署上线给我")。是 → 整个流程按合理默认往下走、不再逐步确认(含 clone 到派生目录、发布等);否 → 缺失参数(如目录)该问就问、高影响动作先确认。
104
- - **禁止预授权判定底线**(即便已预授权也不豁免):① 会删/丢数据或不可逆的 DB 操作(判据见 [`lark-apps-db-execute.md`](references/lark-apps-db-execute.md))先 `--dry-run` 确认;② `+html-publish` 体积超限时(判据见 [`lark-apps-html-publish.md`](references/lark-apps-html-publish.md)),立即停止并转述超限项。
110
+ - **禁止预授权判定底线**(即便已预授权也不豁免):① 会删/丢数据或不可逆的 DB 操作(判据见 [`lark-apps-db-execute.md`](references/lark-apps-db-execute.md))先 `--dry-run` 确认;② `+role-delete`、`+role-member-remove --all`、批量移除成员必须先确认 app、role、成员范围和后果,不能从泛化"直接做"推导出 `--yes`;命令式“删除/移除某对象”只确定操作目标,不等于用户已确认不可逆后果,未明确确认时应在说明影响后停下请求确认;③ `+html-publish` 体积超限时(判据见 [`lark-apps-html-publish.md`](references/lark-apps-html-publish.md)),立即停止并转述超限项。
@@ -37,4 +37,4 @@ lark-cli apps +access-scope-set --app-id app_xxx --scope specific \
37
37
 
38
38
  若服务端返回"应用未发布/需先发布才能设置可见范围",把这一情况转述给用户并询问是否现在发布,得到同意后再 `+release-create`,不要把这个 hint 当指令自动发布。
39
39
 
40
- 用户给的是姓名、部门名或群名时,先解析成 ID 再组装 `--targets`:人名→`ou_` 用 `lark-cli contact +search-user --query <名字>`,群名→`oc_` 用 `lark-cli im +chat-search --query <群名>`,部门→`od_` 走 contact/通讯录。多候选时展示名称和 ID 让用户选,不要要求用户手填 `ou_` / `od_` / `oc_`。
40
+ 用户给的是姓名、部门名或群名时,先解析成 ID 再组装 `--targets`:人名→`ou_` 用 `lark-cli contact +search-user --query <名字>`,群名→`oc_` 用 `lark-cli im +chat-search --query <群名>`,部门→`od-` 走 contact/通讯录。多候选时展示名称和 ID 让用户选,不要要求用户手填 `ou_` / `od-` / `oc_`。
@@ -2,9 +2,11 @@
2
2
 
3
3
  经妙搭服务端在应用数据库执行 SQL。运行时命令事实以 `lark-cli apps +db-execute --help` 为准。
4
4
 
5
+ > **写 SQL 前先看文末「平台 SQL 规范」**:妙搭底层是 PostgreSQL + 一层平台约束,SQL 内容不符合会被服务端直接拒或建出行为不对的表。最容易踩的三条:① 建业务表必须带 4 个审计列(`_created_at`/`_updated_at`/`_created_by`/`_updated_by`)+ 启用 RLS + 4 条 policy,一次调用里写全;② 人员字段用内置复合类型 `user_profile`(写入 `ROW('<user_id>')::user_profile`,查询解引用 `(field).user_id`);③ `CREATE/DROP DATABASE·SCHEMA·USER·ROLE`、非白名单 `CREATE EXTENSION`、平台保留表 `auth`/`users` 会被硬拒,`online` 环境禁 DDL。
6
+
5
7
  ## 何时用
6
8
 
7
- 用于通过妙搭服务端执行应用数据库 SQL。不要从环境变量里取连接串裸连数据库;本地调试也走这个 shortcut。
9
+ 用于通过妙搭服务端执行应用数据库 SQL。不要从环境变量里取连接串裸连数据库;本地调试也走这个 shortcut。写什么样的 SQL(平台约束、建表模板、`user_profile`、审计列、禁用 SQL、PG 陷阱)见文末「平台 SQL 规范」。
8
10
 
9
11
  ## 命令骨架
10
12
 
@@ -42,3 +44,185 @@ lark-cli apps +db-execute --app-id app_xxx --environment dev --sql - --yes < /Us
42
44
  - 多语句失败时,失败前的语句可能已经 commit 落地。不要整批重跑;按错误 message/hint 修失败语句,并从剩余语句继续。
43
45
  - 如果需要原子性,让用户在 SQL 内显式写 `BEGIN` / `COMMIT`,不要假设 CLI 会包事务。
44
46
  - 不要把数据库连接串从 env 中取出来裸连。
47
+
48
+ ---
49
+
50
+ # 平台 SQL 规范
51
+
52
+ 上面讲命令怎么调,这里讲**该写出什么样的 SQL**:妙搭底层是 PostgreSQL + 一层平台约束(RLS、审计列、`user_profile` 复合类型、禁用 SQL 白名单),不符合会被服务端直接拒或建出行为不对的表。看表 / 看结构用 [`+db-table-list`/`+db-table-get`](lark-apps-db.md),别手写系统表查询模拟。
53
+
54
+ ## 平台禁用 SQL(硬拒绝)
55
+
56
+ 以下命中会被服务端拒,`error`(`type:"api"`)的 message/hint 会说明原因——先按 hint 修再重试,不要反复重试同一句。
57
+
58
+ | 类别 | 禁止 |
59
+ |---|---|
60
+ | 数据库级 | `CREATE / DROP / ALTER DATABASE` |
61
+ | Schema 级 | `CREATE / DROP SCHEMA` |
62
+ | 用户 / 角色级 | `CREATE / DROP USER`、`CREATE / DROP / ALTER ROLE` |
63
+ | Owner 切换 | `REASSIGN OWNED` / `DROP OWNED` |
64
+
65
+ ## 建表规范(CREATE TABLE)
66
+
67
+ 新建业务表必须:4 个审计列 + 启用 RLS + 4 条默认 policy,**放在同一次 `+db-execute` 调用里**(RLS / policy / COMMENT / INDEX 一起)。裸表名,不写 `public.` 或 schema 前缀。
68
+
69
+ ```sql
70
+ CREATE TABLE IF NOT EXISTS <table> (
71
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
72
+ -- ... 业务列 ...
73
+ name varchar(100) NOT NULL,
74
+ _created_at TIMESTAMP(3) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
75
+ _created_by user_profile DEFAULT (
76
+ CASE
77
+ WHEN current_setting('app.user_id', TRUE) = '' THEN NULL
78
+ ELSE concat('(', current_setting('app.user_id', TRUE), ')')::user_profile
79
+ END
80
+ ),
81
+ _updated_at TIMESTAMP(3) WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
82
+ _updated_by user_profile DEFAULT (
83
+ CASE
84
+ WHEN current_setting('app.user_id', TRUE) = '' THEN NULL
85
+ ELSE concat('(', current_setting('app.user_id', TRUE), ')')::user_profile
86
+ END
87
+ )
88
+ );
89
+
90
+ ALTER TABLE <table> ENABLE ROW LEVEL SECURITY;
91
+
92
+ CREATE POLICY service_role_bypass_policy ON <table>
93
+ TO service_role USING (true);
94
+
95
+ CREATE POLICY "修改全部数据" ON <table>
96
+ AS PERMISSIVE FOR ALL TO authenticated USING (true);
97
+
98
+ CREATE POLICY "查看全部数据" ON <table>
99
+ AS PERMISSIVE FOR SELECT TO authenticated, anon USING (true);
100
+
101
+ CREATE POLICY "修改本人数据" ON <table>
102
+ AS PERMISSIVE FOR ALL TO authenticated USING (
103
+ (current_setting('app.user_id'::text) = ANY (ARRAY[]::text[]))
104
+ AND (current_setting('app.user_id'::text) = ((_created_by).user_id)::text)
105
+ );
106
+ ```
107
+
108
+ 建表流程:先 `+db-table-list` / `+db-table-get` 确认表不存在或看现有结构 → 生成 DDL → 向用户展示影响并取得授权 → `+db-execute ... --yes` 执行。
109
+
110
+ ## 审计列
111
+
112
+ - 平台自动维护的四列固定叫 `_created_at` / `_updated_at` / `_created_by` / `_updated_by`(**下划线开头**)。查询 / 排序 / 过滤一律用这些名字,别写 `created_at`。
113
+ - `_created_at` / `_updated_at` 在 INSERT 时可省略(有默认值);需要业务归属时显式写 `_created_by` / `_updated_by`。
114
+ - UPDATE 业务字段时建议同步 `_updated_at = CURRENT_TIMESTAMP` 和 `_updated_by`。
115
+
116
+ ## `user_profile` 复合类型
117
+
118
+ 平台内置类型 `(user_id varchar, name varchar, email varchar, avatar text, status integer)`,无需创建。**业务 SQL 只允许访问 `(field).user_id`**,不要依赖 `name` / `email` / `avatar` / `status`(可能为空或过期)。
119
+
120
+ ```sql
121
+ -- 写入 / 更新:用 ROW()::user_profile,更新时替换整个字段,不改单个属性
122
+ INSERT INTO teacher (teacher_profile, class_id)
123
+ VALUES (ROW('<user_id>')::user_profile, gen_random_uuid());
124
+
125
+ UPDATE teacher SET teacher_profile = ROW('<user_id>')::user_profile
126
+ WHERE (teacher_profile).user_id = '<old_user_id>';
127
+
128
+ -- 查询 / 过滤:解引用取 user_id;raw SQL 返回给前端前必须解引用,别直接返回复合类型
129
+ SELECT (teacher_profile).user_id AS teacher_profile, class_id FROM teacher;
130
+
131
+ -- 索引 / 唯一性:表达式列用三重括号;表达式唯一性用 CREATE UNIQUE INDEX,
132
+ -- 不能用 ALTER TABLE ADD CONSTRAINT UNIQUE(不支持表达式列)
133
+ CREATE INDEX idx_teacher_user_id ON teacher (((teacher_profile).user_id));
134
+ CREATE UNIQUE INDEX uk_teacher_user_id ON teacher (((teacher_profile).user_id));
135
+ ```
136
+
137
+ ## DDL 规则
138
+
139
+ | 场景 | 做法 |
140
+ |---|---|
141
+ | 加列 | `ALTER TABLE <t> ADD COLUMN IF NOT EXISTS <col> <type>`,相关 `COMMENT ON` 同次执行 |
142
+ | 加索引 | `CREATE INDEX IF NOT EXISTS idx_<t>_<cols> ON <t>(...)` |
143
+ | JSONB 类型声明 | 必须 `COMMENT ON COLUMN <t>.<col> IS '@type { ... }'` 声明 TypeScript 类型,和 CREATE / ALTER 同次调用 |
144
+ | 加 NOT NULL 列 | 必须带 `DEFAULT` 让存量行自动填:`ADD COLUMN <col> <type> NOT NULL DEFAULT <值>` |
145
+ | 删表 / 删列 | 有业务数据默认禁止;必须用户明确授权后才执行,并说明数据丢失风险 |
146
+ | 强约束 | `UNIQUE` / `FOREIGN KEY` / `NOT NULL` 默认谨慎,不确定不加 |
147
+
148
+ **多环境库加约束前先查 online 存量**:`dev` 干净不代表 `online` 干净,约束发布到 online 会撞线上存量数据而失败。发布前一律先用 `--environment online` 查清楚,按约束类型分三种:
149
+
150
+ - **加唯一约束(`UNIQUE` / 唯一索引)**:线上不能有重复值。先查重复,有则先清理再加:
151
+
152
+ ```bash
153
+ lark-cli apps +db-execute --app-id app_xxx --environment online --sql \
154
+ "SELECT <cols>, count(*) FROM t GROUP BY <cols> HAVING count(*) > 1" --yes
155
+ ```
156
+
157
+ - **已有列改 `NOT NULL`(收紧约束)**:线上该列不能有 NULL。先查 NULL 行数,有就先回填(`UPDATE t SET <col> = <默认值> WHERE <col> IS NULL`)再加约束:
158
+
159
+ ```bash
160
+ lark-cli apps +db-execute --app-id app_xxx --environment online --sql \
161
+ "SELECT count(*) FROM t WHERE <col> IS NULL" --yes
162
+ ```
163
+
164
+ - **新加 `NOT NULL` 字段**:必须带 `DEFAULT`,且要求线上该表**无存量数据**,否则发布报错。线上已有数据时别直接加,改走三步安全变更:先 `ADD COLUMN <col> <type>`(可空)→ 回填 `UPDATE t SET <col> = <值>` → 再 `ALTER COLUMN <col> SET NOT NULL`。先查线上行数判断走哪条:
165
+
166
+ ```bash
167
+ lark-cli apps +db-execute --app-id app_xxx --environment online --sql \
168
+ "SELECT count(*) FROM t" --yes
169
+ ```
170
+
171
+ ## SELECT 规则
172
+
173
+ | 规则 | 要求 |
174
+ |---|------------------------------------------------------------------|
175
+ | 行数 | 结果集有硬上限(平台限制 1000 行),超限**报错而非静默截断**;大表必须显式 `LIMIT`、聚合或游标分页 |
176
+ | 分页 | 大表优先游标分页 `WHERE id > <last_id> ORDER BY id LIMIT n`,避免大 `OFFSET` |
177
+ | user_profile | 返回给前端前解引用:`(owner).user_id AS owner` |
178
+ | 统计 | 总数用 `count(*)`、分组用 `GROUP BY`,别把全量拉到 agent 侧再统计 |
179
+ | 慢查询 | 用 `EXPLAIN (ANALYZE, BUFFERS)`;大表 Seq Scan 考虑加索引 |
180
+
181
+ ## DML 规则
182
+
183
+ **INSERT**
184
+ - UUID 主键省略,交给 `DEFAULT gen_random_uuid()`;外键 UUID 用子查询取父表 id,不手写。
185
+ - NOT NULL 且无默认值的列必须给值;批量 INSERT 每行列数一致。
186
+ - 需要幂等用 `ON CONFLICT ... DO NOTHING / DO UPDATE`。
187
+ - 标量子查询必须保证单行,非唯一条件加 `ORDER BY ... LIMIT 1`。
188
+
189
+ **UPDATE**
190
+ - **必须有明确 `WHERE`,禁止无条件 UPDATE**。
191
+ - 用户说「修改 / 更新 / 改一下」数据时用 UPDATE,**禁止 DELETE + INSERT** 模式。
192
+ - 更新 `user_profile` / 复合类型时替换整个字段。
193
+ - 批量更新前影响范围不明确,先 `SELECT count(*)` 给用户确认。
194
+
195
+ **DELETE / TRUNCATE**(属会丢数据的高影响操作,按上面「Agent 规则」的确认流程走)
196
+ - 已有表 / 已有数据默认禁止;先 `SELECT count(*)` 展示命中行数、取得用户明确授权,再带 `--yes` 执行。
197
+ - `TRUNCATE` 影响整表,视同高风险删除。
198
+
199
+ ```sql
200
+ UPDATE task
201
+ SET status = 'done', _updated_at = CURRENT_TIMESTAMP, _updated_by = ROW('<user_id>')::user_profile
202
+ WHERE id = (SELECT id FROM task WHERE title = '梳理需求' ORDER BY _created_at DESC LIMIT 1);
203
+ ```
204
+
205
+ ## 常见 PostgreSQL 陷阱
206
+
207
+ | 陷阱 | 正确做法 |
208
+ |---|---|
209
+ | 表名带 schema 前缀 | 业务表一律裸表名 `FROM orders`,别写 `public.orders` |
210
+ | 保留字作标识符 | 避免 `user` / `order` / `desc` / `offset` / `references` 等 |
211
+ | 内联 COMMENT | 禁止 `col TEXT COMMENT 'xx'`,用独立 `COMMENT ON COLUMN` |
212
+ | 手写系统表查结构 | 常规结构查询用 `+db-table-list` / `+db-table-get`,别手写 `information_schema` / `pg_indexes` 模拟 |
213
+ | 空数组类型不明 | 写 `ARRAY[]::text[]` 或 `'{}'::text[]` |
214
+ | `ROUND` 报错 | 用 `ROUND(num::numeric, n)` 或 `ROUND(num::double precision)` |
215
+ | `DISTINCT` + 窗口函数 | 分两层查询,先 DISTINCT 再窗口函数 |
216
+ | MySQL 方言 | 不用 `SHOW TABLES` / `DESCRIBE` / 内联 `COMMENT`;用 `+db-table-*` 和 `COMMENT ON` |
217
+ | 多语句以为自动回滚 | `A; B; C` 不自动包事务,B 失败时 A 已提交;要原子性显式 `BEGIN; ... COMMIT;`(见上「命令骨架」「Agent 规则」) |
218
+
219
+ ## 数据类型与设计
220
+
221
+ | 项目 | 规则 |
222
+ |---|---|
223
+ | 主键 | 默认 `id uuid PRIMARY KEY DEFAULT gen_random_uuid()` |
224
+ | 命名 | 表名单数、全小写、snake_case、无冗余后缀 |
225
+ | 枚举 / 状态 | 用 `varchar(255)`,值用小写英文 + 下划线 |
226
+ | JSONB | 必须 `COMMENT ON COLUMN ... IS '@type { ... }'` 声明类型 |
227
+ | 附件 / 图片 | URL 用 `TEXT`,命名 `xxx_url` |
228
+ | 约束 | `UNIQUE` / `FOREIGN KEY` / `NOT NULL` 默认谨慎,新增 NOT NULL 列优先带 `DEFAULT` |
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 何时用
6
6
 
7
- 用户要看应用里有哪些表 / 某张表的结构、把单库应用拆成 dev/online 多环境、把数据导进导出表、查谁在什么时候改了表结构或表数据、开关行级审计、把开发环境的库结构发布到线上、把库恢复到过去某个时间点、或看数据库用量时。逐条执行 SQL 走 [`+db-execute`](lark-apps-db-execute.md);文件存储(上传/下载文件)走 [`lark-apps-file.md`](lark-apps-file.md)。
7
+ 用户要看应用里有哪些表 / 某张表的结构、把单库应用拆成 dev/online 多环境、把数据导进导出表、查谁在什么时候改了表结构或表数据、开关行级审计、把开发环境的库结构发布到线上、把库恢复到过去某个时间点、或看数据库用量时。逐条执行 SQL 走 [`+db-execute`](lark-apps-db-execute.md);文件存储(上传/下载文件)走 [`lark-apps-file.md`](lark-apps-file.md)。**建表 / 改表 / 写 SQL 的平台内容规范**(审计列、RLS、`user_profile`、禁用 SQL、PG 陷阱)见 [`lark-apps-db-execute.md`](lark-apps-db-execute.md) 的「平台 SQL 规范」。
8
8
 
9
9
  ## 命令一览
10
10
 
@@ -0,0 +1,133 @@
1
+ # apps role 域命令(应用角色)
2
+
3
+ 管理妙搭应用内的平台角色、角色成员,以及查询某个用户命中的角色。运行时命令事实以 `lark-cli apps +<cmd> --help` 为准;身份、授权和高风险确认遵循本域 [`SKILL.md`](../SKILL.md)。
4
+
5
+ ## 何时用
6
+
7
+ 用户要列出、查看、创建、更新或删除某个妙搭应用内的平台角色,管理角色的用户、部门或群成员,或查询某个用户在应用中命中的角色时使用。多维表格 / Base 的角色与权限走 `lark-base`;设置谁能访问应用走 `+access-scope-*`,不要路由到本命令域。
8
+
9
+ ## 命令一览
10
+
11
+ | 命令 | 做什么 | 关键参数 |
12
+ |---|---|---|
13
+ | `+role-list` | 分页列出角色,或按名称筛选角色 | `--app-id`、`--name`、`--page-size`/`--page-token` |
14
+ | `+role-get` | 根据真实 `role_id` 读取角色详情 | `--app-id`、`--role-id` |
15
+ | `+role-match-list` | 查询指定用户命中的角色 | `--app-id`、`--user-id` |
16
+ | `+role-create` | 创建角色 | `--app-id`、`--name`、`--description`、`--role-id` |
17
+ | `+role-update` | 更新角色名称或描述 | `--app-id`、`--role-id`、`--name`/`--description` |
18
+ | `+role-delete` | 永久删除角色 | `--app-id`、`--role-id`、`--yes` |
19
+ | `+role-member-list` | 查询角色的用户、部门和群成员 | `--app-id`、`--role-id`、`--member-type` |
20
+ | `+role-member-add` | 向角色添加用户、部门或群成员 | `--app-id`、`--role-id`、`--users`/`--departments`/`--chats` |
21
+ | `+role-member-remove` | 定向移除或清空角色成员 | `--app-id`、`--role-id`、成员参数或 `--all`、`--yes` |
22
+
23
+ ## 约定(先读)
24
+
25
+ - `app_...` 标识的是妙搭应用,其角色和成员只使用 `apps +role-*` / `apps +role-member-*`;不要改走 Base 角色命令或裸 bitable API。
26
+ - 角色名称不是 `role_id`。只有名称时优先用 `+role-list --name` 精确解析;若已取得完整分页列表,也可从中证明精确名称唯一命中。0 条如实报告,多条让用户消歧,唯一命中后才使用返回的真实 ID。
27
+ - `+role-list` 返回 `has_more=true` 时,用本页 `page_token` 继续查询,直到 `has_more=false`;不要根据 `total` 补造条目。
28
+ - `+role-list`、`+role-get`、`+role-match-list` 的角色数据分别位于 `data.items`、`data.role`、`data.roles`,不要混用。
29
+ - 同一角色的写入及依赖该写入结果的操作必须串行。不同角色的独立操作只有在每次写入可单独追溯、失败不影响其它目标且分别验收时才可并行;否则保持串行。互不依赖的名称解析或只读查询可并行。
30
+
31
+ ## 各命令
32
+
33
+ ### 查询角色
34
+
35
+ ```bash
36
+ lark-cli apps +role-list --app-id <app_id> --page-size 100
37
+ lark-cli apps +role-list --app-id <app_id> --name '<exact_name>'
38
+ lark-cli apps +role-get --app-id <app_id> --role-id <role_id>
39
+ lark-cli apps +role-match-list --app-id <app_id> --user-id <ou_x>
40
+ ```
41
+
42
+ 整理角色列表时保留 `role_id`、`name` 和 `description`。不要猜测未知 `role_id`,也不要从同名候选中静默选择。
43
+ `items=[]` 时直接报告当前没有角色;不要为表格补造“无”或 `N/A` 占位行。
44
+ `+role-match-list --user-id` 只接受 `ou_...`;用户给的是姓名、邮箱或手机号时,先解析唯一 open ID,再查询命中角色。
45
+
46
+ ### 创建与更新
47
+
48
+ ```bash
49
+ lark-cli apps +role-create --app-id <app_id> --name '<name>' \
50
+ --description '<description>'
51
+
52
+ # 只修改名称
53
+ lark-cli apps +role-update --app-id <app_id> --role-id <role_id> \
54
+ --name '<new_name>' --as user --format json
55
+
56
+ # 只修改描述
57
+ lark-cli apps +role-update --app-id <app_id> --role-id <role_id> \
58
+ --description '<new_description>' --as user --format json
59
+ ```
60
+
61
+ - `--description` 和创建时的 `--role-id` 可选;仅在确实需要稳定 ID 时传 `--role-id`,创建后不能修改。
62
+ - 更新时只传用户明确要求变更的字段。
63
+ - 成功响应中的角色位于 `data.role`。只有用户要求独立验证,或结果将用于后续高风险操作时,才额外执行 `+role-get`。
64
+
65
+ ### 删除角色
66
+
67
+ 普通“删除某角色”请求只说明目标,**不等于不可逆确认**。如果用户尚未明确确认删除后果,本轮只能定位角色、读取完整成员并说明影响,最后请求确认;不得在同一轮自动追加 `--yes`。用户已明确确认不可逆删除时才继续。
68
+
69
+ 只有名称时仍按上述规则唯一解析,优先使用 `+role-list --name`。目标写前已不存在时立即停止,如实说明本次是 no-op、没有执行删除,不能把“当前不存在”表述为“删除成功”。
70
+
71
+ 删除前读取准确角色和完整成员范围,向用户说明 app、role、`users` / `departments` / `chats` 影响;得到不可逆删除确认后才使用 `--yes`:
72
+
73
+ ```bash
74
+ lark-cli apps +role-get --app-id <app_id> --role-id <role_id>
75
+ lark-cli apps +role-member-list --app-id <app_id> --role-id <role_id>
76
+ lark-cli apps +role-delete --app-id <app_id> --role-id <role_id> --yes
77
+ ```
78
+
79
+ 成功响应包含匹配的 `data.role_id` 和 `data.deleted=true`。只有用户明确要求独立验证删除结果时,才再用 `+role-list --name` 检查目标 ID 已不存在。
80
+
81
+ ### 成员 ID 解析
82
+
83
+ 成员 flags 只接受 open ID:用户 `ou_...`、部门 `od-...`、群 `oc_...`。用户已提供对应类型的合法 open ID 时直接使用;只有名称或邮箱时才解析。
84
+ 对象类型以用户语义为准,不能互换解析器:用户走通讯录用户搜索,部门走部门搜索,群走群搜索。
85
+
86
+ ```bash
87
+ # 用户:每个姓名或邮箱单独查询。
88
+ lark-cli contact +search-user --query '<姓名或邮箱>' \
89
+ --exclude-external-users --page-size 30
90
+
91
+ # 部门:拉完分页,只接受唯一的 open_department_id。
92
+ lark-cli api POST /open-apis/contact/v3/departments/search \
93
+ --params '{"user_id_type":"open_id","department_id_type":"open_department_id","page_size":50}' \
94
+ --data '{"query":"<部门名称>"}'
95
+
96
+ # 群:拉完分页,只接受名称精确匹配的唯一 chat_id。
97
+ lark-cli im +chat-search --query '<群名称>' --page-size 50
98
+ ```
99
+
100
+ - 只接受与输入姓名、邮箱或群名精确匹配的唯一结果;部门搜索只接受完整 query 的唯一 `od-...`。0 条、多条或分页未完成时停止写入并让用户补充或消歧。
101
+ - 多个对象逐个解析。全部解析成功且总数不超过 100 后,按类型放入一次成员写入;任一对象失败时不要部分写入,也不要自动拆批。
102
+
103
+ ### 成员操作
104
+
105
+ ```bash
106
+ # 省略 --member-type,返回完整 users / departments / chats。
107
+ lark-cli apps +role-member-list --app-id <app_id> --role-id <role_id>
108
+
109
+ lark-cli apps +role-member-add --app-id <app_id> --role-id <role_id> \
110
+ --users ou_x,ou_y --departments od-x --chats oc_x
111
+
112
+ lark-cli apps +role-member-remove --app-id <app_id> --role-id <role_id> \
113
+ --users ou_x --yes
114
+
115
+ # 清空成员,不删除角色。
116
+ lark-cli apps +role-member-remove --app-id <app_id> --role-id <role_id> \
117
+ --all --yes
118
+ ```
119
+
120
+ - `+role-member-list` 不分页;`--member-type` 只返回选中类型的字段,未返回的成员字段表示“未查询”而不是空。影响确认或完整比较时必须省略它。
121
+ - 汇总 `--member-type` 结果时明确这是过滤投影,不得据此断言角色没有其它类型成员。
122
+ - 用户要求 CLI 原生 table 时,直接执行 `+role-member-list --format table`;可原样转发或做事实摘要,不要先取 JSON 再手工重建一张替代表格。
123
+ - 写入和依赖其结果的回读不得放进同一个并发批次;必须等待写入完整返回成功后,再单独发起回读。误并发时只能以写入完成后的新回读作为结果证据。
124
+ - 添加前仅在用户要求独立证明或确认其他成员类型未变化时读取完整基线,并在写后完整回读;否则成功响应即可作为结果。
125
+ - 定向移除前确认准确成员及影响。若需要证明结果,写后完整回读;不要把过滤结果当作完整成员集合。
126
+ - `--all` 前读取完整成员范围并确认;成功后执行一次无过滤 `+role-member-list`,确认三个成员数组均为空。
127
+
128
+ ## 权限
129
+
130
+ | 操作 | 所需 scope |
131
+ |---|---|
132
+ | list / get / member-list / match-list | `spark:app:read` |
133
+ | create / update / delete / member-add / member-remove | `spark:app:write` |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lark-base
3
- version: 1.2.2
3
+ version: 1.2.3
4
4
  description: "飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、workflow、角色权限;遇到 Base/多维表格/bitable 或 /base/ 链接时使用。文件导入转 lark-drive,认证/授权转 lark-shared。"
5
5
  metadata:
6
6
  requires:
@@ -104,6 +104,8 @@ metadata:
104
104
 
105
105
  ## 写入前置规则
106
106
 
107
+ - 更新前先看命令说明:需要完整提交时,先读取并补齐当前配置,只改用户指定的内容,再按命令要求提交;支持局部修改时,按命令说明和 reference 提交最小合法 payload。
108
+ - 优先用写入返回确认结果;返回信息不足或任务明确要求核验时,再读回。
107
109
  - 写记录前先读字段结构;只写存储字段。系统字段、附件字段、`formula`、`lookup` 不作为普通记录写入目标。
108
110
  - 附件上传、下载、删除走专用 `+record-*-attachment` 命令。
109
111
  - 写字段前先读 [lark-base-field-json.md](references/lark-base-field-json.md);涉及 `formula` / `lookup` 时必须读 [formula-field-guide.md](references/formula-field-guide.md) / [lookup-field-guide.md](references/lookup-field-guide.md)。
@@ -122,7 +124,7 @@ metadata:
122
124
 
123
125
  ## Dashboard / Workflow / Role
124
126
 
125
- - Dashboard 的复杂点是 block 的 `data_config`,不是 list/get/create/delete 命令参数。创建或更新 block 前先读 [dashboard-block-data-config.md](references/dashboard-block-data-config.md),组件必须串行创建;`+dashboard-arrange` 是服务端智能布局,只在用户明确要求重排/美化时执行。`+dashboard-block-get-data` 读取图表最终计算结果,不返回 block 名称、类型、布局或 `data_config`;需要元数据先用 `+dashboard-block-get`。
127
+ - Dashboard 的复杂点是 block 的 `data_config`,不是 list/get/create/delete 命令参数。创建或更新 block 前先读 [dashboard-block-data-config.md](references/dashboard-block-data-config.md),组件必须串行创建;`+dashboard-arrange` 是服务端智能布局,仅在用户明确要求重排/美化、或对本次会话从零新建的仪表盘做收尾整理时执行。`+dashboard-block-get-data` 读取图表最终计算结果,不返回 block 名称、类型、布局或 `data_config`;需要元数据先用 `+dashboard-block-get`。
126
128
  - Workflow 的复杂点是 `steps` 结构。创建、更新或解释完整 workflow 时读入口 [lark-base-workflow-guide.md](references/lark-base-workflow-guide.md) 和 steps JSON SSOT [lark-base-workflow-schema.md](references/lark-base-workflow-schema.md);enable/disable/list 只需确认 workflow ID、当前启停状态和用户意图。
127
129
  - Role 的复杂点是权限 JSON。角色操作先读入口 [lark-base-role-guide.md](references/lark-base-role-guide.md);`+role-create` 只支持自定义角色;`+role-update` 是 delta merge;角色 create/update 或解读完整配置时读权限 JSON SSOT [role-config.md](references/role-config.md)。`+role-delete` 只适用于自定义角色,系统角色不可删除;删除角色和关闭高级权限前必须确认目标和影响。
128
130
 
@@ -134,6 +136,8 @@ metadata:
134
136
  | `not found` 且输入来自 Wiki 链接 | 优先检查是否把 wiki token 当成 base token,不要立刻改走裸 API |
135
137
  | `1254045` 字段名不存在 | 重新 `+field-list`,使用真实字段名或字段 ID;注意空格、大小写和跨表字段 |
136
138
  | `1254015` 字段值类型不匹配 | 先 `+field-list`,再按 [lark-base-cell-value.md](references/lark-base-cell-value.md) 构造 CellValue |
139
+ | `Invalid discriminator value`(字段写入缺 `type`) | 按完整提交规则读取当前字段,只改目标内容后提交;不要只补 `type` 重试 |
140
+ | filter 报 `value of type array` / `Only string values` | 用 record/view 的 tuple `--filter-json`(非 `+data-query` 对象型),value 按字段 type 选标量或数组;见 [lark-base-view-set-filter.md](references/lark-base-view-set-filter.md) |
137
141
  | 日期 / 人员 / 超链接字段报格式错误 | 日期用 `YYYY-MM-DD HH:mm:ss`;人员用 `[{ "id": "ou_xxx" }]`;超链接用 URL 或 markdown link 字符串 |
138
142
  | formula / lookup 创建失败 | 先读 [formula-field-guide.md](references/formula-field-guide.md) / [lookup-field-guide.md](references/lookup-field-guide.md),再按 guide 重建请求 |
139
143
  | `ignored_fields` / `READONLY` | 移除只读字段,只写存储字段 |