@amaster.ai/pi-lark 0.1.2-beta.54 → 0.1.2-beta.56

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 (96) hide show
  1. package/package.json +2 -2
  2. package/skills/lark-apps/SKILL.md +2 -0
  3. package/skills/lark-apps/references/lark-apps-db.md +130 -2
  4. package/skills/lark-apps/references/lark-apps-user-id-convert.md +63 -0
  5. package/skills/lark-base/SKILL.md +22 -34
  6. package/skills/lark-base/references/lark-base-cell-value.md +19 -7
  7. package/skills/lark-base/references/lark-base-data-analysis-cloud.md +145 -0
  8. package/skills/lark-base/references/lark-base-data-analysis-pandas.md +93 -0
  9. package/skills/lark-base/references/lark-base-data-analysis-python-stdlib.md +120 -0
  10. package/skills/lark-base/references/lark-base-data-analysis-sop.md +166 -155
  11. package/skills/lark-base/references/lark-base-data-query-guide.md +1 -3
  12. package/skills/lark-base/references/lark-base-data-query.md +6 -9
  13. package/skills/lark-base/references/lark-base-field-json.md +2 -2
  14. package/skills/lark-base/references/lark-base-record-upsert.md +2 -2
  15. package/skills/lark-calendar/SKILL.md +2 -0
  16. package/skills/lark-calendar/references/lark-calendar-create.md +1 -0
  17. package/skills/lark-doc/SKILL.md +1 -1
  18. package/skills/lark-doc/references/lark-doc-media-download.md +2 -1
  19. package/skills/lark-drive/SKILL.md +5 -3
  20. package/skills/lark-drive/references/lark-drive-download.md +29 -2
  21. package/skills/lark-drive/references/lark-drive-export.md +1 -0
  22. package/skills/lark-drive/references/lark-drive-member-remove.md +59 -0
  23. package/skills/lark-drive/references/lark-drive-preview.md +21 -2
  24. package/skills/lark-drive/references/lark-drive-push.md +5 -1
  25. package/skills/lark-drive/references/lark-drive-search.md +2 -0
  26. package/skills/lark-minutes/SKILL.md +11 -5
  27. package/skills/lark-minutes/references/lark-minutes-apply-permission.md +95 -0
  28. package/skills/lark-minutes/references/lark-minutes-detail.md +7 -6
  29. package/skills/lark-minutes/references/lark-minutes-download.md +4 -2
  30. package/skills/lark-note/SKILL.md +11 -9
  31. package/skills/lark-note/references/lark-note-detail.md +5 -2
  32. package/skills/lark-note/references/lark-note-transcript.md +2 -0
  33. package/skills/lark-shared/SKILL.md +36 -0
  34. package/skills/lark-slides/SKILL.md +54 -54
  35. package/skills/lark-slides/references/cli/lark-slides-add-slide.md +92 -0
  36. package/skills/lark-slides/references/cli/lark-slides-create.md +176 -0
  37. package/skills/lark-slides/references/cli/lark-slides-delete-slide.md +65 -0
  38. package/skills/lark-slides/references/cli/lark-slides-history.md +132 -0
  39. package/skills/lark-slides/references/cli/lark-slides-media-upload.md +103 -0
  40. package/skills/lark-slides/references/cli/lark-slides-replace-slide.md +259 -0
  41. package/skills/lark-slides/references/cli/lark-slides-screenshot.md +115 -0
  42. package/skills/lark-slides/references/{lark-slides-update-slide.md → cli/lark-slides-update-slide.md} +3 -3
  43. package/skills/lark-slides/references/cli/lark-slides-xml-presentation-slide-get.md +110 -0
  44. package/skills/lark-slides/references/cli/lark-slides-xml-presentation-slide-replace.md +188 -0
  45. package/skills/lark-slides/references/cli/lark-slides-xml-presentations-get.md +157 -0
  46. package/skills/lark-slides/references/iconpark-index.json +5 -41901
  47. package/skills/lark-slides/references/iconpark.md +3 -44
  48. package/skills/lark-slides/references/lark-slides-add-slide.md +3 -90
  49. package/skills/lark-slides/references/lark-slides-create.md +3 -174
  50. package/skills/lark-slides/references/lark-slides-delete-slide.md +3 -63
  51. package/skills/lark-slides/references/lark-slides-edit-workflows.md +3 -141
  52. package/skills/lark-slides/references/lark-slides-history.md +3 -130
  53. package/skills/lark-slides/references/lark-slides-media-upload.md +3 -102
  54. package/skills/lark-slides/references/lark-slides-pptx-template-workflows.md +3 -83
  55. package/skills/lark-slides/references/lark-slides-replace-slide.md +3 -256
  56. package/skills/lark-slides/references/lark-slides-screenshot.md +3 -113
  57. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-get.md +3 -108
  58. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-replace.md +3 -186
  59. package/skills/lark-slides/references/lark-slides-xml-presentations-get.md +3 -155
  60. package/skills/lark-slides/references/planning-layer.md +1 -1
  61. package/skills/lark-slides/references/slides_chart_demo.xml +5 -1415
  62. package/skills/lark-slides/references/slides_xml_schema_definition.xml +3 -3512
  63. package/skills/lark-slides/references/troubleshooting.md +3 -60
  64. package/skills/lark-slides/references/validation-checklist.md +3 -154
  65. package/skills/lark-slides/references/workflow/error-handling.md +62 -0
  66. package/skills/lark-slides/references/workflow/slides-editing.md +143 -0
  67. package/skills/lark-slides/references/workflow/template-editing.md +85 -0
  68. package/skills/lark-slides/references/workflow/validation-xml.md +156 -0
  69. package/skills/lark-slides/references/xml/iconpark-index.json +37458 -0
  70. package/skills/lark-slides/references/xml/iconpark.md +46 -0
  71. package/skills/lark-slides/references/xml/slides_chart_demo.xml +1415 -0
  72. package/skills/lark-slides/references/xml/slides_xml_schema_definition.xml +3514 -0
  73. package/skills/lark-slides/references/xml/xml-schema-quick-ref.md +497 -0
  74. package/skills/lark-slides/references/xml-schema-quick-ref.md +3 -495
  75. package/skills/lark-slides/scripts/iconpark_tool.py +1 -1
  76. package/skills/lark-slides/scripts/xml_lint.py +2989 -0
  77. package/skills/lark-slides/scripts/xml_lint_test.py +4720 -0
  78. package/skills/lark-slides/scripts/xml_text_overlap_lint.py +3 -2975
  79. package/skills/lark-slides/scripts/xml_text_overlap_lint_test.py +5 -4712
  80. package/skills/lark-task/SKILL.md +12 -0
  81. package/skills/lark-task/references/lark-task-create.md +3 -1
  82. package/skills/lark-vc/SKILL.md +13 -5
  83. package/skills/lark-vc/references/lark-vc-detail.md +11 -6
  84. package/skills/{lark-vc-agent/references/lark-vc-agent-meeting-events.md → lark-vc/references/lark-vc-meeting-events.md} +121 -20
  85. package/skills/{lark-vc-agent/references/lark-vc-agent-meeting-list-active.md → lark-vc/references/lark-vc-meeting-list-active.md} +2 -2
  86. package/skills/{lark-vc-agent/references/lark-vc-agent-meeting-message-send.md → lark-vc/references/lark-vc-meeting-message-send.md} +3 -3
  87. package/skills/lark-vc/references/lark-vc-recording.md +8 -6
  88. package/skills/lark-vc/references/vc-domain-boundaries.md +6 -1
  89. package/skills/lark-vc-agent/SKILL.md +24 -9
  90. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md +2 -2
  91. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md +2 -2
  92. package/skills/lark-wiki/SKILL.md +3 -1
  93. package/skills/lark-wiki/references/lark-wiki-node-copy.md +4 -19
  94. package/skills/lark-wiki/references/lark-wiki-node-create.md +18 -2
  95. package/skills/lark-wiki/references/lark-wiki-node-get.md +11 -0
  96. package/skills/lark-wiki/references/lark-wiki-node-list.md +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/pi-lark",
3
- "version": "0.1.2-beta.54",
3
+ "version": "0.1.2-beta.56",
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",
@@ -61,7 +61,7 @@
61
61
  "vitest": "^4.0.0"
62
62
  },
63
63
  "dependencies": {
64
- "@amaster.ai/pi-shared": "0.1.2-beta.54"
64
+ "@amaster.ai/pi-shared": "0.1.2-beta.56"
65
65
  },
66
66
  "scripts": {
67
67
  "fetch-skills": "node scripts/fetch-skills.mjs",
@@ -52,9 +52,11 @@ lark-cli auth login --domain apps
52
52
  | 管理妙搭应用自动化触发器(定时/记录变更/Webhook/飞书审批四类触发器的查询/创建/更新/启停;Webhook URL·Token 一次性回显、不落盘) | `+automation-list/get/create/update/enable/disable` | [`lark-apps-automation.md`](references/lark-apps-automation.md) |
53
53
  | 查看某次会话某一轮(turn)的回复消息(含仍在生成中的本轮)/ 导出上一轮模型回复("这一轮回复了什么""上一轮的回复""导出某轮消息") | 先 `+session-get`(取 `latest_turn.turn_id`)-> `+session-messages-list --turn-id <id>`(仅 user 身份;分页用 `--page-token`) | [`lark-apps-session-messages-list.md`](references/lark-apps-session-messages-list.md) |
54
54
  | 外部能力(AI模型能力和飞书平台能力)集成/插件/Plugin/Capability | `+plugin-install`, `+plugin-list`, `+plugin-uninstall` | [`lark-apps-plugin-install.md`](references/lark-apps-plugin-install.md), [`lark-apps-plugin-uninstall.md`](references/lark-apps-plugin-uninstall.md), [`lark-apps-plugin-list.md`](references/lark-apps-plugin-list.md) |
55
+ | 把一批 ID 在妙搭 user_id ↔ 飞书 open_id / union_id / 飞书 user_id 之间互转(例如拿到 open_id 但下游要 user_id) | `+user-id-convert --convert-type <方向> --ids <id1,id2,...>` | [`lark-apps-user-id-convert.md`](references/lark-apps-user-id-convert.md) |
55
56
 
56
57
  ## 高频路径
57
58
 
59
+ - **Base 到应用数据库同步**:用户说“Base 同步到数据库 / 整库同步 / 多张表同步 / 批量任务重新启用 / operation-not-allowed”时,先读 [`lark-apps-db.md`](references/lark-apps-db.md) 的 Base 数据同步段落,再查 app_id 或处理授权。先形成计划再动手:`+db-sync-create` 一次只处理一张 Base 表,整库/多表必须拆成多份单表配置和多次 preview/create;batch/import 任务是一次性任务,不能重新 enable,遇 operation-not-allowed 先解释生命周期边界,再用 `+db-sync-get` 查状态/结果,持续同步要新建 streaming 任务。
58
60
  - **性能/监控/观测指标**:用户问“接口请求量、错误量、错误率、接口慢、延迟、CPU、内存、最近一小时/七天趋势”时,不要去当前工作区搜索监控文件,也不要询问“监控数据在哪”。先按「app_id 获取」解析应用:`lark-cli apps +list --keyword "<应用名>" --as user`;拿到 `app_id` 后读 [`lark-apps-observability.md`](references/lark-apps-observability.md),用 `+metric-list`。
59
61
  - **请求量 + 错误量 + 延迟**:请求量/错误量用 `lark-cli apps +metric-list --app-id <app_id> --metric requests --since <range> --as user`(不传 `--series` 会同时返回 total/error);延迟用 `--metric latency`(不传 `--series` 会返回 p50/p99)。如果用户给了具体接口,再加 `--api <path-or-name>`;不要臆造 group-by 参数。
60
62
  - **PV/UV/访问量/活跃用户**:先解析 `app_id`,再用 `+analytics-list`,不要误用 `+metric-list`。
@@ -15,6 +15,13 @@
15
15
  | `+db-env-create` | 把单库应用初始化为 dev/online 多环境(高危) | `--environment`、`--sync-data`、`--yes` |
16
16
  | `+db-data-export` | 把一张表的数据导出到本地文件 | `--table`、`--output`、`--limit`、`--environment` |
17
17
  | `+db-data-import` | 把本地 csv/json 文件导进一张表(高危) | `--file`、`--table`、`--environment`、`--yes` |
18
+ | `+db-sync-create` | 预览或创建 Base 到应用数据库的同步任务(高危) | `--config`、`--preview`、`--output`、`--environment`、`--yes` |
19
+ | `+db-sync-list` | 列出 Base 同步任务 | `--mode`、`--status`、`--table`、`--page-size`/`--page-token`、`--environment` |
20
+ | `+db-sync-get` | 查看同步任务配置、状态、统计和 warnings | `--task-id` |
21
+ | `+db-sync-enable` | 启用 streaming 同步任务 | `--task-id` |
22
+ | `+db-sync-disable` | 停用 streaming 同步任务 | `--task-id` |
23
+ | `+db-sync-update` | 修改 streaming 同步任务映射配置(高危) | `--task-id`、`--config`、`--yes` |
24
+ | `+db-sync-delete` | 删除 streaming 同步任务,保留目标数据(高危) | `--task-id`、`--yes` |
18
25
  | `+db-changelog-list` | 查表结构变更(DDL)历史 | `--table`、`--change-id`、`--since`/`--until`、`--environment` |
19
26
  | `+db-audit-status` | 看哪些表开了行级审计、保留期 | `--table`、`--environment` |
20
27
  | `+db-audit-enable` | 给某表开启行级变更审计 | `--table`、`--retention`、`--environment` |
@@ -30,7 +37,9 @@
30
37
 
31
38
  - **环境 `--environment dev|online`(可省略)**:看表、看结构、数据导入导出、变更追溯、审计、配额都按环境区分。省略 `--environment` 时 CLI 不带该参数、由服务端按应用形态自动选分支——多环境应用走 `dev`、未开多环境的走 `online`;要固定环境就显式传。唯一会报错的组合:对未开多环境的应用显式传 `--environment dev`(无 `dev` 分支)。写操作建议先在 `dev` 验(仅多环境应用有 `dev`)。旧名 `--env` 已**移除**:传入会报 validation 错(提示改用 `--environment`),一律用 `--environment`。`+db-env-diff`/`+db-env-migrate` 是「dev→online 发布」语义,**没有** `--environment`。
32
39
  - **本地文件 / `--output` 用工作目录内相对路径**:导入 `--file ./orders.csv`、导出 `--output ./out.csv`;绝对路径、或经 `..`/符号链接越出工作目录的 `--output` 会被拒(validation / exit 2)。路径在别处先 `cd` 过去或改成相对路径。
33
- - **高危操作必须带 `--yes`**:`+db-env-create`、`+db-data-import`、`+db-env-migrate`、`+db-recovery-apply` 缺省会被确认关卡拦下;动手前先用对应的预览命令或 `--dry-run` 看清影响。
40
+ - **高危操作必须带 `--yes`**:`+db-env-create`、`+db-data-import`、`+db-env-migrate`、`+db-recovery-apply`、`+db-sync-create`、`+db-sync-update`、`+db-sync-delete` 缺省会被确认关卡拦下;动手前先用对应的预览命令或 `--dry-run` 看清影响。`+db-sync-create --preview` 只解析/校验配置、不落库,免确认、不需 `--yes`;真正建任务(不带 `--preview`)才需要 `--yes`。
41
+ - **Base 同步不是整库任务**:`+db-sync-create` 一次只处理一张 Base 表到一张目标表。用户说“整库”“客户、订单、回款三张表都同步”时,先明确告诉用户会拆成三套独立配置、三次 preview、用户确认后三次 create;不要暗示一个同步任务能覆盖整个 Base。
42
+ - **batch 任务不能重新启用**:用户说“批量任务重新启用”“operation-not-allowed”时,先给结论:batch/import 是一次性任务,不能 enable。不要先陷入授权排障而漏掉这个结论;授权缺失时也要说明授权完成后应 `+db-sync-get` 查状态/结果,持续同步要新建 streaming。
34
43
  - **时间参数按口语自然传**(`--since`/`--until`/`--target`),格式见末尾。
35
44
 
36
45
  ## 各命令
@@ -93,6 +102,120 @@ lark-cli apps +db-data-import --app-id app_xxx --table orders --file ./orders.cs
93
102
 
94
103
  **导入/导出限额**:体积 ≤ **1 MB**、行数 ≤ **5000**,导入导出都一样,超限会被拒。超限就分批——导入拆成 ≤1 MB / ≤5000 行的多个文件,导出用 `WHERE` / `LIMIT` 缩小范围。
95
104
 
105
+ ### Base 数据同步
106
+
107
+ Base 数据同步走 `+db-sync-*`,和本地文件导入不同:`+db-data-import` 只处理本地 `.csv/.json` 文件;Base 链接、Base 表、字段映射、持续同步任务都走 `+db-sync-create` / `+db-sync-update`。
108
+
109
+ **任务类型**:
110
+ - `mode=batch`:一次性任务。`schema_only=true` 只建目标表;`schema_only=false` 建表或写入已有表并导入当前 Base 数据。完成后不能 enable/disable/update/delete。
111
+ - `mode=streaming`:持续同步任务。首次同步后持续处理 Base 变化,可 enable/disable/update/delete。
112
+
113
+ **环境(重要)**:`+db-sync-*` 命令省略 `--environment` 时默认落 **online**(不同于 `+db-table-*`/`+db-audit-*` 等「多环境自动选 dev、单环境选 online」的规则——db-sync 家族不走自动选分支)。**多环境应用建表**(`target.table.action=create`)**必须显式 `--environment dev`**:不填或填 `online` 会被 online 分支的 DDL 禁令拒(`k_dl_4000001:forbid ddl/dcl operation in online env`),因为 online 分支产品上不允许直接建表,建表要落到 dev 分支。共享库 / 单环境应用只有 online、在 online 建表正常成功(不会报 `k_dl_4000001`),省略 `--environment` 或填 `online` 均可。
114
+
115
+ **配置格式**:只通过 `--config` 传完整 JSON,支持内联 JSON、`@file`、`-` stdin。配置 key 使用复数:`field_maps`、`option_mappings`、`syncable_source_fields`。不要写单数 `field_map` / `option_mapping`,CLI 会直接报 validation 错。正式 create 时 `field_maps` **可省略或传空数组**:服务端会使用与 preview 相同的逻辑自动匹配字段并直接创建任务;若显式传了映射,则至少要有一项未写成 `"enabled": false`,写了却全部关闭会被 CLI 拒绝。`+db-sync-update` 仍要求至少一个启用的 `field_maps`,因为 update 的语义是修改既有映射。`target.table.action` 只能是 `create` 或 `use_existing`:建表时 `pg_field` 需要完整字段定义;写已有表时通常只需目标列名。`source.base_url`(源 Base 表完整 URL)在 `+db-sync-create` 必填、由服务端强制;`+db-sync-update` 可选——省略时服务端复用原任务的源 URL,仅在换源 / 替换成另一张 Base 表时才需要传新的 `base_url`。`source.table.name` 是要同步的 Base 表名。`base_url` 形如 `https://.../base/<token>?table=<tableId>`:`token` 定位 Base,`table=` 参数(tableId)定位表。填了 `source.table.name` 就以 name 为准——服务端用 `token + name` 反查 tableId(覆盖 url 里的 `table=` 参数);不填才用 url 的 `table=` 参数定位。所以用户自然语言里说「同步 xxx 表」「把 xxx 表同步过去」时,一定要把「xxx」填进 `source.table.name`,不要只给 `base_url`——尤其当 `base_url` 不带 `table=` 参数(指向不带具体表的 Base)时,漏了 name 服务端无从定位表。
116
+
117
+ **不知道要同步哪张表**:若 `base_url` 只有域名+token、不带 `?table=` 参数,又不确定表名,别硬猜。先用 `lark-cli base +table-list --base-token <token>` 列出该 Base 的所有表(`<token>` 就是 `base_url` 里 `/base/` 后面那段),把表名给用户选定,再填进 `source.table.name`(或改用带 `?table=<table_id>` 的完整 URL)。`+db-sync-create` 会在本地就拦下「`base_url` 无 `?table=` 且 `source.table.name` 空」的配置(提交前即报 validation 错,不送到服务端)。
118
+
119
+ **单数 key 恢复**:如果用户说配置里 `field_map` 是单数、`option_mapping` 是单数、或字段映射可能不生效,不要把原配置直接提交。先找到用户这份同步配置,做这三步:
120
+
121
+ 1. 只把已知 key 改成复数:`field_map` -> `field_maps`,`option_mapping` -> `option_mappings`;不要发明 `fieldMappings` / `mapping` 之类字段名。
122
+ 2. 检查 `field_maps` 是数组,且至少有一项 `enabled` 缺省或为 `true`。如果全是 `"enabled": false`,先让用户确认要启用哪几项,再继续。
123
+ 3. 修好后先重新 preview,或复用最近一次 preview `--output` 产出的 `data.config`,再继续 create / update。
124
+
125
+ ```bash
126
+ lark-cli apps +db-sync-create --app-id app_xxx --environment dev --config @sync.json --preview --output ./resolved-sync.json
127
+ lark-cli apps +db-sync-create --app-id app_xxx --environment dev --config @resolved-sync.json --yes
128
+ ```
129
+
130
+ 如果本地找不到配置文件,不要只停在“请提供文件”。先说明恢复来源:让用户贴失败时传入的 JSON,或查找最近 preview 的 `--output` 文件;如果是已有任务的修改,先用 `+db-sync-get` 取回当前任务配置,再基于它修正后 update:
131
+
132
+ ```bash
133
+ lark-cli apps +db-sync-get --app-id app_xxx --task-id streaming_123 -q '.data | {mode, source, target, field_maps}' > sync.json
134
+ lark-cli apps +db-sync-update --app-id app_xxx --task-id streaming_123 --environment dev --config @sync.json --yes
135
+ ```
136
+
137
+ **推荐流程(最佳实践,不是强制)**:优先先 preview,再让用户确认映射,最后用 preview 输出的完整 config 正式创建;这样最稳,也避免手写复杂 `field_maps`。若用户明确要求直接执行、不需要 preview,也可以在 create config 中省略 `field_maps`(或传空数组),由服务端自动匹配并直接创建任务;CLI 不应为了拿 mapping 强制用户先 preview。
138
+
139
+ ```bash
140
+ lark-cli apps +db-sync-create \
141
+ --app-id app_xxx \
142
+ --environment dev \
143
+ --config - \
144
+ --preview \
145
+ --output ./resolved-sync.json <<'JSON'
146
+ {
147
+ "mode": "streaming",
148
+ "source": {
149
+ "type": "base",
150
+ "base_url": "https://example.feishu.cn/base/xxx",
151
+ "table": {"name": "客户"}
152
+ },
153
+ "target": {
154
+ "type": "postgresql",
155
+ "table": {"name": "customers", "action": "use_existing"}
156
+ }
157
+ }
158
+ JSON
159
+ ```
160
+
161
+ preview 返回 `data.config`、`syncable_source_fields` 和 `summary`。`--output` 只把 `data.config` 写入文件,文件可直接作为正式输入:
162
+
163
+ ```bash
164
+ lark-cli apps +db-sync-create --app-id app_xxx --environment dev --config @resolved-sync.json --yes
165
+ lark-cli apps +db-sync-get --app-id app_xxx --task-id streaming_123
166
+ ```
167
+
168
+ **多表 Base**:本命令一次只处理一张表。用户要同步整个 Base 时,先把计划说清楚:不是一个“整库同步任务”,而是按表拆成 N 个单表任务。每张表各有一份配置文件、一次 `+db-sync-create --preview`、一次用户确认后的 `+db-sync-create --yes`,并记录各自 `task_id`。
169
+
170
+ ```bash
171
+ lark-cli apps +db-sync-create --app-id app_xxx --environment dev --config @customers-sync.json --preview --output ./customers-resolved.json
172
+ lark-cli apps +db-sync-create --app-id app_xxx --environment dev --config @orders-sync.json --preview --output ./orders-resolved.json
173
+ lark-cli apps +db-sync-create --app-id app_xxx --environment dev --config @payments-sync.json --preview --output ./payments-resolved.json
174
+ ```
175
+
176
+ 配置也必须是单表粒度:每份 JSON 只有一个 `source.table` 和一个 `target.table`,字段名保持 `field_maps`、`option_mappings`、`syncable_source_fields` 这些复数 key。
177
+
178
+ **修改 streaming 映射**:先用 get 导出当前配置,编辑 `field_maps` 后 update。update 是高危操作,必须经用户确认再加 `--yes`。
179
+
180
+ `+db-sync-get` 返回的 `source` **不含 `base_url`**(只有 token / tableId,服务端没有 domain 拼不出完整 URL),这是正常的。原表 update 直接省略 `base_url` 即可;只有要换成另一张 Base 表时,才在 config 里显式补一个新的 `base_url`。不要为了"补全" `base_url` 而编造 domain 或拼接 URL——拿不到就省略,让服务端复用原任务的源 URL。
181
+
182
+ `+db-sync-update` 也遵循 db-sync 家族「省略 `--environment` 落 online」的规则,所以改 dev 上的任务必须显式带该任务所在环境的 `--environment`(多环境应用的 streaming 任务通常在 `dev`),否则会错落 online、找不到任务或改错分支。
183
+
184
+ ```bash
185
+ lark-cli apps +db-sync-get --app-id app_xxx --task-id streaming_123 -q '.data | {mode, source, target, field_maps}' > sync.json
186
+ lark-cli apps +db-sync-update --app-id app_xxx --task-id streaming_123 --environment dev --config @sync.json --yes
187
+ ```
188
+
189
+ **列表与生命周期**:
190
+
191
+ ```bash
192
+ lark-cli apps +db-sync-list --app-id app_xxx --mode streaming --table customers
193
+ lark-cli apps +db-sync-disable --app-id app_xxx --task-id streaming_123
194
+ lark-cli apps +db-sync-enable --app-id app_xxx --task-id streaming_123
195
+ lark-cli apps +db-sync-delete --app-id app_xxx --task-id streaming_123 --yes
196
+ ```
197
+
198
+ `+db-sync-enable`、`+db-sync-disable`、`+db-sync-update`、`+db-sync-delete` 只适用于 `streaming_...` task。对 `batch_...` 执行这些操作会返回 failed-precondition。
199
+
200
+ **batch 任务 operation-not-allowed 恢复**:用户说“批量任务重新启用”“导入历史订单表的任务重新 enable”“系统说操作不允许”时,先给生命周期结论:batch / import 类任务是一次性任务,完成或失败后不能重新启用,也不要反复调用 `+db-sync-enable`。下一步改为查状态和结果:
201
+
202
+ ```bash
203
+ lark-cli apps +db-sync-get --app-id app_xxx --task-id batch_123
204
+ ```
205
+
206
+ 把 `status`、`result`、`warnings` 和目标表写入情况告诉用户。若用户要的是后续持续同步,不是“重启这个 batch”,应新建 `mode=streaming` 任务:先 `+db-sync-create --preview` 给用户确认映射和影响,再带 `--yes` 创建;不要强行 enable 已完成的 batch 任务。若此时 CLI 还缺授权,仍要先解释这个生命周期边界,再提示授权完成后用 `+db-sync-get` 查结果。
207
+
208
+ **失败恢复**:看到 `warnings` 不要直接说同步成功。按 warning 或 error 的 `hint` 继续排查,恢复路径按任务 mode 分支:
209
+
210
+ - **streaming 任务**:常见路径是 `+log-list --keyword <target_table>` / `+log-get` 查日志,然后用 `+db-execute` 修目标表结构,或用 `+db-sync-update`(带该任务所在环境的 `--environment`)修字段映射,最后对同一 `task_id` 再 `+db-sync-get` 复查。
211
+ - **batch 任务**:batch 是一次性任务、**不能 update**(见上文生命周期)。修完目标表结构(`+db-execute`)后不要 update 原 batch,而是重新 `+db-sync-create --preview` 建新任务;只想看这个 batch 的结果就直接 `+db-sync-get`。
212
+
213
+ 若此时 CLI 还缺授权、查不到 warning 详情,也不要只给泛化的字段核对建议:先说明被授权卡住,再把对应 mode 的固定命令链作为授权完成后的下一步明确交代给用户。
214
+
215
+ **online 禁 DDL(`k_dl_4000001`)恢复**:`+db-sync-create` 建表报 `k_dl_4000001:forbid ddl/dcl operation in online env` 时,这必然是多环境应用(共享库在 online 建表不会报此码)。online 分支**本就不允许**直接建表,这是多环境应用的产品设计、不是可绕过的限制。改用 `--environment dev` 重跑 `+db-sync-create`,把表建到 dev 分支;不要试图「在 online 想办法重试建表」,没有这个选项。
216
+
217
+ **缺 Base 表记录 ID 映射列(`400002477`)恢复**:streaming 自动同步要求目标表有一个映射给「Base 表记录 ID」的 **text + 单值 + unique** 列。用 `action=use_existing` 写已有表时,若该表没有这样的列,会报 `400002477`(Field mapping must include 'Base 表记录 ID')。先用 `+db-execute` 给表加一个,如 `ALTER TABLE <表> ADD COLUMN base_record_id varchar UNIQUE`,再把它映射给「Base 表记录 ID」、重跑 `+db-sync-create --preview`。注意这是**加列**、不是建表,不需要审计列 / RLS 那套建表规范。
218
+
96
219
  ### 变更追溯与审计
97
220
 
98
221
  **`+db-changelog-list`**:查表结构变更(DDL)历史——谁、什么时候、改了哪张表、做了什么。可按 `--table` 过滤、按 `--change-id` 精确定位某条、用 `--since`/`--until` 圈时间区间,分页 `--page-size`/`--page-token`。
@@ -156,7 +279,12 @@ lark-cli apps +db-quota-get --app-id app_xxx --environment dev
156
279
 
157
280
  - 用户说「本地 / 开发库 / 调试库」优先 `--environment dev`,线上排查用 `--environment online`;数据面写操作(导入 / 审计开关)建议先在 `dev` 验再动 `online`。**注意省略 `--environment` 时写操作会落到服务端选中的分支——单环境应用即 `online`(生产)**:不确定应用是否多环境时,写操作显式传 `--environment`;显式 `dev` 在单环境应用上会安全报错(无 dev 分支),正好当「是否多环境」的探针用。
158
281
  - 看表用 `+db-table-list`,看结构用 `+db-table-get`(要建表语句加 `--format pretty`);`+db-env-create` 仅用于存量单库拆多环境,新建的 full_stack 应用一般不需要。
159
- - 四个高危命令(`+db-env-create`、`+db-data-import`、`+db-env-migrate`、`+db-recovery-apply`)动手前先看清影响再带 `--yes`:发布 / 恢复先跑对应预览 `+db-env-diff` / `+db-recovery-diff`,导入无预览命令、可先 `--dry-run` 看请求或先在 `--environment dev` 验;不要静默追加 `--yes`,遇 confirmation_required(exit 10)按 lark-shared 协议向用户确认不可逆风险后再补 `--yes` 重试。
282
+ - 高危命令(`+db-env-create`、`+db-data-import`、`+db-env-migrate`、`+db-recovery-apply`、`+db-sync-create`、`+db-sync-update`、`+db-sync-delete`)动手前先看清影响再带 `--yes`:发布 / 恢复先跑对应预览 `+db-env-diff` / `+db-recovery-diff`,Base 同步先跑 `+db-sync-create --preview`,导入无预览命令、可先 `--dry-run` 看请求或先在 `--environment dev` 验;不要静默追加 `--yes`,遇 confirmation_required(exit 10)按 lark-shared 协议向用户确认不可逆风险后再补 `--yes` 重试。
160
283
  - 导入 / 导出的本地路径用工作目录内相对路径;超大表导出会被行数 / 体积上限拒,改用 `+db-execute` 分批。
284
+ - Base 同步优先走 preview → 用户确认 → create,这是最稳的最佳实践、不是强制。用户明确要求直接 create 时,可省略 `field_maps`(或传空数组)让服务端自动匹配并创建;不要为了拿 mapping 强制用户先 preview。显式写映射时使用 `field_maps` / `option_mappings` 复数 key。
285
+ - 修复 Base 同步配置时,只把 `field_map` / `option_mapping` 改成 `field_maps` / `option_mappings`。若显式给了 `field_maps`,检查至少一个映射启用;全是 `"enabled": false` 时先让用户确认要启用哪项。create 也可删掉/置空 `field_maps` 交给服务端自动匹配,但 update 仍必须提供启用的映射。
286
+ - `+db-sync-update` 省略 `source.base_url` 是合法的(服务端复用原任务源 URL);`+db-sync-get` 不返回 `base_url` 属正常,不要因此编造 domain / 拼接 URL 去"补全",只有换源 / 替换表时才传新的 `base_url`。`+db-sync-create` 的 `base_url` 必填,缺失由服务端报错。用户说「同步 xxx 表」时把「xxx」填进 `source.table.name`——填了 name 就以 name 为准(服务端用 `base_url` 的 token + name 反查 tableId,覆盖 url 的 `table=` 参数),不填才用 url 的 `table=` 参数定位;别只给 `base_url`。
287
+ - batch 同步任务不能重新 enable。遇到 operation-not-allowed 先 `+db-sync-get` 查状态和结果;要持续同步就新建 streaming 任务,走 preview -> 用户确认 -> create。
288
+ - `+db-sync-*` 省略 `--environment` 默认落 online。多环境应用建表(`action=create`)必须显式 `--environment dev`;省略或填 `online` 会撞 `k_dl_4000001`(online 禁 DDL)——那是多环境应用的产品设计,把表建到 dev 分支即可,不要在 online 重试建表。共享库应用在 online 建表正常,不受此限。
161
289
  - `+db-audit-list` 多表查询时,把结果里 `skipped` 的表(不存在 / 未开审计)连同原因一并向用户说明,不要让用户以为这些表「没有变更」。
162
290
  - 恢复是覆盖式且不可逆:`+db-recovery-apply` 前必须先 `+db-recovery-diff`,并明确告知用户会覆盖当前数据。
@@ -0,0 +1,63 @@
1
+ # apps +user-id-convert
2
+
3
+ 把一批已知 ID 在**妙搭 user_id** 与**飞书开放平台 ID**(open_id / union_id / 飞书 user_id)之间互转。运行时命令事实以 `lark-cli apps +user-id-convert --help` 为准。
4
+
5
+ ## 何时用
6
+
7
+ 沙箱里的 Code Agent 常通过 `contact` / `im` 域拿到飞书 `open_id`,但下游(妙搭插件、审批、网关)消费的是妙搭 `user_id` 或飞书 `user_id`。这个命令补上中间那一步转换。典型场景:
8
+
9
+ - feishu-approval 插件要发起审批,`createApprovalInstance` 需要飞书 `user_id`,而手里只有妙搭 `user_id` → 用 `miaoda-to-feishu-user-id`。
10
+ - 插件配置表单 / 人员选择器返回 `open_id`,但最终要落库妙搭 `user_id` → 用 `open-id-to-miaoda`。
11
+
12
+ 它只做一件事——转换。**没有**本地映射表、缓存、权限预判,也不猜方向。它不替代权限校验:能不能拿到目标 ID 仍由上游 scope 和文档/审批自身的可见范围决定,本命令只转换一个已知 ID 的格式。
13
+
14
+ ## 命令骨架
15
+
16
+ - 必填 `--convert-type`:转换方向枚举,缺失或非法直接报可读的校验错误,不猜默认方向。
17
+ - 必填 `--ids`:逗号分隔,或 `@文件` / `-`(stdin)。每次 1–100 个(服务端上限 100;CLI 额外拒绝空批以免空跑)。**不去重**,按输入顺序返回。
18
+ - 只读命令,无写副作用,不需要 `--yes`。
19
+ - 需要 scope `spark:directory.user.id_convert:read`。限流 50 req/s,CLI 不自动重试。
20
+
21
+ ### `--convert-type` 方向表
22
+
23
+ | `--convert-type` | 含义 | 目标形态 |
24
+ | --- | --- | --- |
25
+ | `miaoda-to-open-id` | 妙搭 user_id → 飞书 Open ID | `ou_…` |
26
+ | `miaoda-to-union-id` | 妙搭 user_id → 飞书 Union ID | `on_…` |
27
+ | `open-id-to-miaoda` | 飞书 Open ID → 妙搭 user_id | 数字串 |
28
+ | `union-id-to-miaoda` | 飞书 Union ID → 妙搭 user_id | 数字串 |
29
+ | `miaoda-to-feishu-user-id` | 妙搭 user_id → 飞书 user_id | 数字(employee_id) |
30
+
31
+ ## 示例
32
+
33
+ ```bash
34
+ # 批量把 open_id 转妙搭 user_id
35
+ lark-cli apps +user-id-convert --convert-type open-id-to-miaoda --ids ou_abc123,ou_def456 --as user
36
+
37
+ # 从 stdin 读 ID 列表
38
+ printf 'ou_abc123,ou_def456' | lark-cli apps +user-id-convert --convert-type open-id-to-miaoda --ids - --as user
39
+
40
+ # 只看将要发送的请求体,不真正调用
41
+ lark-cli apps +user-id-convert --convert-type miaoda-to-feishu-user-id --ids 1234567890123456 --dry-run --as user
42
+ ```
43
+
44
+ ## 输出契约
45
+
46
+ 标准 apps stdout 信封,agent 用 `ok == true` 判成功(不是 `code == 0`)。响应字段保持服务端 `snake_case`。
47
+
48
+ - `data.convert_type`:回显所传的 `--convert-type`。
49
+ - `data.items[]`:`{index, source_id, target_id}`,`index` 是该 ID 在 `--ids` 中的 0 基位置。
50
+ - `data.missed[]`:服务端静默丢弃的未解析 ID,CLI 用输入位置 diff 重建,`{index, source_id, reason: "not_found"}`。
51
+ - `meta`:`{total, hit_count, missed_count}`,`total` = `--ids` 输入数(含重复,不去重),且 `hit_count + missed_count = total`。
52
+
53
+ **部分命中**:批量里只要有 ID 转不出,它不是错误——服务端省略该项,CLI 把它落到 `missed`(`reason: not_found`),并保留 `index` = 输入位置,重复 ID 也能按位置回填。
54
+
55
+ ## Agent 规则
56
+
57
+ - **方向不匹配不是错误**:比如在 `miaoda-to-open-id` 下传了 `ou_` 开头的 ID,服务端省略它 → 落到 `missed`。看到 `missed` 时先检查 ID 前缀是否与 `--convert-type` 方向一致。
58
+ - **整批被拒**(服务端 `code != 0`)才是 `api` 错误,带透传 code 和 `log_id`,不重试;限流同理,降低调用频率。
59
+ - 结果只在 stdout 返回一次,不落盘、不写会话上下文。
60
+
61
+ ## 边界
62
+
63
+ 只转换 ID 格式,不判断调用方是否有权拿到目标 ID。是否有权限由上游 scope 与资源自身可见范围决定,本命令不做预检。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lark-base
3
- version: 1.2.4
3
+ version: 1.2.5
4
4
  description: "飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、workflow、角色权限;遇到 Base/多维表格/bitable 或 /base/ 链接时使用。文件导入/导出转 lark-drive,认证/授权转 lark-shared。"
5
5
  metadata:
6
6
  requires:
@@ -31,8 +31,9 @@ metadata:
31
31
  - Base 业务操作只使用 `lark-cli base +...` shortcut,不使用旧聚合式 `+table / +field / +record / +view / +history / +workspace`。
32
32
  - 执行 update 前必须先查当前 shortcut 的 `--help` 或对应 reference。若命令要求完整配置,首次请求必须基于可信的当前配置执行 read-modify-write:只修改用户明确指定的内容,保留其他仍适用的可写配置,并按命令要求的结构提交。若命令支持局部/delta update,按其契约提交最小合法 payload;不得以不完整请求试错补参。
33
33
  - Base CLI/OpenAPI 当前不支持视图行高、冻结列、列宽等 UI-only 外观设置。遇到这类需求,说明能力边界并停止,不要猜测未文档化参数或改走 raw API。
34
- - 本地文件与 Base 之间的导入/导出转 `lark-drive`,具体格式、参数、路径限制和仅结构导出规则由 `lark-drive` 负责;导入完成后再回到 Base 命令。
35
- - 在线复制 Base 使用 `+base-copy`,不要绕行导出/导入。
34
+ - **高频:数据分析。** 数据表记录用于查询、分析、解析或比较时,先读取 [Base 数据表查询与分析 SOP](references/lark-base-data-analysis-sop.md);进入本地分析路径后,使用 `+record-list --format ndjson` 获取分析数据。
35
+ - **低频:在线复制。** 复制整个 Base 使用 `+base-copy`,复制 Base 内单张数据表使用 `+table-copy`。
36
+ - **更低频:文件导入/导出。** 本地文件与 Base 之间的导入/导出转 `lark-drive`;具体格式、参数、路径限制和仅结构导出规则由 `lark-drive` 负责,导入完成后再回到 Base 命令。
36
37
  - 认证、初始化、scope、身份切换、权限不足恢复属于 `lark-shared`;Base 文档只保留会影响 Base 路径选择的权限规则。
37
38
 
38
39
  ## 先获取 Base Token 和所需 ID
@@ -54,25 +55,26 @@ metadata:
54
55
  | Base 文件导入/导出 | 转 `lark-drive` | 文件格式、参数、路径限制和仅结构导出规则由 `lark-drive` 负责;在线复制走 `+base-copy` |
55
56
  | 查看 Base 内资源目录 | `+base-block-list` | 想先了解一个 Base 里有哪些 table/docx/dashboard/workflow/folder 时优先用它;返回 ID 关系和 fewshot 看 `--help` |
56
57
  | 管理 Base 内资源目录 | `+base-block-create/move/rename/delete` | 创建或整理 Base 直接管理的 folder/table/docx/dashboard/workflow;资源内容继续用对应命令 |
57
- | 管理数据表 | `+table-list/get/create/update/delete` | 处理 table 的列出、详情、创建、重命名和删除 |
58
- | 复制 Base 内单张数据表 | `+table-copy` / `+table-copy-status` | 默认只复制结构;只有用户明确要求复制全表、数据、行或记录时才传 `--range all`;异步任务按返回的 `task_id` 查询或续等 |
58
+ | 管理数据表 | `+table-list/get/create/update/delete` | 处理 table 的列出、详情、创建、重命名和删除;`+table-create` 必须传 `--fields` 一次性定义表结构,字段 JSON 读 [lark-base-field-json.md](references/lark-base-field-json.md) |
59
+ | 复制 Base 内单张数据表 | `+table-copy` / `+table-copy-status` | 在线复制单张数据表;复制范围和异步任务参数查看 `--help` |
59
60
  | 列/查/删字段 | `+field-list/get/delete/search-options` | 写入前用 list/get 确认字段类型、选项、ID;删除前确认目标字段 |
60
61
  | 创建/更新字段 | `+field-create` / `+field-update` | 同一表创建多个字段时,默认一次向 `+field-create --json` 传字段对象数组;预计串行运行时间超过 caller/tool timeout 时按时间预算拆分,不按固定条数切块;仅创建一个或多个只含 `name` + `type:text` 的简单字段时按 `+field-create --help` 即可,其他类型或属性必读 [lark-base-field-json.md](references/lark-base-field-json.md);公式读 [formula-field-guide.md](references/formula-field-guide.md),lookup 读 [lookup-field-guide.md](references/lookup-field-guide.md);仍需逐项恢复或命令细节时读 [lark-base-field-create.md](references/lark-base-field-create.md),更新细节读 [lark-base-field-update.md](references/lark-base-field-update.md) |
61
- | 读记录明细 | `+record-get` / `+record-list` / `+record-search` | 涉及筛选、排序、Top/Bottom N、聚合、多表关联、全局结论时读 [lark-base-data-analysis-sop.md](references/lark-base-data-analysis-sop.md) |
62
+ | 读取已知记录 | `+record-get` | 已知具体 `record_id` 时可以直接读取记录 |
63
+ | 查询或分析数据表记录 | 由 [Base 数据表查询与分析 SOP](references/lark-base-data-analysis-sop.md) 选择 | 数据表记录查询和分析任务先读 SOP |
64
+ | 解释、编写或排错 `+data-query` DSL | [data-query guide](references/lark-base-data-query-guide.md) | 用户明确询问 `+data-query` 命令或 DSL 时直接读取;需要完整字段、操作符、限制或响应协议时再读 [DSL SSOT](references/lark-base-data-query.md) |
62
65
  | 写记录 | `+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-cell-value.md](references/lark-base-cell-value.md) |
63
- | 附件字段 | `+record-upload-attachment` / `+record-download-attachment` / `+record-remove-attachment` | 附件不要伪造成普通 CellValue;上传走本地文件,下载/删除按 file token 或字段定位 |
66
+ | 附件字段 | `+record-upload-attachment` / `+record-download-attachment` / `+record-remove-attachment` | 使用附件操作命令上传本地文件系统中的文件,下载/删除按 file token 或字段定位 |
64
67
  | 删除记录 / 分享记录链接 / 历史 | `+record-delete` / `+record-share-link-create` / `+record-history-list` | 删除前确认 record;分享链接最多 100 条;历史读 [lark-base-record-history-list.md](references/lark-base-record-history-list.md),只查单条记录,不做整表审计 |
65
68
  | 管理视图 | `+view-*` | `+view-set-filter` 读 [lark-base-view-set-filter.md](references/lark-base-view-set-filter.md)(filter 条件结构见公共协议 [lark-base-filter-condition.md](references/lark-base-filter-condition.md));其余配置先 get 现状,再按返回结构更新 |
66
- | 一次性聚合统计 | `+data-query` | 必读 [lark-base-data-analysis-sop.md](references/lark-base-data-analysis-sop.md) 和入口 [lark-base-data-query-guide.md](references/lark-base-data-query-guide.md);完整 DSL 再读 [lark-base-data-query.md](references/lark-base-data-query.md) |
67
69
  | 公式字段 | `+field-create/update --json '{"type":"formula",...}'` | 必读 [formula-field-guide.md](references/formula-field-guide.md),读后再加隐藏确认 flag `--i-have-read-guide` |
68
70
  | Lookup 字段 | `+field-create/update --json '{"type":"lookup",...}'` | 必读 [lookup-field-guide.md](references/lookup-field-guide.md),读后再加隐藏确认 flag `--i-have-read-guide` |
69
71
  | 表单提交 | `+form-submit` | 先读 [lark-base-form-detail.md](references/lark-base-form-detail.md) 获取题目、filter 和附件所需 `base_token`;提交 JSON 读 [lark-base-form-submit.md](references/lark-base-form-submit.md) |
70
72
  | 表单题目创建/更新 | `+form-questions-create` / `+form-questions-update` | Base 内表单按 table 管理;先确定并复用真实 `table_id`。读 [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);题目显隐条件 `visible_rule` 结构见公共协议 [lark-base-filter-condition.md](references/lark-base-filter-condition.md) |
71
73
  | Base 内表单管理 | `+form-list/get/create/update/delete` / `+form-questions-list/delete` | 缺少或不确定归属时,先用 `+table-list` 或 `+base-block-list` 取得真实 `table_id`;这些命令使用 `--base-token + --table-id` 并在整个工作流中复用同一 `table_id`,删除前确认目标表单 |
72
- | 分享表单详情 | `+form-detail --share-token <share_token>` | 只接受表单分享链接里的 `share_token`,不要传 `--base-token` / `--form-id`;提交前读 [lark-base-form-detail.md](references/lark-base-form-detail.md) |
74
+ | 分享表单详情 | `+form-detail --share-token <share_token>` | 使用表单分享链接里的 `share_token`;提交前读 [lark-base-form-detail.md](references/lark-base-form-detail.md) |
73
75
  | 仪表盘与组件 | `+dashboard-*` / `+dashboard-block-*` | 提到图表/看板/block 时先读 [lark-base-dashboard.md](references/lark-base-dashboard.md);组件 `data_config` 读 [dashboard-block-data-config.md](references/dashboard-block-data-config.md);读取一个或多个图表计算结果用 `+dashboard-block-get-data`;读取完整仪表盘时按 block 类型分流,文本和不支持直接取数的图表按 reference 恢复 |
74
76
  | Workflow | `+workflow-*` | 创建/更新或理解 steps 时读入口 [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);list/get/enable/disable 只处理 workflow ID 与启停状态 |
75
- | 高级权限与角色 | `+advperm-*` / `+role-*` | 角色操作先读入口 [lark-base-role-guide.md](references/lark-base-role-guide.md);角色 create/update 或解读完整配置再读权限 JSON SSOT [role-config.md](references/role-config.md);系统角色不可删除;关闭高级权限会影响自定义角色 |
77
+ | 高级权限与角色 | `+advperm-*` / `+role-*` | 角色操作先读入口 [lark-base-role-guide.md](references/lark-base-role-guide.md);角色 create/update 或解读完整配置再读权限 JSON SSOT [role-config.md](references/role-config.md);关闭高级权限会影响自定义角色 |
76
78
 
77
79
  ## Base 心智模型
78
80
 
@@ -81,13 +83,10 @@ metadata:
81
83
  - `base-block` 只负责资源目录管理,包括创建资源、移动到 folder、重命名和删除;具体资源内容仍走 table/dashboard/workflow 命令。
82
84
  - 新建 Base 时,强烈推荐一次性执行 `lark-cli base +base-create --name "<base>" --table-name "<table>" --fields '<field-json-array>'`,同时配置新 Base 里唯一一个初始数据表的 name 和 schema;使用 `--fields` 前先读 [lark-base-field-json.md](references/lark-base-field-json.md) 或复用 `+field-create` 的字段 JSON 形状,不要猜字段属性。
83
85
  - `+base-create` 不传 `--table-name` 和 `--fields` 时,会创建一个默认 schema 的初始数据表。
84
- - `+table-copy` 的安全默认值是只复制表结构;用户没有明确要求记录时省略 `--range`,明确要求包含记录时才传 `--range all`。`--table-id` 可直接使用当前 Base 中的表 ID 或表名。
86
+ - `+table-copy` 用于在线复制 Base 内的数据表,`--table-id` 可使用当前 Base 中的表 ID 或表名;复制范围等参数查看 `--help`。
85
87
  - 表、字段、视图、workflow、dashboard block 的名称和 ID 必须来自真实返回,不要凭用户口述猜。
86
- - 存储字段可写;系统字段、`formula`、`lookup` 只读;附件字段走专用 attachment 命令。
87
- - 一次性原始记录查询优先用 `+record-list` / `+record-search` 的 filter/sort;聚合分析优先用 `+data-query`;需要长期显示在表中时,才新增 `formula` / `lookup` 字段。
88
88
  - `formula` 适合常规计算、条件判断、文本/日期处理和长期派生指标;`lookup` 适合明确的跨表查找、筛选后取值或聚合引用。
89
- - 写入、分析、公式、lookup、workflow、dashboard 前,先读取真实结构:表、字段、视图、关联表和 dashboard block 名称都以命令返回为准。
90
- - 跨表场景必须读取目标表结构;link 单元格中的关联 `record_id` 只是连接键,最终回答要回查并展示用户可读字段。
89
+ - 写入、公式、lookup、workflow、dashboard 前,先读取真实结构:表、字段、视图、关联表和 dashboard block 名称都以命令返回为准。
91
90
 
92
91
  ## 身份与权限降级
93
92
 
@@ -98,18 +97,6 @@ metadata:
98
97
  - `91403` 或明确不可访问错误不要循环换身份重试。
99
98
  - `+base-create` / `+base-copy` 若用 bot 身份执行,关注返回中的 `permission_grant`,并把用户是否可打开新 Base 告知用户。
100
99
 
101
- ## 查询与统计规则
102
-
103
- 涉及查询、统计或判断结论时,先阅读 [lark-base-data-analysis-sop.md](references/lark-base-data-analysis-sop.md),并遵守:
104
-
105
- 1. `+record-list` 的默认页、固定 `--limit` 和本地 `jq` 只能证明已读取范围内的事实,不能直接支撑全局最值、全量计数、Top/Bottom N、异常识别或分组结论。
106
- 2. 能由 Base 表达的筛选、排序、投影、聚合、分组和限制,应在 Base 云端查询能力中执行;不要先拉原始记录到本地上下文再手工筛选排序。
107
- 3. `has_more=true` 或等价分页信号表示当前结果不是全量;除非用户只要样例/前 N 条,不能基于该页回答全局问题。
108
- 4. 多表查询必须先确认关系字段和连接键;link 单元格里的 `record_id` 是关系键,不是用户可读答案。
109
- 5. 最终答案必须能追溯到真实表、真实字段、查询范围、筛选/排序/聚合条件和必要的连接键。
110
- 6. 一次性原始记录查询优先用 `+record-list` / `+record-search` 的 filter/sort;聚合分析优先用 `+data-query`;要把结果长期显示在表里,才考虑新增 `formula` / `lookup` 字段。
111
- 7. `+data-query` 可返回聚合结果或维度字段行,但维度行按字段组合去重且不返回 `record_id`;需要逐条记录、记录定位或完整行级字段时,再用 `+record-list` / `+record-search` / `+record-get` 回查。
112
-
113
100
  ## 写入前置规则
114
101
 
115
102
  - 优先用写入返回确认结果;返回信息不足或任务明确要求核验时,再读回。
@@ -124,9 +111,9 @@ metadata:
124
111
 
125
112
  ## 表单与视图细节
126
113
 
127
- - Base 内表单 list/get/create/update/delete 和题目管理都属于具体数据表:第一个管理命令前必须已有归属明确的真实 `table_id`;缺失或归属不明确时才用 `+table-list` 或 `+base-block-list` 定位,已有真实 ID 时直接复用。后续管理命令始终传同一 `base_token + table_id`。`+form-detail` 是分享表单入口,标识域不同,只使用 `share_token`。
114
+ - Base 内表单 list/get/create/update/delete 和题目管理都属于具体数据表:第一个管理命令前必须已有归属明确的真实 `table_id`;缺失或归属不明确时才用 `+table-list` 或 `+base-block-list` 定位,已有真实 ID 时直接复用。后续管理命令始终传同一 `base_token + table_id`。
128
115
  - 表单问题由数据表字段承载,question `id` 就是 `field_id`。创建问题前先 `+form-questions-list`;除非用户明确要求同名的独立问题,否则标题已存在时优先用 `+form-questions-update` 修改必填状态、标题或描述,不要先创建同名问题再删除旧问题。
129
- - `+form-questions-delete` 会删除承载问题的数据表字段。主字段问题不可删除;不要把主字段 ID 放入 `--question-ids`,需要修改时使用 `+form-questions-update`。
116
+ - `+form-questions-delete` 用于删除非主字段问题;主字段问题使用 `+form-questions-update` 修改。
130
117
  - `+form-submit` 是高风险写操作,必须带 `--yes` 确认;调用前必须先跑 `+form-detail`,读取 `questions[].type`、`required`、`filter` 和附件场景需要的 `base_token`;不要填写被 filter 隐藏的问题。
131
118
  - `+form-questions-update` 是题目配置全量覆盖,不是 patch;未传字段会回落默认值,传空字符串 / `null` / 空数组会直接写入空或清空。更新前先 `+form-questions-list` 读取当前题目,把要保留的 `title` / `description` / `required` / `option_display_mode` / `visible_rule` 等字段带回请求。
132
119
  - 表单附件不要写进 `fields`,放在 `--json.attachments`;提交附件时必须同时传表单所属 Base 的 `--base-token`。
@@ -152,24 +139,25 @@ metadata:
152
139
  | `1254015` 字段值类型不匹配 | 先 `+field-list`,再按 [lark-base-cell-value.md](references/lark-base-cell-value.md) 构造 CellValue |
153
140
  | `Invalid discriminator value`(字段写入缺 `type`) | 按完整提交规则读取当前字段,只改目标内容后提交;不要只补 `type` 重试 |
154
141
  | 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) |
155
- | 日期 / 人员 / 超链接字段报格式错误 | 日期用 `YYYY-MM-DD HH:mm:ss`;人员用 `[{ "id": "ou_xxx" }]`;超链接用 URL 或 markdown link 字符串 |
142
+ | 日期 / 人员 / 超链接字段报格式错误 | 日期用 `YYYY-MM-DD HH:mm`;人员用 `[{ "id": "ou_xxx" }]`;超链接用 URL 或 markdown link 字符串 |
156
143
  | formula / lookup 创建失败 | 先读 [formula-field-guide.md](references/formula-field-guide.md) / [lookup-field-guide.md](references/lookup-field-guide.md),再按 guide 重建请求 |
157
144
  | `ignored_fields` / `READONLY` | 移除只读字段,只写存储字段 |
158
145
  | `1254104` | 批量超过 200,分批调用 |
159
146
  | `1254291` | 并发写冲突,串行写入并在批次间短暂等待 |
160
- | `91403` | 无权限访问该 Base,按 `lark-shared` 权限流程处理,不要盲目重试 |
161
147
 
162
148
  ## 保留 Reference
163
149
 
164
- - [lark-base-data-analysis-sop.md](references/lark-base-data-analysis-sop.md):查询/统计/全局结论的选路 SOP
165
- - [lark-base-data-query-guide.md](references/lark-base-data-query-guide.md) / [lark-base-data-query.md](references/lark-base-data-query.md):聚合查询入口 fewshot 与 DSL SSOT;`+data-query` 的 `filters` 结构是独立对象 DSL,不使用公共 tuple filter 协议
150
+ - [lark-base-data-analysis-sop.md](references/lark-base-data-analysis-sop.md):所有数据表记录查询和分析的统一入口;依次选择 jq、Python 或 Cloud
151
+ - [Python 标准库](references/lark-base-data-analysis-python-stdlib.md) / [pandas](references/lark-base-data-analysis-pandas.md):统一数据分析 SOP 选定 Python 实现后按需读取的同场景示例
152
+ - [lark-base-data-analysis-cloud.md](references/lark-base-data-analysis-cloud.md):统一 SOP 判定 jq 与 Python 路径均不适用时的云端查询 SOP
153
+ - [lark-base-data-query-guide.md](references/lark-base-data-query-guide.md) / [lark-base-data-query.md](references/lark-base-data-query.md):Cloud SOP 选定 `+data-query` 后或用户直接询问该命令/DSL 时读取 fewshot,完整 DSL 细节再读 SSOT;其 `filters` 使用独立对象 DSL
166
154
  - [lark-base-cell-value.md](references/lark-base-cell-value.md):记录 CellValue 构造
167
155
  - [lark-base-field-json.md](references/lark-base-field-json.md):字段 JSON 构造
168
156
  - [formula-field-guide.md](references/formula-field-guide.md) / [lookup-field-guide.md](references/lookup-field-guide.md):公式与 lookup 字段
169
157
  - [lark-base-field-create.md](references/lark-base-field-create.md) / [lark-base-field-update.md](references/lark-base-field-update.md):字段创建/更新命令级补充
170
158
  - [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-record-history-list.md](references/lark-base-record-history-list.md):记录写入 JSON 与历史返回解释
171
159
  - [lark-base-view-set-filter.md](references/lark-base-view-set-filter.md):视图筛选 JSON
172
- - [lark-base-filter-condition.md](references/lark-base-filter-condition.md):视图 filter、记录 `--filter-json`、表单 `visible_rule` 的 tuple 条件结构公共协议 SSOT;不适用于 `+data-query`
160
+ - [lark-base-filter-condition.md](references/lark-base-filter-condition.md):视图 filter、记录 `--filter-json`、表单 `visible_rule` 的 tuple 条件结构公共协议 SSOT
173
161
  - [lark-base-form-detail.md](references/lark-base-form-detail.md) / [lark-base-form-submit.md](references/lark-base-form-submit.md) / [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):表单详情、提交和复杂 JSON
174
162
  - [lark-base-dashboard.md](references/lark-base-dashboard.md) / [dashboard-block-data-config.md](references/dashboard-block-data-config.md) / [lark-base-dashboard-block-get-data.md](references/lark-base-dashboard-block-get-data.md):仪表盘、组件配置与图表结果协议
175
163
  - [lark-base-workflow-guide.md](references/lark-base-workflow-guide.md) / [lark-base-workflow-schema.md](references/lark-base-workflow-schema.md):workflow 入口与 steps JSON SSOT
@@ -48,25 +48,29 @@ text 字段的 `style.type` 影响单元格检查逻辑:
48
48
 
49
49
  ### 2.3 select(单选/多选)
50
50
 
51
- `select` 字段用 `multiple` 区分单选和多选:`multiple=false` 时传选项名字符串,`multiple=true` 时传选项名数组。只支持写入字段中已有的选项;构造 CellValue 前先用 `+field-list` 或 `+field-search-options` 确认目标选项存在。
51
+ `select` 字段统一传选项名称数组。`multiple=false` 时数组只能包含一个元素,`multiple=true` 时可以包含多个元素。只支持写入字段中已有的选项;构造 CellValue 前先用 `+field-list` 或 `+field-search-options` 确认目标选项存在。
52
52
 
53
53
  ```json
54
54
  {
55
- "单选": "Todo",
55
+ "单选": ["Todo"],
56
56
  "多选": ["后端", "高优"]
57
57
  }
58
58
  ```
59
59
 
60
+ 读取单元格时与写入的数据结构一致。
61
+
60
62
  ### 2.4 datetime
61
63
 
62
- 优先用 `YYYY-MM-DD HH:mm:ss` 字符串,这是最稳妥的写法,也和常见 API 输出更容易对齐。不要写相对时间(如“明天上午”)。
64
+ 写入可省略时区偏移量,系统会按 Base 时区解析输入字符串;优先使用 `YYYY-MM-DD HH:mm`。Base 默认按分钟展示,但底层以毫秒级精度存储时间
63
65
 
64
66
  ```json
65
67
  {
66
- "截止时间": "2026-03-24 10:00:00"
68
+ "截止时间": "2026-03-24 10:00"
67
69
  }
68
70
  ```
69
71
 
72
+ 读取单元格时,日期时间输出为标准 RFC3339 字符串并固定保留三位毫秒,例如 `"2026-03-24T10:00:00.000+08:00"`。
73
+
70
74
  ### 2.5 checkbox
71
75
 
72
76
  用 JSON boolean:`true` 或 `false`,不要用 `"true"`、`"是"`、`1`。
@@ -79,7 +83,7 @@ text 字段的 `style.type` 影响单元格检查逻辑:
79
83
 
80
84
  ### 2.6 user / group_chat
81
85
 
82
- 用对象数组,元素至少包含 `id`。人员字段传用户 ID(如 `ou_xxx`),群字段传群 ID(如 `oc_xxx`);单值/多值都统一使用数组。
86
+ `user` 和 `group_chat` 字段统一传对象数组。`multiple=false` 时数组只能包含一个元素,`multiple=true` 时可以包含多个元素。每个元素至少包含 `id`;人员字段传用户 ID(如 `ou_xxx`),群字段传群 ID(如 `oc_xxx`)。
83
87
 
84
88
  > **人员字段:不要猜 ID。** 不知道 `open_id` 时,先用 `lark-contact` 查 id:`lark-cli contact +search-user --query "<姓名/邮箱/手机号>" --as user`。
85
89
 
@@ -97,6 +101,8 @@ text 字段的 `style.type` 影响单元格检查逻辑:
97
101
  }
98
102
  ```
99
103
 
104
+ 读取单元格时仍为对象数组,每个元素为 `{id, name}`,例如 `[{"id":"ou_xxx","name":"张三"}]`。
105
+
100
106
  ### 2.7 link
101
107
 
102
108
  用对象数组,元素包含 `id`,值为目标记录的 `record_id`。不要传记录标题;先用 `+record-list` / `+record-search` 找到目标记录 ID。
@@ -109,6 +115,8 @@ text 字段的 `style.type` 影响单元格检查逻辑:
109
115
  }
110
116
  ```
111
117
 
118
+ 读取单元格时与写入的数据结构一致。
119
+
112
120
  ### 2.8 location
113
121
 
114
122
  写入对象必须使用 `{lng, lat}`,两者都是数字;`lng` 是经度,`lat` 是纬度。不需要手动传 `full_address`,平台会根据坐标解析地址。
@@ -122,10 +130,12 @@ text 字段的 `style.type` 影响单元格检查逻辑:
122
130
  }
123
131
  ```
124
132
 
125
- 读取、筛选、转文本等场景使用 `full_address` 字符串;只有公式能访问坐标。如果用户只给地址文本,先获取或确认坐标后再写入;不要把仅有地址文本直接当作 location CellValue。
133
+ 读取单元格时,非空 location 为 `{lng, lat, full_address}`,三个成员均非空,`full_address` 是字符串;筛选、转文本等场景使用 `full_address`,只有公式能访问坐标。如果用户只给地址文本,先获取或确认坐标后再写入;不要把仅有地址文本直接当作 location CellValue。
126
134
 
127
135
  ### 2.9 attachment(不作为普通 CellValue 写入)
128
136
 
137
+ 读取单元格时,附件为数组,每个元素为 `{file_token, size, name}`,例如 `[{"file_token":"box_xxx","size":1024,"name":"report.pdf"}]`。
138
+
129
139
  - 追加附件:使用 `lark-cli base +record-upload-attachment --record-id <record_id> --field-id <field_id> --file <path>`;可重复 `--file` 一次追加多个附件,不能用普通记录操作接口写附件值。
130
140
  - 删除附件:使用 `lark-cli base +record-remove-attachment --record-id <record_id> --field-id <field_id> --file-token <file_token> --yes`;可重复 `--file-token` 一次删除同一单元格里的多个附件。
131
141
  - 下载附件:使用 `lark-cli base +record-download-attachment --record-id <record_id> --file-token <file_token> --output <dir>`;不传 `--file-token` 时下载整行所有附件,也可重复 `--file-token` 只下载指定附件。Base 附件必须用这个命令下载,用其他下载入口可能失败。
@@ -141,6 +151,8 @@ text 字段的 `style.type` 影响单元格检查逻辑:
141
151
 
142
152
  写入只读字段通常不会更新数据;返回里可能出现 `ignored_fields`,reason 会说明 `READONLY`。看到这种返回时,不要重试同一 payload,应移除只读字段,只写存储字段。
143
153
 
154
+ 读取单元格时,`auto_number`、`formula`、`lookup` 为 `string|null`;`created_at`、`updated_at` 为标准 RFC3339 字符串或 `null`;`created_by`、`updated_by` 为 `array<{id, name}>`。
155
+
144
156
  ## 4. 完整示例
145
157
 
146
158
  ```json
@@ -149,7 +161,7 @@ text 字段的 `style.type` 影响单元格检查逻辑:
149
161
  "状态": "Todo",
150
162
  "标签": ["高优", "外部依赖"],
151
163
  "工时": 8,
152
- "截止时间": "2026-03-24 10:00:00",
164
+ "截止时间": "2026-03-24 10:00",
153
165
  "已完成": false,
154
166
  "负责人": [{ "id": "ou_123" }],
155
167
  "关联任务": [{ "id": "rec_456" }],