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

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 (73) hide show
  1. package/package.json +2 -2
  2. package/skills/lark-apps/SKILL.md +5 -3
  3. package/skills/lark-apps/references/lark-apps-automation.md +164 -0
  4. package/skills/lark-apps/references/lark-apps-get.md +43 -0
  5. package/skills/lark-apps/references/lark-apps-html-publish.md +7 -2
  6. package/skills/lark-apps/references/lark-apps-init.md +1 -2
  7. package/skills/lark-apps/references/lark-apps-openapi-key.md +1 -1
  8. package/skills/lark-apps/references/lark-apps-release-create.md +3 -1
  9. package/skills/lark-base/SKILL.md +1 -1
  10. package/skills/lark-base/references/lark-base-dashboard-block-get-data.md +7 -7
  11. package/skills/lark-calendar/references/lark-calendar-create.md +1 -0
  12. package/skills/lark-doc/references/lark-doc-xml-extended-blocks.md +2 -1
  13. package/skills/lark-drive/SKILL.md +10 -4
  14. package/skills/lark-drive/references/lark-drive-comment-location.md +16 -4
  15. package/skills/lark-drive/references/lark-drive-comments-guide.md +16 -8
  16. package/skills/lark-drive/references/lark-drive-export.md +39 -10
  17. package/skills/lark-drive/references/lark-drive-list-comments.md +125 -0
  18. package/skills/lark-drive/references/lark-drive-member-add.md +1 -1
  19. package/skills/lark-drive/references/lark-drive-pull.md +3 -3
  20. package/skills/lark-drive/references/lark-drive-push.md +1 -1
  21. package/skills/lark-drive/references/lark-drive-status.md +12 -14
  22. package/skills/lark-im/SKILL.md +5 -4
  23. package/skills/lark-im/references/lark-im-messages-reply.md +1 -1
  24. package/skills/lark-im/references/lark-im-messages-send.md +1 -1
  25. package/skills/lark-minutes/SKILL.md +19 -4
  26. package/skills/lark-minutes/references/lark-minutes-todo.md +2 -2
  27. package/skills/lark-shared/SKILL.md +9 -9
  28. package/skills/lark-sheets/SKILL.md +98 -29
  29. package/skills/lark-sheets/references/lark-sheets-batch-update.md +18 -9
  30. package/skills/lark-sheets/references/lark-sheets-changeset.md +105 -0
  31. package/skills/lark-sheets/references/lark-sheets-chart.md +4 -2
  32. package/skills/lark-sheets/references/lark-sheets-conditional-format.md +2 -0
  33. package/skills/lark-sheets/references/lark-sheets-filter-view.md +1 -1
  34. package/skills/lark-sheets/references/lark-sheets-float-image.md +6 -6
  35. package/skills/lark-sheets/references/lark-sheets-formula-translation.md +12 -3
  36. package/skills/lark-sheets/references/lark-sheets-formula-verify.md +77 -0
  37. package/skills/lark-sheets/references/lark-sheets-history.md +93 -0
  38. package/skills/lark-sheets/references/lark-sheets-pivot-table.md +7 -2
  39. package/skills/lark-sheets/references/lark-sheets-range-operations.md +44 -14
  40. package/skills/lark-sheets/references/lark-sheets-read-data.md +3 -3
  41. package/skills/lark-sheets/references/lark-sheets-sheet-structure.md +4 -4
  42. package/skills/lark-sheets/references/lark-sheets-visual-standards.md +4 -4
  43. package/skills/lark-sheets/references/lark-sheets-workbook.md +29 -4
  44. package/skills/lark-sheets/references/lark-sheets-write-cells.md +21 -11
  45. package/skills/lark-slides/SKILL.md +29 -18
  46. package/skills/lark-slides/references/asset-planning.md +0 -1
  47. package/skills/lark-slides/references/examples.md +57 -227
  48. package/skills/lark-slides/references/iconpark.md +2 -2
  49. package/skills/lark-slides/references/lark-slides-create.md +21 -2
  50. package/skills/lark-slides/references/lark-slides-media-upload.md +0 -1
  51. package/skills/lark-slides/references/lark-slides-pptx-template-workflows.md +89 -0
  52. package/skills/lark-slides/references/lark-slides-replace-pages.md +1 -1
  53. package/skills/lark-slides/references/lark-slides-replace-slide.md +1 -1
  54. package/skills/lark-slides/references/lark-slides-screenshot.md +11 -8
  55. package/skills/lark-slides/references/lark-slides-xml-get.md +100 -0
  56. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-delete.md +9 -7
  57. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-get.md +4 -4
  58. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-replace.md +12 -10
  59. package/skills/lark-slides/references/lark-slides-xml-presentations-get.md +14 -13
  60. package/skills/lark-slides/references/planning-layer.md +1 -1
  61. package/skills/lark-slides/references/troubleshooting.md +7 -25
  62. package/skills/lark-slides/references/validation-checklist.md +18 -9
  63. package/skills/lark-slides/references/visual-planning.md +4 -3
  64. package/skills/lark-slides/references/xml-schema-quick-ref.md +6 -2
  65. package/skills/lark-slides/scripts/xml_text_overlap_lint.py +647 -52
  66. package/skills/lark-slides/scripts/xml_text_overlap_lint_test.py +529 -0
  67. package/skills/lark-task/SKILL.md +1 -0
  68. package/skills/lark-vc-agent/SKILL.md +11 -4
  69. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md +1 -1
  70. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md +1 -1
  71. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-list-active.md +2 -2
  72. package/skills/lark-sheets/references/lark-sheets-core-operations.md +0 -103
  73. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-create.md +0 -220
@@ -3,7 +3,7 @@
3
3
 
4
4
  > **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
5
5
 
6
- 把 `doc` / `docx` / `sheet` / `bitable` / `slides` 导出到本地文件。这个 shortcut 内置有限轮询:
6
+ 把 `doc` / `docx` / `sheet` / `bitable` / `slides`(也支持 Wiki URL / Wiki node token 自动解包)导出到本地文件。这个 shortcut 内置有限轮询:
7
7
 
8
8
  - 如果导出任务在轮询窗口内完成,会直接下载到本地目录
9
9
  - 如果轮询结束仍未完成,会返回 `ticket`、`ready=false`、`timed_out=true` 和 `next_command`
@@ -13,6 +13,22 @@
13
13
  ## 命令
14
14
 
15
15
  ```bash
16
+ # 推荐:直接传 URL,CLI 自动解析类型和 token
17
+ lark-cli drive +export \
18
+ --url "https://example.feishu.cn/docx/<DOCX_TOKEN>" \
19
+ --file-extension pdf
20
+
21
+ # Wiki URL 也推荐直接传,CLI 会先解析到底层 obj_token/obj_type
22
+ lark-cli drive +export \
23
+ --url "https://example.feishu.cn/wiki/<WIKI_NODE_TOKEN>" \
24
+ --file-extension pdf
25
+
26
+ # 只有裸 Wiki node token 时,显式传 --doc-type wiki,让 CLI 先解析到底层文档类型
27
+ lark-cli drive +export \
28
+ --token "<WIKI_NODE_TOKEN>" \
29
+ --doc-type wiki \
30
+ --file-extension pdf
31
+
16
32
  # 导出新版文档为 pdf,默认保存到当前目录
17
33
  lark-cli drive +export \
18
34
  --token "<DOCX_TOKEN>" \
@@ -96,8 +112,9 @@ lark-cli drive +export \
96
112
 
97
113
  | 参数 | 必填 | 说明 |
98
114
  |------|------|------|
99
- | `--token` | 是 | 源文档 token |
100
- | `--doc-type` | 是 | 源文档类型:`doc` / `docx` / `sheet` / `bitable` / `slides` |
115
+ | `--url` | 与 `--token` 二选一 | 源文档 URL,推荐优先使用;CLI 自动解析类型和 token,Wiki URL 会解析到底层 `obj_token/obj_type` |
116
+ | `--token` | 与 `--url` 二选一 | 源文档裸 token;裸 token 必须同时传 `--doc-type`。裸 Wiki node token 必须传 `--doc-type wiki`,CLI 会先解析到底层 `obj_token/obj_type` |
117
+ | `--doc-type` | 条件必填 | 源文档类型:`doc` / `docx` / `sheet` / `bitable` / `slides` / `wiki`;仅当使用裸 `--token` 时必填,使用 `--url` 时自动推断。`wiki` 只用于裸 Wiki node token,解析后会按真实底层类型发起导出 |
101
118
  | `--file-extension` | 是 | 导出格式:`docx` / `pdf` / `xlsx` / `csv` / `markdown` / `base` / `pptx` |
102
119
  | `--sub-id` | 条件必填 | 当 `sheet` / `bitable` 导出为 `csv` 时必填 |
103
120
  | `--only-schema` | 否 | 仅当 `--doc-type bitable --file-extension base` 时可用;只导出多维表格结构,不导出记录数据 |
@@ -107,22 +124,34 @@ lark-cli drive +export \
107
124
 
108
125
  ## 关键约束
109
126
 
110
- - `markdown` 只支持 `docx`
111
- - `base` 只支持 `bitable`
112
- - `--only-schema` 只支持 `bitable` 导出为 `.base`,用于仅导出表结构
113
- - `pptx` 只支持 `slides`
127
+ - 推荐优先传 `--url`,不要从 URL 手工拆 token 和 type;尤其是 Wiki URL,CLI 会自动解包到底层资源
128
+ - `--url` 和 `--token` 互斥
129
+ - 裸 `--token` 必须传 `--doc-type`;裸 Wiki node token 使用 `--doc-type wiki`
130
+ - `doc` 支持导出为 `docx` / `pdf`
131
+ - `docx` 支持导出为 `docx` / `pdf` / `markdown`
132
+ - `sheet` 支持导出为 `xlsx` / `csv`
133
+ - `bitable` 支持导出为 `xlsx` / `csv` / `base`
114
134
  - `slides` 支持导出为 `pptx` / `pdf`
115
- - `sheet` / `bitable` 导出为 `csv` 时必须带 `--sub-id`
135
+ - `csv` 只支持 `sheet` / `bitable`,且必须带 `--sub-id`
136
+ - `--only-schema` 只支持 `bitable` 导出为 `.base`,用于仅导出表结构
137
+ - 如果格式不匹配,CLI 会返回 typed validation error,并在 `hint` 中给出可重试的 `--file-extension` 建议;例如 `docx + csv` 会提示改用 `docx/pdf/markdown`,或改传 sheet/bitable URL
116
138
  - shortcut 内部固定有限轮询:最多 10 次,每次间隔 5 秒
117
139
  - 轮询超时不是失败;会返回 `ticket`、`timed_out=true` 和 `next_command`,供后续继续查询
118
140
 
141
+ ## 错误码处理
142
+
143
+ | 错误码 | 含义 | 处理方式 |
144
+ |--------|------|----------|
145
+ | `1069914` | token 非法或 token/type 不匹配;常见原因是把 Wiki node token 当作底层 `docx` / `sheet` / `bitable` token 使用,没有传 `--doc-type wiki` | 优先改用 `--url <Wiki URL>`;只有裸 Wiki token 时,用 `--token <WIKI_NODE_TOKEN> --doc-type wiki`。不确定 token 类型时,先用 `lark-cli drive +inspect --url <TOKEN> --type wiki` 检查是否能解包为 Wiki node;如果不是 Wiki token,再检查 token 来源、`--doc-type` 是否与实际资源类型一致 |
146
+ | `1069902` | 没有当前导出任务所需权限 | 不要直接重试同一命令;先确认当前 `--as` 身份是否能访问该文档、是否有下载/导出权限,以及文档是否受分享、密级或租户策略限制。需要补权限时,让文档 owner 或管理员授权后再执行 |
147
+ | `99991679` | 缺少 OpenAPI scope | 按错误 envelope 中的 `missing_scopes` / `required_scope` / `hint` 补齐授权;常见方式是重新执行 `lark-cli auth login --scope "<缺失 scope>"`。补 scope 前不要反复重试导出命令 |
148
+
119
149
  ## 推荐续跑方式
120
150
 
121
151
  ```bash
122
152
  # 第一步:先尝试直接导出
123
153
  lark-cli drive +export \
124
- --token "<DOCX_TOKEN>" \
125
- --doc-type docx \
154
+ --url "<DOCX_URL>" \
126
155
  --file-extension pdf \
127
156
  --file-name "weekly-report.pdf"
128
157
 
@@ -0,0 +1,125 @@
1
+ # drive +list-comments
2
+
3
+ > **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和权限处理。
4
+
5
+ 列出 doc/docx/sheet/file/slides/base(bitable)/apps 的评论卡片。优先传用户给出的完整 URL,shortcut 会自动识别类型;apps 为妙搭类型,支持 `/page/<token>` URL;如果传 wiki URL 或 `--token <wiki_token> --type wiki`,会先解析到真实文档。
6
+
7
+ ## 重要默认口径
8
+
9
+ - 默认只查未解决评论,即不额外传 `--solved-status` 或显式传 `--solved-status false`。即使用户说“所有评论”“全部评论”“把评论都列出来”,只要没有明确提到包含已解决评论,仍然按默认口径查询未解决评论。
10
+ - 仅当用户明确要求“包含已解决评论”“已解决和未解决都要”“全部历史评论”这类语义时,才传 `--solved-status all`。
11
+ - 是否还有下一页以输出里的 `has_more` 为准;`page_token` 只作为 `has_more=true` 时续跑下一页的游标。
12
+
13
+ ## 命令
14
+
15
+ ```bash
16
+ # 推荐:直接传用户给出的完整 URL。默认只查未解决评论。
17
+ lark-cli drive +list-comments \
18
+ --url "<DOCUMENT_URL>"
19
+
20
+ # 只有用户明确要求包含已解决评论时,才查询已解决和未解决的全部评论。
21
+ lark-cli drive +list-comments \
22
+ --url "<DOCUMENT_URL>" \
23
+ --solved-status all
24
+
25
+ # 查询已解决评论。
26
+ lark-cli drive +list-comments \
27
+ --url "<DOCUMENT_URL>" \
28
+ --solved-status true
29
+
30
+ # 只查全文评论或局部评论。
31
+ lark-cli drive +list-comments \
32
+ --url "<DOCUMENT_URL>" \
33
+ --comment-scope whole
34
+
35
+ lark-cli drive +list-comments \
36
+ --url "<DOCUMENT_URL>" \
37
+ --comment-scope partial
38
+
39
+ # 电子表格 URL 保留 /sheets/ 路径,直接原样传入;不要把 sheet token 拼成 /docx/<token>。
40
+ lark-cli drive +list-comments \
41
+ --url "https://example.larksuite.com/sheets/<SHEET_TOKEN>"
42
+
43
+ # 妙搭 apps URL 使用 /page/<token>,shortcut 会识别为 file_type=apps。
44
+ lark-cli drive +list-comments \
45
+ --url "https://example.feishu.cn/page/<APPS_TOKEN>/"
46
+
47
+ # wiki URL 会自动解包。
48
+ lark-cli drive +list-comments \
49
+ --url "https://example.larksuite.com/wiki/<WIKI_TOKEN>"
50
+
51
+ # 裸 wiki token 也支持,但必须显式声明 --type wiki。
52
+ lark-cli drive +list-comments \
53
+ --token "<WIKI_TOKEN>" \
54
+ --type wiki
55
+
56
+ # 裸 token 需要声明 token 对应类型;不要默认当作 docx。这里以 sheet 为例。
57
+ lark-cli drive +list-comments \
58
+ --token "<DOCUMENT_TOKEN>" \
59
+ --type sheet \
60
+ --page-size 100
61
+
62
+ # 妙搭裸 apps token 需要显式声明 --type apps。
63
+ lark-cli drive +list-comments \
64
+ --token "<APPS_TOKEN>" \
65
+ --type apps
66
+
67
+ # docx 需要评论定位关系时再带 need-relation;非 docx 会静默忽略。
68
+ lark-cli drive +list-comments \
69
+ --url "https://example.larksuite.com/docx/<DOCX_TOKEN>" \
70
+ --need-relation
71
+
72
+ # 分页续跑。
73
+ # 先看上一页输出的 has_more;只有 has_more=true 时,才用返回的 page_token 继续。
74
+ lark-cli drive +list-comments \
75
+ --url "<DOCUMENT_URL>" \
76
+ --page-size 100 \
77
+ --page-token "<NEXT_PAGE_TOKEN>"
78
+
79
+ # 预览请求链路,不发真实请求。
80
+ lark-cli drive +list-comments \
81
+ --url "https://example.larksuite.com/wiki/<WIKI_TOKEN>" \
82
+ --dry-run
83
+ ```
84
+
85
+ ## 参数
86
+
87
+ | 参数 | 必填 | 说明 |
88
+ |------|------|------|
89
+ | `--url` | 与 `--token` 二选一 | 推荐入口。支持 doc/docx/sheet/file/slides/base/bitable/apps/wiki URL;apps 妙搭 URL 使用 `/page/<token>`;wiki URL 会自动解析到真实文档。 |
90
+ | `--token` | 与 `--url` 二选一 | 裸 token 或 URL。裸 token 必须搭配 `--type`;wiki token 使用 `--type wiki`。 |
91
+ | `--type` | 裸 token 时必填 | 传 token 对应类型:`doc`、`docx`、`sheet`、`file`、`slides`、`bitable`、`base`、`apps`、`wiki`。wiki token 使用 `wiki`;传 `base` 时,CLI 会按 `bitable` 类型处理。 |
92
+ | `--solved-status` | 否 | `false` / `true` / `all`,默认 `false`。`false` 查未解决评论;`true` 查已解决评论;`all` 查全部评论。 |
93
+ | `--comment-scope` | 否 | `all` / `whole` / `partial`,默认 `all`。`all` 查全部范围;`whole` 查全文评论;`partial` 查局部评论。 |
94
+ | `--need-reaction` | 否 | 是否返回评论卡片上的 reaction 数据;只有用户明确需要 reaction 时才带。 |
95
+ | `--need-relation` | 否 | docx 评论定位关系字段;仅 docx 生效,非 docx 静默忽略。需要定位正文时先读 [`lark-drive-comment-location.md`](lark-drive-comment-location.md)。 |
96
+ | `--page-size` | 否 | 默认 50,最大 100。 |
97
+ | `--page-token` | 否 | 分页游标;本 shortcut 不自动翻页,按返回的 `page_token` 继续请求下一页。 |
98
+
99
+ ## 行为说明
100
+
101
+ - `--comment-scope all` 查全部范围;`whole` 查全文评论;`partial` 查局部/选区评论。
102
+ - 当用户已经给出完整 URL 时,原样传给 `--url`;不要先提取 token 再重组成其他类型 URL。比如 sheet 保留 `/sheets/<token>`,wiki 保留 `/wiki/<token>`,妙搭 apps 保留 `/page/<token>`。
103
+ - URL 输入时不需要传 `--type`;如果 URL 类型和显式 `--type` 冲突,shortcut 会返回 validation error,建议移除 `--type`。
104
+ - wiki 输入会自动解析到真实文档,再查询评论列表。JSON 输出不额外返回 wiki token 或 wiki node。
105
+ - 输出中的 `items` 保留评论卡片字段,外层补充 `file_token`、`file_type`、`has_more`、`page_token`、`count`;`count` 是当前页返回的评论卡片数。是否继续分页以 `has_more` 为准,而不是只看 `page_token` 是否存在。
106
+ - 如果需要批量按评论 ID 查询、获取更多回复、创建/编辑/删除回复,继续使用原生 `drive file.comments batch_query` 或 `drive file.comment.replys.*`。
107
+
108
+ ## 输出
109
+
110
+ ```json
111
+ {
112
+ "file_token": "docx_token",
113
+ "file_type": "docx",
114
+ "items": [],
115
+ "has_more": false,
116
+ "page_token": "",
117
+ "count": 0
118
+ }
119
+ ```
120
+
121
+ ## 参考
122
+
123
+ - [lark-drive](../SKILL.md) -- 云空间(云盘/云存储)全部命令
124
+ - [lark-drive-comments-guide](lark-drive-comments-guide.md) -- 评论统计、回复限制和原生 API 说明
125
+ - [lark-drive-comment-location](lark-drive-comment-location.md) -- 使用 `need_relation` 定位 docx 正文
@@ -54,7 +54,7 @@ lark-cli drive +member-add \
54
54
  }
55
55
  ```
56
56
 
57
- 批量部分失败时,`partial` 为 `true`,CLI 以非零退出码返回 `error.type=partial_failure`。检查 `error.detail` 中的 `requested_count`、`succeeded_count`、`members`、`missing_member_ids` 和可选的 `mismatched_member_ids`。响应顺序不影响匹配结果。
57
+ 批量部分失败时,`partial` 为 `true`,同一份结果以 `ok:false` 部分失败信封写到 **stdout**(stderr 不再输出单独的错误信封),CLI 以非零退出码结束。检查 `data` 中的 `requested_count`、`succeeded_count`、`members`、`missing_member_ids` 和可选的 `mismatched_member_ids`。响应顺序不影响匹配结果。
58
58
 
59
59
  ## 行为说明
60
60
 
@@ -17,11 +17,11 @@
17
17
  | `summary.deleted_local` | 启用 `--delete-local --yes` 时删除的本地文件数 |
18
18
  | `items[]` | 每个文件的明细(`rel_path` / `file_token` / `source_id` / `action` / 失败时的 `error`) |
19
19
 
20
- `summary.failed > 0` 时命令以 **非零状态码**(`exit=1`,`error.type=partial_failure`)退出,且同一份 `summary + items` 会在 `error.detail` 里返回;脚本/agent 直接通过 exit code 判断成败即可,不需要再去解 `summary.failed`。
20
+ `summary.failed > 0` 时命令以 **非零状态码**(`exit=1`)退出:同一份 `summary + items` 会以 `ok:false` 部分失败信封写到 **stdout**(字段在 `data.summary` / `data.items`),stderr 不再输出单独的错误信封;脚本/agent 直接通过 exit code 判断成败即可,不需要再去解 `summary.failed`。
21
21
 
22
22
  ## 远端同名文件冲突
23
23
 
24
- 如果 Drive 中多个条目映射到同一个 `rel_path`,默认直接失败(`error.type=duplicate_remote_path`),且不会下载、覆盖或删除任何本地文件。只有“多个 `type=file` 同名”的场景支持显式策略;`file-folder` 这类异构冲突始终直接失败。
24
+ 如果 Drive 中多个条目映射到同一个 `rel_path`,默认直接失败(stderr 类型化错误信封:`error.type=validation`、`error.subtype=failed_precondition`,`error.params[]` 逐条列出冲突的 `rel_path` 及碰撞条目),且不会下载、覆盖或删除任何本地文件。只有“多个 `type=file` 同名”的场景支持显式策略;`file-folder` 这类异构冲突始终直接失败。
25
25
 
26
26
  | 策略 | 行为 |
27
27
  |------|------|
@@ -80,7 +80,7 @@ lark-cli drive +pull --local-dir ./repo --folder-token fldcnxxxxxxxxx \
80
80
 
81
81
  - `--delete-local`(无 `--yes`)→ Validate 直接报错:`--delete-local requires --yes`,没有任何下载、列表请求或删除发生。
82
82
  - `--delete-local --yes`,**且下载阶段全部成功** → 扫一遍 `--local-dir` 下所有常规文件,把不在云端清单里的逐个 `os.Remove`。**只删常规文件,不删目录**:远端文件夹被删除后,对应本地目录会保留空壳。
83
- - `--delete-local --yes`,**但下载阶段有任何条目失败** → **跳过整个删除阶段**,命令以 `partial_failure` 非零退出。设计意图:避免出现"前面下载失败、后面继续删本地文件"的半同步状态;操作者修好下载错误后再重跑即可。
83
+ - `--delete-local --yes`,**但下载阶段有任何条目失败** → **跳过整个删除阶段**,命令以 `ok:false` 部分失败结果非零退出。设计意图:避免出现"前面下载失败、后面继续删本地文件"的半同步状态;操作者修好下载错误后再重跑即可。
84
84
  - 远端同名文件冲突且使用默认 `fail` → 在下载阶段前失败,删除阶段不会运行。
85
85
  - 不传 `--delete-local` → `summary.deleted_local` 永远是 0;命令对本地"多余"文件视而不见。
86
86
 
@@ -24,7 +24,7 @@
24
24
 
25
25
  ## 远端同名文件冲突
26
26
 
27
- 如果 Drive 中多个条目映射到同一个 `rel_path`,默认直接失败(`error.type=duplicate_remote_path`),且不会上传、覆盖或进入 `--delete-remote` 删除阶段。只有“多个 `type=file` 同名”的场景支持显式策略;`file-folder` 这类异构冲突始终直接失败。
27
+ 如果 Drive 中多个条目映射到同一个 `rel_path`,默认直接失败(stderr 类型化错误信封:`error.type=validation`、`error.subtype=failed_precondition`,`error.params[]` 逐条列出冲突的 `rel_path` 及碰撞条目),且不会上传、覆盖或进入 `--delete-remote` 删除阶段。只有“多个 `type=file` 同名”的场景支持显式策略;`file-folder` 这类异构冲突始终直接失败。
28
28
 
29
29
  | 策略 | 行为 |
30
30
  |------|------|
@@ -19,7 +19,7 @@
19
19
 
20
20
  ## 远端同名文件冲突
21
21
 
22
- 如果 Drive 中多个条目映射到同一个 `rel_path`,`+status` 会在下载/hash 前直接失败,返回 `error.type=duplicate_remote_path`,并在 `error.detail.duplicates_remote[]` 中列出该路径下所有冲突条目的 `file_token`、`type`、名称、大小和时间字段;其中 `created_time`、`modified_time` 缺失时会省略,`size` 在缺失或为 `0` 时都可能被省略。不要把这种情况当成普通 `modified`;它表示同步域本身有歧义,需要先整理云端结构,或在 `+pull` / `+push` 中仅对“duplicate file”场景显式选择冲突策略。
22
+ 如果 Drive 中多个条目映射到同一个 `rel_path`,`+status` 会在下载/hash 前直接失败,在 stderr 返回类型化错误信封(`error.type=validation`、`error.subtype=failed_precondition`);`error.params[]` 每条的 `name` 是冲突的 `rel_path`,`reason` 枚举该路径下所有碰撞条目(`type` + `file_token`)。不要把这种情况当成普通 `modified`;它表示同步域本身有歧义,需要先整理云端结构,或在 `+pull` / `+push` 中仅对“duplicate file”场景显式选择冲突策略。
23
23
 
24
24
  ## 命令
25
25
 
@@ -76,20 +76,18 @@ lark-cli drive +status \
76
76
  ```json
77
77
  {
78
78
  "ok": false,
79
+ "identity": "user",
79
80
  "error": {
80
- "type": "duplicate_remote_path",
81
- "message": "multiple Drive entries map to the same rel_path",
82
- "detail": {
83
- "duplicates_remote": [
84
- {
85
- "rel_path": "dup.txt",
86
- "entries": [
87
- {"file_token": "<full_file_token>", "type": "file", "name": "dup.txt", "size": 5, "created_time": "1730000000", "modified_time": "1730000000"},
88
- {"file_token": "<folder_token>", "type": "folder", "name": "dup.txt", "created_time": "1730000060", "modified_time": "1730000060"}
89
- ]
90
- }
91
- ]
92
- }
81
+ "type": "validation",
82
+ "subtype": "failed_precondition",
83
+ "message": "1 rel_path(s) map to multiple Drive entries",
84
+ "hint": "resolve the duplicate remote files first: re-run +pull with --on-duplicate-remote=rename (downloads each with a hashed suffix), or use --on-duplicate-remote=newest|oldest (supported by +pull/+sync/+push) to pick one, or delete the extra remote files; a plain retry will not help",
85
+ "params": [
86
+ {
87
+ "name": "dup.txt",
88
+ "reason": "2 Drive entries collide here: file <full_file_token>, folder <folder_token>"
89
+ }
90
+ ]
93
91
  }
94
92
  }
95
93
  ```
@@ -41,13 +41,14 @@ Chat (oc_xxx)
41
41
  - `--as bot` means **bot identity** and uses `tenant_access_token`. Calls run as the app bot, so behavior depends on the bot's membership, app visibility, availability range, and bot-specific scopes.
42
42
  - If an IM API says it supports both `user` and `bot`, the token type changes who the operator is. The same API can succeed with one identity and fail with the other because owner/admin status, chat membership, tenant boundary, or app availability are checked against the current caller.
43
43
 
44
- ### Sender Name Resolution with Bot Identity
44
+ ### Sender Name Resolution
45
45
 
46
- When using bot identity (`--as bot`) to fetch messages (e.g. `+chat-messages-list`, `+threads-messages-list`, `+messages-mget`), sender names may not be resolved (shown as open_id instead of display name). This happens when the bot cannot access the user's contact info.
46
+ When fetching messages (`+chat-messages-list`, `+threads-messages-list`, `+messages-mget`, `+messages-search`), the CLI shows a display name for both user and bot senders:
47
47
 
48
- **Root cause**: The bot's app visibility settings do not include the message sender, so the contact API returns no name.
48
+ - **Server-provided name**: the read APIs return `sender_name` (plus the full-i18n `sender_i18n_names` map) on each message `sender`; the CLI surfaces it as the sender's `name` for users and bots alike. No name lookup and no extra permission are needed — **no contact scope** and no `application:bot.basic_info:read`.
49
+ - **Fallback to id**: when the server does not provide a name, the sender is shown by its id and the command still exits 0. There is no contact-directory fallback.
49
50
 
50
- **Solution**: Check the app's visibility settings in the Lark Developer Console — ensure the app's visible range covers the users whose names need to be resolved. Alternatively, use `--as user` to fetch messages with user identity, which typically has broader contact access.
51
+ The raw `sender_name` is not duplicated in output (its value is in `name`); the full `sender_i18n_names` map (all locales) is preserved for consumers that need a specific language, alongside an optional `open_bot_id` (`ou_`) for bot senders aligned with the message-receive event channel. System messages (`msg_type: system`) have no sender name — that is normal, not an error.
51
52
 
52
53
  ### Default message enrichment (reactions / update_time)
53
54
 
@@ -188,7 +188,7 @@ lark-cli im +messages-reply --message-id om_xxx --msg-type interactive --content
188
188
  | `--video-cover <path\|url\|key>` | **Required with `--video`** | Cwd-relative local cover image path, URL, or `image_key` (`img_xxx`) |
189
189
  | `--audio <path\|url\|key>` | One content option | Voice-message audio key, URL, or cwd-relative local path. Local paths and URLs must be Opus (`.opus` or Ogg Opus `.ogg`) |
190
190
  | `--reply-in-thread` | No | Reply inside the thread. The reply appears in the target message's thread instead of the main chat stream |
191
- | `--idempotency-key <key>` | No | Idempotency key; the same key sends only one reply within 1 hour |
191
+ | `--idempotency-key <key>` | No | Idempotency key, max 50 characters; the same key sends only one reply within 1 hour |
192
192
  | `--as <identity>` | No | Identity type: `bot` or `user` (default `bot`) |
193
193
  | `--dry-run` | No | Print the request only, do not execute it |
194
194
 
@@ -191,7 +191,7 @@ lark-cli im +messages-send --chat-id oc_xxx --msg-type interactive --content '<c
191
191
  | `--video-cover <path\|url\|key>` | **Required with `--video`** | Cwd-relative local cover image path, URL, or `image_key` (`img_xxx`). Local paths and URLs are uploaded automatically |
192
192
  | `--audio <path\|url\|key>` | One content option | Voice-message audio key, URL, or cwd-relative local path. Local paths and URLs must be Opus (`.opus` or Ogg Opus `.ogg`) |
193
193
  | `--msg-type <type>` | No | Message type (default `text`). If you use `--text` / `--markdown` / media flags, the effective type is inferred automatically. Explicitly setting a conflicting `--msg-type` fails validation |
194
- | `--idempotency-key <key>` | No | Idempotency key; the same key sends only one message within 1 hour |
194
+ | `--idempotency-key <key>` | No | Idempotency key, max 50 characters; the same key sends only one message within 1 hour |
195
195
  | `--as <identity>` | No | Identity type: `bot` or `user` (default `bot`) |
196
196
  | `--dry-run` | No | Print the request only, do not execute it |
197
197
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lark-minutes
3
3
  version: 1.0.0
4
- description: "飞书妙记:搜索妙记、查看妙记基础信息、下载/上传音视频、读取或编辑妙记的产物内容、改标题、替换说话人/关键词。当给出minute_token、本地音视频文件,要查/改/转妙记产物时使用;本地音视频转纪要/逐字稿优先走本 skill,不要用 ffmpeg/whisper 本地转写。不负责:获取会议关联妙记,或仅按自然语言标题定位纪要"
4
+ description: "飞书妙记:搜索妙记、查看妙记基础信息、下载/上传音视频、读取或编辑妙记的产物内容、改标题、替换说话人/关键词、申请妙记查看/编辑权限。当给出minute_token、本地音视频文件,要查/改/转妙记产物,或用户明确要主动申请妙记权限时使用;本地音视频转纪要/逐字稿优先走本 skill,不要用 ffmpeg/whisper 本地转写。不负责:获取会议关联妙记,或仅按自然语言标题定位纪要"
5
5
  metadata:
6
6
  requires:
7
7
  bins: ["lark-cli"]
@@ -31,6 +31,7 @@ metadata:
31
31
  | [`+download`](references/lark-minutes-download.md) | 下载妙记音视频媒体文件 |
32
32
  | [`+upload`](references/lark-minutes-upload.md) | 上传 file_token 生成妙记 |
33
33
  | [`+update`](references/lark-minutes-update.md) | 更新妙记标题 |
34
+ | `+apply-permission` | 申请妙记查看或编辑权限 |
34
35
  | [`+speaker-replace`](references/lark-minutes-speaker-replace.md) | 替换妙记逐字稿中的说话人(须先 `lark-cli api GET .../speakerlist` 取 `speaker_id`) |
35
36
  | `+word-replace` | 批量替换逐字稿关键词(详见 `lark-cli minutes +word-replace --help`) |
36
37
  | [`+summary`](references/lark-minutes-summary.md) | 替换妙记 AI 总结全文 |
@@ -52,6 +53,7 @@ metadata:
52
53
  | 在妙记里增加 / 更改 / 删除 AI 待办 | `+todo`(**禁止走 lark-task**) |
53
54
  | 替换妙记的AI 总结 | `+summary` |
54
55
  | 重命名妙记/改妙记标题 | `+update` |
56
+ | 申请妙记权限(查看/编辑) | `+apply-permission --perm view\|edit` |
55
57
  | 替换说话人/把 A 的发言改成 B/重新归属发言人/把外部(非飞书)说话人改成飞书用户" | 先 `lark-cli api GET .../transcript/speakerlist` 取 `speaker_id`,再 [`minutes +speaker-replace`](references/lark-minutes-speaker-replace.md);`--from-speaker-id` 只传 id,不传展示名 |
56
58
  | 批量替换逐字稿关键词 | `+word-replace` |
57
59
  | 用户同时提到"会议/开会"和"妙记" | 先 [lark-vc](../lark-vc/SKILL.md)(`+search` → `+recording`)获取 `minute_token`,再本 skill |
@@ -75,8 +77,21 @@ metadata:
75
77
  2. 如果是会议 / 日程上下文中的妙记基础信息,先通过 VC/Calendar 链路拿到 `minute_token`,再调用 `minutes minutes get`。
76
78
  3. 用户意图不明确时,默认先给基础元信息,帮助确认是否命中目标妙记。
77
79
 
80
+ ### 3. 申请妙记权限
78
81
 
79
- ### 3. 上传音视频文件生成妙记(并可继续获取纪要 / 逐字稿)
82
+ 遇到妙记没有查看或编辑权限时,引导用户申请对应权限;只有用户明确要申请时,才调用 `minutes +apply-permission`。
83
+
84
+ 只有当用户明确要求"申请查看权限"、"申请编辑权限"、"帮我申请这条妙记权限"时,才调用:
85
+
86
+ ```bash
87
+ lark-cli minutes +apply-permission --minute-token <token> --perm view|edit
88
+ ```
89
+
90
+ 这是向妙记所有者发起权限申请,不代表立即获得权限。
91
+
92
+ **安全约束**:遇到无权限错误时,不要自动调用 `+apply-permission`;先把无权限事实告知用户,只有用户明确要求申请权限时才发起申请。
93
+
94
+ ### 4. 上传音视频文件生成妙记(并可继续获取纪要 / 逐字稿)
80
95
 
81
96
  1. 当用户说"把音视频文件转成纪要""把录音转成逐字稿/文字稿/撰写文字""把 mp4/mp3 转成总结/待办/章节"时,也先走这个入口。
82
97
  2. **处理流程**:
@@ -120,9 +135,9 @@ lark-cli minutes +todo --minute-token <token> --as user --todos '[
120
135
 
121
136
  **更新 / 删除前**:先用 `minutes +detail --minute-tokens <token> --todo` 读取 `todos[].todo_id`(按 `content` 匹配目标条目;列表顺序不保证稳定,**不要**用"第 2 条"代替 `todo_id`)。
122
137
 
123
- **无编辑权限**:若 CLI 返回 `error.type=no_edit_permission`,表示对**这条妙记**没有编辑权,应请所有者授权;**不要**误走 `auth login --scope`。
138
+ **无编辑权限**:若 CLI 返回 `error.subtype=permission_denied`,表示对**这条妙记**没有编辑权,应请所有者授权;**不要**误走 `auth login --scope`。
124
139
 
125
- **逐字稿关键词替换无命中**:`minutes +word-replace` 时,若 CLI 返回 `error.type=words_not_found`,表示传入的 `source_word` 在该妙记逐字稿中**一个都没匹配到**,未做任何替换。这是**参数问题不是权限问题**:先用 `minutes +detail --minute-tokens <token> --transcript` 读取当前逐字稿,核对 `source_word` 的精确写法与大小写后重试。
140
+ **逐字稿关键词替换无命中**:`minutes +word-replace` 时,若 CLI 返回 `error.subtype=not_found`,表示传入的 `source_word` 在该妙记逐字稿中**一个都没匹配到**,未做任何替换。这是**参数问题不是权限问题**:先用 `minutes +detail --minute-tokens <token> --transcript` 读取当前逐字稿,核对 `source_word` 的精确写法与大小写后重试。
126
141
 
127
142
  **替换 AI 总结全文**:见 [minutes +summary](references/lark-minutes-summary.md)。
128
143
 
@@ -126,8 +126,8 @@ lark-cli minutes +todo --minute-token obcnxxxxxxxxxxxxxxxxxxxx --operation add -
126
126
  | 未指定操作 | 单条模式传 `--operation`,或批量传 `--todos` |
127
127
  | `--todos` 与单条 flags 冲突 | 二选一 |
128
128
  | `todos[i]` 校验失败 | 检查该条 `operation` 与字段组合 |
129
- | `error.type` = `no_edit_permission` | **妙记资源无编辑权**:向妙记所有者申请该妙记的编辑/协作权限;**不要**走 `auth login --scope` |
130
- | 缺少 OAuth scope(`permission_violations` 含 `minutes:minutes:update`) | `lark-cli auth login --scope "minutes:minutes:update"` |
129
+ | `error.subtype` = `permission_denied` | **妙记资源无编辑权**:向妙记所有者申请该妙记的编辑/协作权限;**不要**走 `auth login --scope` |
130
+ | 缺少 OAuth scope(`error.missing_scopes` 含 `minutes:minutes:update`) | `lark-cli auth login --scope "minutes:minutes:update"` |
131
131
 
132
132
  ## 参考
133
133
 
@@ -69,7 +69,7 @@ LARKSUITE_CLI_NO_UPDATE_NOTIFIER=1 LARKSUITE_CLI_NO_SKILLS_NOTIFIER=1 lark-cli a
69
69
  遇到权限相关错误时,**根据当前身份类型采取不同解决方案**。
70
70
 
71
71
  错误响应中包含关键信息:
72
- - `permission_violations`:列出缺失的 scope (N选1)
72
+ - `missing_scopes`:列出缺失的 scope (N选1)
73
73
  - `console_url`:飞书开发者后台的权限配置链接
74
74
  - `hint`:建议的修复命令
75
75
 
@@ -159,7 +159,7 @@ lark-cli update
159
159
  错误信封写入 **stderr**(退出码非 0):
160
160
 
161
161
  ```json
162
- { "ok": false, "identity": "user", "error": { "type": "api", "subtype": "...", "code": 99991679, "message": "...", "hint": "..." } }
162
+ { "ok": false, "identity": "user", "error": { "type": "authorization", "subtype": "missing_scope", "code": 99991679, "message": "...", "hint": "...", "missing_scopes": ["..."] } }
163
163
  ```
164
164
 
165
165
  **判断成功必须用 `ok == true`(或进程退出码 0),不要用 `code == 0`**:成功信封没有顶层 `code` / `msg` 字段,`code` 只出现在错误信封的 `error` 内,含义是上游 OpenAPI 的 numeric code。按 OpenAPI 老格式 `{"code": 0, "msg": "ok"}` 判断会把所有成功调用误判为失败;封装写入类命令(如 `task +create`)时尤其危险,误判会绕过幂等逻辑导致重复创建。
@@ -178,22 +178,22 @@ lark-cli 对高风险写操作(`risk: "high-risk-write"`)有强制确认门
178
178
  ```json
179
179
  {
180
180
  "ok": false,
181
+ "identity": "bot",
181
182
  "error": {
182
- "type": "confirmation_required",
183
+ "type": "confirmation",
184
+ "subtype": "confirmation_required",
183
185
  "message": "drive +delete requires confirmation",
184
186
  "hint": "add --yes to confirm",
185
- "risk": {
186
- "level": "high-risk-write",
187
- "action": "drive +delete"
188
- }
187
+ "risk": "high-risk-write",
188
+ "action": "drive +delete"
189
189
  }
190
190
  }
191
191
  ```
192
192
 
193
193
  **遇到这种情况,不要当普通错误放弃。** 按以下流程处理:
194
194
 
195
- 1. **识别**:看到子进程 exit code = `10` 且 stderr JSON 里 `error.type == "confirmation_required"`
196
- 2. **向用户确认**:把 `error.risk.action` 和关键参数展示给用户,明确告知"这是高风险操作",等待用户显式同意
195
+ 1. **识别**:看到子进程 exit code = `10` 且 stderr JSON 里 `error.type == "confirmation"`、`error.subtype == "confirmation_required"`
196
+ 2. **向用户确认**:把 `error.action`、`error.risk` 和关键参数展示给用户,明确告知"这是高风险操作",等待用户显式同意
197
197
  3. **用户同意** → 在你**原始 argv 的末尾追加 `--yes`** 后重试
198
198
  4. **用户拒绝** → 终止流程,不要擅自改写参数或跳过门禁
199
199