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

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 (62) hide show
  1. package/package.json +2 -2
  2. package/skills/lark-apps/SKILL.md +29 -2
  3. package/skills/lark-base/SKILL.md +4 -3
  4. package/skills/lark-base/references/lark-base-data-query-guide.md +8 -0
  5. package/skills/lark-base/references/lark-base-field-create.md +19 -8
  6. package/skills/lark-base/references/lark-base-field-json.md +3 -2
  7. package/skills/lark-doc/SKILL.md +25 -61
  8. package/skills/lark-doc/references/genres/business-analysis.md +30 -0
  9. package/skills/lark-doc/references/genres/data-report.md +32 -0
  10. package/skills/lark-doc/references/genres/email.md +38 -0
  11. package/skills/lark-doc/references/genres/execution-plan.md +27 -0
  12. package/skills/lark-doc/references/genres/formal-doc.md +37 -0
  13. package/skills/lark-doc/references/genres/meeting-minutes.md +24 -0
  14. package/skills/lark-doc/references/genres/memo-brief.md +25 -0
  15. package/skills/lark-doc/references/genres/official-redhead.md +73 -0
  16. package/skills/lark-doc/references/genres/prd.md +26 -0
  17. package/skills/lark-doc/references/genres/proposal.md +24 -0
  18. package/skills/lark-doc/references/genres/research-report.md +32 -0
  19. package/skills/lark-doc/references/genres/retrospective.md +25 -0
  20. package/skills/lark-doc/references/genres/route-consumer.md +37 -0
  21. package/skills/lark-doc/references/genres/route-creative.md +36 -0
  22. package/skills/lark-doc/references/genres/route-knowledge.md +39 -0
  23. package/skills/lark-doc/references/genres/route-marketing.md +40 -0
  24. package/skills/lark-doc/references/genres/route-media.md +36 -0
  25. package/skills/lark-doc/references/genres/route-opinion.md +38 -0
  26. package/skills/lark-doc/references/genres/route-personal-brand.md +36 -0
  27. package/skills/lark-doc/references/genres/route-platform.md +9 -0
  28. package/skills/lark-doc/references/genres/route-report.md +10 -0
  29. package/skills/lark-doc/references/genres/route-workplace.md +17 -0
  30. package/skills/lark-doc/references/genres/sop-tutorial.md +41 -0
  31. package/skills/lark-doc/references/genres/technical-doc.md +39 -0
  32. package/skills/lark-doc/references/genres/wechat.md +39 -0
  33. package/skills/lark-doc/references/genres/weekly-report.md +24 -0
  34. package/skills/lark-doc/references/genres/white-paper.md +32 -0
  35. package/skills/lark-doc/references/genres/xiaohongshu.md +38 -0
  36. package/skills/lark-doc/references/lark-doc-create-workflow.md +121 -0
  37. package/skills/lark-doc/references/lark-doc-create.md +22 -48
  38. package/skills/lark-doc/references/lark-doc-fetch.md +75 -92
  39. package/skills/lark-doc/references/lark-doc-history.md +3 -1
  40. package/skills/lark-doc/references/lark-doc-md.md +5 -1
  41. package/skills/lark-doc/references/lark-doc-script.md +76 -0
  42. package/skills/lark-doc/references/lark-doc-update.md +70 -222
  43. package/skills/lark-doc/references/lark-doc-whiteboard.md +5 -9
  44. package/skills/lark-doc/references/lark-doc-xml-extended-blocks.md +17 -12
  45. package/skills/lark-doc/references/lark-doc-xml.md +38 -167
  46. package/skills/lark-im/SKILL.md +3 -3
  47. package/skills/lark-im/references/lark-im-messages-resources-download.md +19 -25
  48. package/skills/lark-slides/SKILL.md +11 -13
  49. package/skills/lark-slides/references/lark-slides-create.md +70 -39
  50. package/skills/lark-slides/references/lark-slides-edit-workflows.md +4 -7
  51. package/skills/lark-slides/references/lark-slides-update-slide.md +146 -0
  52. package/skills/lark-slides/references/lark-slides-xml-presentations-get.md +26 -3
  53. package/skills/lark-slides/references/slides_chart_demo.xml +0 -1
  54. package/skills/lark-slides/references/troubleshooting.md +6 -6
  55. package/skills/lark-slides/references/validation-checklist.md +1 -1
  56. package/skills/lark-slides/references/xml-schema-quick-ref.md +0 -2
  57. package/skills/lark-doc/references/lark-doc-word-stat.md +0 -93
  58. package/skills/lark-doc/references/style/lark-doc-create-workflow.md +0 -47
  59. package/skills/lark-doc/references/style/lark-doc-style.md +0 -68
  60. package/skills/lark-doc/references/style/lark-doc-update-workflow.md +0 -48
  61. package/skills/lark-doc/scripts/doc_word_stat.py +0 -1243
  62. package/skills/lark-slides/references/lark-slides-replace-pages.md +0 -97
@@ -1,183 +1,54 @@
1
- 基于 HTML 子集的 XML 格式描述飞书文档内容。
2
-
3
- # 一、标准 HTML 标签
4
- p, h1-h9, ul, ol, li, table, thead, tbody, tr, th, td, blockquote, pre, code, hr, img, b, em, u, del, a, br, span 语义不变
5
-
6
- # 二、扩展标签速查表
7
- ## 块级标签
8
- |标签|说明|关键属性|
9
- |-|-|-|
10
- | `<title>` | 文档标题(每篇唯一)| `align` |
11
- | `<checkbox>` | 待办项| `done="true"\|"false"` |
12
-
13
- ## 容器标签
14
- |标签|说明|关键属性|
15
- |-|-|-|
16
- | `<callout>` | 高亮框,子块仅支持文本块(如 `<p>`)、标题、列表、待办、引用;禁止裸文本及 `<table>`、`<img>`、`<pre>`、`<hr>`、`<grid>`、`<whiteboard>`、`<sheet>` 等其他块级标签或资源块 | `emoji`(默认 bulb), `background-color`, `border-color`, `text-color` |
17
- | `<grid>` + `<column>` | 分栏布局,各列 width-ratio 之和为 1 | `width-ratio` |
18
- | `<whiteboard>` | 嵌入画板 | `type`: `blank` \| `mermaid` \| `plantuml` \| `svg` |
19
- | `<pre>` | (代码块,内含 `code`)| `lang`, `caption` |
20
- | `<figure>` | 视图容器 | `view-type` |
21
- | `<bookmark>` | 书签链接 | `<bookmark name="标题" href="https://..."></bookmark>`,必传 name 和 href |
22
-
23
- ## 行内组件
24
- | 标签 | 说明 | 关键属性 |
25
- |-|-|-|
26
- | `<cite type="user">` | @人 | XML 导入时必须显式传入 `user-id`:`<cite type="user" user-id="userID"></cite>` |
27
- | `<cite type="doc">` | @文档 | `<cite type="doc" doc-id="docx_token"></cite>` |
28
- | `<latex>` | 行内公式 | `<latex>E = mc^2</latex>` |
29
- | `<img>` | 图片(可独立成块或内联) | `<img width="800" height="600" caption="说明" name="图.png" href="http 或 https"/>` |
30
- | `<source>` | 文件附件(可独立成块或内联) | `<source name="报告.pdf"/>` |
31
- | `<a type="url-preview">` | 预览卡片 | `<a type="url-preview" href="...">标题</a>` |
32
- | `<button>` | 操作按钮 | `background-color`、`src`,必须包含 `action=OpenLink\|DuplicatePage\|FollowPage` |
33
- | `<time>` | 提醒 | 必包含 `expire-time`、`notify-time`(毫秒时间戳)、`should-notify=true\|false` |
34
-
35
- ## 文本块通用属性
36
- - `align` — `"left"`|`"center"`|`"right"`(适用于 p / h1-h9 / li / checkbox)
37
- - 有序列表项用 `seq="auto"` 自动编号
38
-
39
- # 三、资源块
40
-
41
- 文档中可嵌入外部资源块(属于容器标签的特殊形式),需要额外语法创建:
42
-
43
- - `<img>` — `<img href="https://..."/>` 上传网络图片
44
- - `<whiteboard>` — 简单图由 SubAgent 直接插入 `<whiteboard type="svg">完整自包含 SVG</whiteboard>`;也可用本地文件简写 `<whiteboard type="svg" path="@diagram.svg"></whiteboard>`、`<whiteboard type="mermaid" path="@flow.mmd"></whiteboard>`、`<whiteboard type="plantuml" path="@sequence.puml"></whiteboard>`,CLI 会写入前展开为内联内容;复杂图使用 `<whiteboard type="blank"></whiteboard>` 先创建空白画板,再按 [`lark-doc-whiteboard.md`](lark-doc-whiteboard.md) 启动 SubAgent 调用 `lark-whiteboard` 写入;
45
- - `<sheet>` — `<sheet type="blank"></sheet>` 空白;`<sheet sheet-id="SID" token="TOKEN"></sheet>` 复制已有
46
- - `<task>` — `<task task-id="GUID"></task>`,必传 task-id(任务 guid)
47
- - `<chat_card>` — `<chat_card chat-id="CHAT_ID"></chat_card>`,必传 chat-id
48
- - `<sub-page-list>` — `<sub-page-list></sub-page-list>` 子页面列表块;仅 wiki 文档可插入
49
- - `<html5-block>`、`<okr>` — 前者在飞书文档「HTML 块」iframe 中加载单文件 HTML,内容可用 HTML 渲染时直接使用;后者创建时仅支持 root-only `<okr cycle-id="..."/>` 挂载已有 OKR。完整语法与字段规则见 [`lark-doc-xml-extended-blocks.md`](lark-doc-xml-extended-blocks.md)。
50
- - bitable、base_ref、synced_reference、synced_source — 不可创建,仅支持移动
51
-
52
- # 四、块级复制与移动
53
-
54
- ## 移动(block_move_after)
55
- 支持**所有**块类型(块级标签、容器标签、行内组件、资源块),使用 `docs +update --command block_move_after --block-id "<锚点>" --src-block-ids "id1,id2"`。
56
-
57
- ## 复制(block_copy_insert_after)
58
- - **基础标签**(块级标签、容器标签、行内组件):均支持复制
59
- - **资源块**:仅 img、source、whiteboard、sheet、chat_card、sub-page-list 支持复制;task、bitable、base_ref、synced_reference、synced_source、okr 不支持复制
60
-
61
- 使用 `docs +update --command block_copy_insert_after --block-id "<锚点>" --src-block-ids "id1,id2"`。
62
-
63
- > 详见 [lark-doc-update.md](lark-doc-update.md)。
64
-
65
- # 五、补充规则
66
-
67
- ## 富文本样式嵌套顺序
68
- - 行内样式标签必须按以下固定顺序嵌套(外 → 内),关闭顺序严格反转:`<a> → <b> → <em> → <del> → <u> → <code> → <span> → 文本内容`
69
-
70
- ## 列表分组
71
- - 连续同类型列表项自动合并为一个 `<ul>` 或 `<ol>`
72
- - 嵌套子列表放在 `<li>` 内部
73
- - 新增列表项必须包在 `<ul>` 或 `<ol>` 内:
74
- ```xml
75
- <ul>
76
- <li>第一项</li>
77
- <li>第二项</li>
78
- </ul>
79
- ```
1
+ # 飞书 XML 语法
80
2
 
81
- ## 代码块
82
- - 代码块必须写成 `<pre lang="xxx" caption="可选说明"><code>代码内容</code></pre>`。
83
- - 不要将代码文本直接放在 `<pre>` 下;应放在内层 `<code>` 中。
3
+ **语法采用类 HTML 标签,渲染采用纵向块级文档流:顶层 Block 按文档顺序纵向排列,块内支持富文本和子块嵌套。默认宽度约 820 px,宽版模式约 1020 px**
84
4
 
5
+ 以下为 XML 语法示例,使用时需替换其中的示例值。属性必须写成 `name="value"`,禁止省略引号。
85
6
 
86
- ## 用户名写入规则
7
+ ## 常用标签
87
8
 
88
- - 任何包含 `<cite type="user">` 的 XML 在导入、新建或编辑回写时,都必须显式传入 `user-id`;其值为用户的 `open_id`,不得省略。
89
- - 当从 IM 消息、日历、审批、任务等来源获取到用户的 `open_id` 时,写入文档**必须**使用 `<cite type="user" user-id="open_id">` 标签,而非纯文本名字。这样文档中会渲染为可点击的 @人。
90
- - 典型场景:IM 消息的 `sender`、`mentions`、reactions 的 `operator`、卡片消息中引用的用户、系统消息中的用户名、合并转发中的用户名。
91
- - 当只有纯文本名字而没有 `open_id` 时(如系统消息、合并转发内容),先通过 `lark-cli contact +search-user --query "名字" --as user` 反查 `open_id`,再写入 cite 标签。
9
+ - `p, h1-h9, blockquote, hr, img, b, em, u, del, br, span` 语义不变。普通文档建议只使用 `h1-h6`,`h7-h9` 仅在确需更深层级时使用。
10
+ - `<a type="url-preview" href="URL">链接标题</a>`
11
+ - `<latex>E = mc^2</latex>`:适用行内公式,也适用于上标、下标写法。
12
+ - `<ol><li>第一项<ul><li>子项</li></ul></li><li>第二项</li></ol>`:子列表放在 `<li>` 内;新增列表项必须放在 `<ul>` 或 `<ol>` 内。
13
+ - `<pre lang="go" caption="示例"><code>fmt.Println(&quot;hello&quot;)</code></pre>`:代码必须放在 `<code>` 内,禁止直接放在 `<pre>` 下;`caption` 可省略。
14
+ - `<img path="@./photo.png"/>`:上传当前工作目录内的本地图片。也可用 `<img href="URL"/>` 上传公开 HTTP(S) 网络图片,或用 `<img src="token"/>` 复制原始图片;三者任选一个,可选 `width`、`height`、`caption`、`name`。使用 `href` 时,CLI 会将远程图片转为本地资源并完成上传;响应须为 PNG、JPEG、GIF 或 WebP,单图不超过 20MiB。内部网络图片须先下载到本地再使用 `path`。
15
+ - `<source path="@./report.pdf" name="报告.pdf"/>`:上传本地附件;也可使用 `<source token="token" name="xx"/>` 复制已有附件。可独立使用、放入 `<p>` 作为行内附件,或写成 `<figure view-type="Card|Preview"><source/></figure>`;
16
+ - `<checkbox done="true|false">todo</checkbox>`
17
+ - `p, h1-h9, li, checkbox, title` 支持可选属性 `align`,可选值为 `left`、`center`、`right`,例如 `<p align="center">居中正文</p>`。
92
18
 
93
- ## 表格扩展
94
- 标准 HTML table 结构不变,扩展点:
95
- - `<colgroup>` / `<col>` 定义列宽,紧跟 `<table>` 之后:`<col span="2" width="100"/>`
96
- - `<th>` / `<td>` 增加 `background-color` 和 `vertical-align`(top | middle | bottom)
97
- - 有表头时第一行在 `<thead>` 用 `<th>`,其余在 `<tbody>` 用 `<td>`
98
- - 合并单元格仅起始格输出 `colspan` / `rowspan`,被合并的格不出现
19
+ ## 标题与列表编号
99
20
 
100
- # 六、美化系统
101
- - 颜色优先使用命名色,也可写 `rgb(r,g,b)` / `rgba(r,g,b,a)`。**基础色(7 色)**:red, orange, yellow, green, blue, purple, gray
102
- | 属性 | 支持的命名色 |
103
- |-|-|
104
- | 文字颜色 `<span text-color>` | 基础色 |
105
- | 高亮框字色 `<callout text-color>` | 基础色 |
106
- | 高亮框边框 `<callout border-color>` | 基础色 |
107
- | 文字背景 `<span background-color>` | 基础色 + `light-{色}` + `medium-gray` |
108
- | 高亮框填充 `<callout background-color>` | `gray` + `light-{色}` + `medium-{色}` |
109
- | 单元格背景 `<th/td background-color>` | 同文字背景 |
110
- | 按钮背景 `<button background-color>` | 同文字背景 |
111
- - 常用 emoji: 💡(默认)✅❌📝❓❗👍❤️📌🏁⭐
21
+ - 完整文档以唯一的 `<title>` 开头;正文标题使用 `<h1>` 至 `<h9>`,层级须连续,不跳级,例如 `<h1>` 后不能直接使用 `<h3>`,应先出现 `<h2>`。需要自动编号时设置 `seq="auto"`,系统会按标题层级生成并递增阿拉伯数字编号,例如一级标题为 `1`,二级标题为 `1.1`。
22
+ - 有序列表:默认属性 `seq="auto"`,需从指定数字开始时设置对应值,如 `seq="3"`。
112
23
 
113
- # 七、**重要规则**
114
- ## 转义规则:标签本身 **禁止转义**,只有标签内部的文本内容才需要转义
24
+ ## 表格
115
25
 
116
- **错误** ❌:`&lt;p&gt;内容&lt;/p&gt;`(把标签也转义了)
117
- **正确** ✅:`<p>A &amp; B 的对比:1 &lt; 2</p>`(标签保持原样,文本中的 `&` 和 `<` 才转义)
26
+ - `<table><thead><tr><th><p>表头</p></th></tr></thead><tbody><tr><td><p>内容</p></td></tr></tbody></table>`
27
+ - `<colgroup><col /></colgroup>` 紧跟 `<table>` 定义列宽;`width` 表示列宽,可选 `span` 表示连续作用的列数。
28
+ - `<th>` / `<td>` 支持 `background-color`、`vertical-align`、`colspan`、`rowspan`;`vertical-align`:`top | middle | bottom`;`background-color` 支持基础色相、`light-{色相}`、`medium-gray`,表头优先使用 `light-gray` 或 `medium-gray`,彩色单元格仅用于表达状态或分类。被合并的单元格不再写入。
118
29
 
119
- 转义字符表:
120
- - `<` → `&lt;`
121
- - `>` → `&gt;`
122
- - `&` → `&amp;`
123
- - `\n`(换行符) → `<br/>`
30
+ ## 扩展标签
124
31
 
32
+ - `<cite type="user" user-id="ou_xxx"/>`:@人,会渲染为用户头像;必须显式传入用户 `open_id`,不得用纯文本名字冒充 @人。
33
+ - `<cite type="doc" doc-id="DOC_TOKEN"/>`:@文档,会渲染为文档标题。
34
+ - `<cite type="citation"><a href="URL" url-type="N"></a></cite>`:参考文献容器,仅含多个 `<a>`。`url-type` 标识链接类型:`5`(WebURL)须在`<a></a>`中填写渲染标题;`1`(Docx)、`6`(Minutes)、`12`(Base)、`13`(Sheet)可留空。
35
+ - `<whiteboard></whiteboard>`:`type | src` 二选一。`type=blank` 为新建;`type=mermaid|plantuml|svg` 时,支持 `path=@./file` 导入,也支持在标签内直接写入内容;`src=token` 表示复制已有画板。复杂图需读取 [`lark-doc-whiteboard.md`](lark-doc-whiteboard.md);
36
+ - `<grid><column width-ratio="0.5"><p>左栏</p></column><column width-ratio="0.5"><p>右栏</p></column></grid>`:各列 `width-ratio` 之和为 1。
37
+ - `<callout emoji="💡" background-color="light-*" border-color="*"><p>高亮块内容</p></callout>`:子块仅支持 `p`、`ol`、`ul`、`checkbox`、行内标签;禁止 `<table>`、`<img>`、`<pre>`、`<hr>`、`<grid>`、`<whiteboard>`、等其他块级标签或资源块。可选 `text-color`。
38
+ - 其他扩展标签 `html5-block`、`bookmark`、`button`、`time`、`sheet`、`task`、`chat_card`、`sub-page-list`、`okr` 见 [`lark-doc-xml-extended-blocks.md`](lark-doc-xml-extended-blocks.md)。
125
39
 
126
- # 八、完整示例
40
+ ## 颜色
127
41
 
128
- ```xml
129
- <title>文档标题</title>
42
+ 颜色用于表达语义,并在全文保持一致;默认保持中性色排版,避免仅为装饰而着色。
130
43
 
131
- <h1>一级标题</h1>
44
+ - **合法值**:色相为 `red, orange, yellow, green, blue, purple, gray`;`text-color`、`border-color` 使用基础色相;`<span>`、`<th>`、`<td>`、`<button>` 背景支持基础色相、`light-{色相}`、`medium-gray`;高亮块背景支持 `gray`、`light-{色相}`、`medium-{色相}`。
45
+ - **高亮块**:默认使用 `light-*` 背景和默认文字色;强提醒才使用 `medium-*`,彩色文字只强调短语。
46
+ - **表格**:表头优先使用 `light-gray` 或 `medium-gray`;彩色单元格只表达状态或分类,避免整表铺色。
132
47
 
133
- <p><b>加粗文本</b>,<span text-color="green">绿色文本</span></p>
48
+ ## 转义规则
134
49
 
135
- <callout emoji="💡" background-color="light-yellow" border-color="yellow">
136
- <p>高亮框内容,子块仅支持文本/标题/列表/待办/引用</p>
137
- </callout>
50
+ 禁止转义标签本身;只转义标签内部的文本内容。
138
51
 
139
- <checkbox done="true">已完成事项</checkbox>
140
- <checkbox done="false">未完成事项</checkbox>
141
-
142
- <grid>
143
- <column width-ratio="0.5">
144
- <p>左栏</p>
145
- </column>
146
- <column width-ratio="0.5">
147
- <p>右栏</p>
148
- </column>
149
- </grid>
150
-
151
- <table>
152
- <colgroup><col span="2" width="120"/></colgroup>
153
- <thead><tr><th background-color="light-gray">表头</th><th background-color="light-gray">表头</th></tr></thead>
154
- <tbody><tr><td>单元格</td><td>单元格</td></tr></tbody>
155
- </table>
156
-
157
- <p><cite type="doc" doc-id="DOC_TOKEN"></cite> <cite type="user" user-id="USER_ID"></cite></p>
158
-
159
- <ol><li seq="auto">第一项</li><li seq="auto">第二项</li></ol>
160
-
161
- <p><a type="url-preview" href="https://example.com">链接标题</a></p>
162
-
163
- <p><latex>E = mc^2</latex></p>
164
-
165
- <pre lang="go" caption="示例"><code>fmt.Println("hello")</code></pre>
166
-
167
- <hr/>
168
-
169
- <source name="文件名.pdf"/>
170
- <img src="IMG_TOKEN" width="800" height="400" caption="说明" name="图.png"/>
171
- <img href="https://example.com/photo.png"/>
172
-
173
- <button action="OpenLink" src="https://example.com">按钮文字</button>
174
-
175
- <time expire-time="1775916000000" notify-time="1775912400000" should-notify="false">时间戳毫秒</time>
176
-
177
- <cite type="citation"><a href="https://example.com">引文标题</a></cite>
178
- <bookmark name="书签标题" href="https://example.com"></bookmark>
179
-
180
- <task task-id="TASK_GUID"></task>
181
- <chat_card chat-id="CHAT_ID"></chat_card>
182
- <sub-page-list></sub-page-list>
183
- ```
52
+ - 文本转义:`<` → `&lt;`,`>` → `&gt;`,`&` → `&amp;`,换行符 `\n` → `<br/>`。
53
+ - 错误:`&lt;p&gt;内容&lt;/p&gt;`
54
+ - 正确:`<p>A &amp; B 的对比:1 &lt; 2</p>`
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lark-im
3
3
  version: 1.0.0
4
- description: "飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件(支持大文件分片下载)、管理表情回复、发送应用内/短信/电话加急、发送和处理交互卡片(Interactive Card)、监听卡片按钮回调(card.action.trigger)。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员、搜索群、创建群聊或话题群、管理标记数据、管理 Feed 置顶(添加/移除/查询置顶会话)、管理标签数据、处理卡片回调时使用。"
4
+ description: "飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件、管理表情回复、发送应用内/短信/电话加急、发送和处理交互卡片(Interactive Card)、监听卡片按钮回调(card.action.trigger)。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员、搜索群、创建群聊或话题群、管理标记数据、管理 Feed 置顶(添加/移除/查询置顶会话)、管理标签数据、处理卡片回调时使用。"
5
5
  metadata:
6
6
  requires:
7
7
  bins: ["lark-cli"]
@@ -56,7 +56,7 @@ The four message-pulling shortcuts (`+messages-mget`, `+chat-messages-list`, `+m
56
56
 
57
57
  ### Opt-in resource auto-download (`--download-resources`)
58
58
 
59
- `+chat-messages-list`, `+messages-mget`, and `+threads-messages-list` accept `--download-resources` (**off by default** — no `resources` block and no extra requests when omitted). When set, eligible message resources (image/file/audio/video/media + post-embedded; **stickers excluded**) are downloaded into `./lark-im-resources/` and each message gains a `resources` array of `{message_id, key, type, local_path, size_bytes}`. Downloads are deduped by `(message_id, file_key)`, run with bounded concurrency, and isolate single-resource failures (`error: true` + stderr warning). **Scope:** requires `im:message:readonly` (already declared by the listing commands — no extra scope); works under both user and bot identity. For one-off downloads use [`+messages-resources-download`](references/lark-im-messages-resources-download.md). Full contract: [`references/lark-im-message-enrichment.md`](references/lark-im-message-enrichment.md).
59
+ `+chat-messages-list`, `+messages-mget`, and `+threads-messages-list` accept `--download-resources` to save eligible attachments into `./lark-im-resources/` and add a `resources` array to each message. It is off by default; stickers are not downloadable. A failed attachment is reported on that resource without aborting the message pull. Use [`+messages-resources-download`](references/lark-im-messages-resources-download.md) for one attachment. See [`references/lark-im-message-enrichment.md`](references/lark-im-message-enrichment.md) for the output contract.
60
60
 
61
61
  ### Card Messages (Interactive)
62
62
 
@@ -111,7 +111,7 @@ Shortcut 是对常用操作的高级封装(`lark-cli im +<verb> [flags]`)。
111
111
  | [`+chat-update`](references/lark-im-chat-update.md) | Update group chat name or description; user/bot; updates a chat's name or description |
112
112
  | [`+messages-mget`](references/lark-im-messages-mget.md) | Batch get messages by IDs; user/bot; fetches up to 50 om_ message IDs, formats sender names, expands thread replies |
113
113
  | [`+messages-reply`](references/lark-im-messages-reply.md) | Reply to a message (supports thread replies); user/bot; supports text/markdown/post/media replies, reply-in-thread, idempotency key |
114
- | [`+messages-resources-download`](references/lark-im-messages-resources-download.md) | Download images/files from a message; user/bot; supports automatic chunked download for large files (8MB chunks), auto-detects file extension from Content-Type |
114
+ | [`+messages-resources-download`](references/lark-im-messages-resources-download.md) | Download an image or file attached to a message; user/bot |
115
115
  | [`+messages-search`](references/lark-im-messages-search.md) | Search messages across chats (supports keyword, sender, time range filters) with user or bot identity; filters by chat/sender/attachment/time, supports auto-pagination via `--page-all` / `--page-limit`, enriches results via batched mget and chats batch_query |
116
116
  | [`+messages-send`](references/lark-im-messages-send.md) | Send a message to a chat or direct message; user/bot; sends to chat-id or user-id with text/markdown/post/media, supports idempotency key |
117
117
  | [`+threads-messages-list`](references/lark-im-threads-messages-list.md) | List messages in a thread; user/bot; accepts om_/omt_ input, resolves message IDs to thread_id, supports --order asc/desc sorting, auto-pagination |
@@ -2,11 +2,11 @@
2
2
 
3
3
  > **Prerequisite:** Read [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) first to understand authentication, global parameters, and safety rules.
4
4
 
5
- Download image or file resources from a message. Supports **automatic chunked download for large files** using HTTP Range requests. Resources are identified by the combination of `message_id` + `file_key`, both of which come directly from message content returned by `im +chat-messages-list`.
5
+ Download an image or file attached to a message. Use the `message_id` and resource key returned by a message-reading command; do not guess or combine identifiers from different messages.
6
6
 
7
7
  > **Note:** read-only message commands render resource keys in message content, but they do not download binaries automatically. Use this command whenever you need to fetch the actual image/file bytes or save them to a specific path.
8
8
 
9
- This skill maps to the shortcut: `lark-cli im +messages-resources-download` (internally calls `GET /open-apis/im/v1/messages/{message_id}/resources/{file_key}`).
9
+ Shortcut: `lark-cli im +messages-resources-download`.
10
10
 
11
11
  ## Commands
12
12
 
@@ -34,27 +34,11 @@ lark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_x
34
34
  | `--message-id <id>` | Yes | Message ID (`om_xxx` format) |
35
35
  | `--file-key <key>` | Yes | Resource key (`img_xxx` or `file_xxx`) |
36
36
  | `--type <type>` | Yes | Resource type: `image` or `file` |
37
- | `--output <path>` | No | Output path (relative paths only; `..` traversal is not allowed). When omitted, the server's original filename from `Content-Disposition` is used if available; otherwise defaults to `file_key`. File extension is automatically inferred from `Content-Disposition` or `Content-Type` if not provided |
37
+ | `--output <path>` | No | Relative output path; absolute paths and `..` traversal are rejected. When omitted, the command uses the attachment name when available and otherwise falls back to the resource key |
38
38
  | `--as <identity>` | No | Identity type: `user` (default) or `bot` |
39
39
  | `--dry-run` | No | Print the request only, do not execute it |
40
40
 
41
- ## Large File Download (Auto Chunking)
42
-
43
- When downloading large files, the command automatically uses **HTTP Range requests** for reliable chunked downloading:
44
-
45
- | Behavior | Details |
46
- |----------|---------|
47
- | Probe chunk | First 128 KB to detect file size and Content-Type |
48
- | Chunk size | 8 MB per subsequent request |
49
- | Workers | Single-threaded sequential download (ensures reliability) |
50
- | Retries | Up to 2 retries for transient request failures, with exponential backoff |
51
-
52
- **Benefits:**
53
- - Reduces the impact of transient request failures during large downloads
54
- - Preserves the server's original filename via `Content-Disposition` (supports RFC 5987 UTF-8 encoding); falls back to `Content-Type`-based extension inference
55
- - Validates file size integrity after download completion
56
-
57
- ## `file_key` Sources
41
+ ## Choose `--type`
58
42
 
59
43
  Different resource markers in message content correspond to different `file_key` and `type` values:
60
44
 
@@ -65,6 +49,17 @@ Different resource markers in message content correspond to different `file_key`
65
49
  | Audio | `file_xxx` | `file_xxx` | `file` |
66
50
  | Video | `file_xxx` | `file_xxx` | `file` |
67
51
 
52
+ Stickers cannot be downloaded with this command.
53
+
54
+ ## Output
55
+
56
+ On success, read:
57
+
58
+ | Field | Meaning |
59
+ |------|---------|
60
+ | `data.saved_path` | Saved local path |
61
+ | `data.size_bytes` | Saved byte count |
62
+
68
63
  ## Usage Scenario
69
64
 
70
65
  ### Scenario: Extract and download an image from a message
@@ -82,11 +77,10 @@ lark-cli im +messages-resources-download --message-id om_xxx --file-key img_v3_x
82
77
 
83
78
  | Symptom | Root Cause | Solution |
84
79
  |---------|---------|---------|
85
- | Download failed | `file_key` does not match the `message_id` | Make sure the `file_key` came from that message's content |
86
- | Hit error code 234002 or 14005 | No permission, **not** missing API scope | no access to this chat or file was deleted — do not retry, return the error to the user |
87
- | Permission denied | `im:message:readonly` is not authorized | Run `auth login --scope "im:message:readonly"` |
88
- | File size mismatch | Chunked download integrity check failed | Network instability during download; retry the command |
89
- | Content-Range error | Server returned invalid range header | Transient API issue; retry the command |
80
+ | Resource does not match the message | `file_key` and `message_id` came from different messages | Read the message again and use its matching identifiers |
81
+ | Permission denied | `im:message:readonly` is not authorized | For user identity, run `lark-cli auth login --scope "im:message:readonly"`; for bot identity, grant the scope to the app in the developer console |
82
+ | Attachment unavailable | The message or resource is deleted, hidden, restricted, or inaccessible to the caller | Do not retry unchanged; report the exact CLI error |
83
+ | Retryable network error | The transfer did not complete | Retry the same command |
90
84
 
91
85
  ## References
92
86
 
@@ -79,10 +79,10 @@ metadata:
79
79
 
80
80
  | 用户需求 | 优先动作 | 关键文档 / 命令 |
81
81
  |----------|----------|-----------------|
82
- | 新建 PPT | 先规划 `slide_plan.json`,再按复杂度选择一步或两步创建 | `planning-layer.md`、`visual-planning.md`、`asset-planning.md`、`lark-slides-create.md`、`slides +create`、`slides +add-slide`、`lark-slides-add-slide.md`(两步创建逐页添加) |
82
+ | 新建 PPT | 先规划 `slide_plan.json`,再按页数选择一步或两步创建 | `planning-layer.md`、`visual-planning.md`、`asset-planning.md`、`lark-slides-create.md`、`slides +create`、`slides +add-slide`、`lark-slides-add-slide.md`(两步创建逐页添加) |
83
83
  | 用户要求使用模板,或提供 PPTX 文件要求修改、美化 | 将模板导入为 Slides 再编辑 | `lark-slides-pptx-template-workflows.md` |
84
- | 编辑单个标题、文本块、图片或局部元素 | 优先块级替换/插入,不改页序 | `slides +replace-slide`、`lark-slides-replace-slide.md` |
85
- | 一页改动很多、要改背景或删除若干元素,或要整页重建一页/多页 | 在原 presentation 内按页重建,不创建新 Slides 链接 | `slides +replace-pages`、`lark-slides-replace-pages.md` |
84
+ | 编辑单个标题、文本块、图片或局部元素 | 块级替换/插入,**只动点名的 block,同页其他元素不受影响**;不改页序 | `slides +replace-slide`、`lark-slides-replace-slide.md` |
85
+ | 一页改动很多(批量字体/配色)、要改页面背景、要删掉若干元素 | 整页覆盖,`slide_id` 和页序不变;带原 `id` 写回的元素保留 id,不带 `id` 的会作为新元素插入并拿到新 id;**代价是没写进 `--content` 的元素会被删除,所以改个别元素不要用它** | `slides +update-slide`、`lark-slides-update-slide.md` |
86
86
  | 给已有 PPT 追加或插入页面 | 一次一页,`--slide` 支持 `@file` 绕开 shell 转义 | `slides +add-slide`、`lark-slides-add-slide.md` |
87
87
  | 删除页面 | 按 `slide_id` 单页删除,删前先回读确认 | `slides +delete-slide`、`lark-slides-delete-slide.md` |
88
88
  | 读取或分析已有 PPT | 解析 slides/wiki token,用 shortcut 回读全文 XML 或读取单页 XML,保存 `xml_presentation_id`、`slide_id`、`revision_id` | `slides +xml-get`、`xml_presentation.slide.get`、`lark-slides-xml-presentations-get.md` |
@@ -106,15 +106,13 @@ metadata:
106
106
 
107
107
  **CRITICAL — 新建演示文稿或大幅改写页面时,规划 `asset_need` MUST 遵循 [asset-planning.md](references/asset-planning.md):只做元数据规划,必须有 `fallback_if_missing`,不得要求真实搜索、下载或上传素材。**
108
108
 
109
- **CRITICAL — 将完整 `<slide>` XML 提交给 `slides +create --slides`、`slides +add-slide`、`xml_presentation.slide create` 或 `slides +replace-pages` 之前,MUST 先把待提交 XML 保存到本地文件并运行唯一版式准出入口 [`scripts/xml_text_overlap_lint.py`](scripts/xml_text_overlap_lint.py);`summary.error_count` 必须为 0 才能调用接口。**
109
+ **CRITICAL — 将完整 `<slide>` XML 提交给 `slides +create`、`slides +add-slide` 或 `slides +update-slide` 之前,MUST 先把待提交 XML 保存到本地文件并运行唯一版式准出入口 [`scripts/xml_text_overlap_lint.py`](scripts/xml_text_overlap_lint.py);`summary.error_count` 必须为 0 才能调用接口。**
110
110
 
111
- **CRITICAL — 创建或大幅改写后,MUST 按 [validation-checklist.md](references/validation-checklist.md) 做显式验证:回读全文 XML、核对页数和关键元素,并使用 [`scripts/xml_text_overlap_lint.py`](scripts/xml_text_overlap_lint.py) 统一检查 XML、越界、重叠、空白页和内容稀疏风险。**
111
+ **CRITICAL — 创建、大幅改写或每次通过 `slides +update-slide` 整页写回后,MUST 按 [validation-checklist.md](references/validation-checklist.md) 做显式验证:回读全文 XML、核对页数和关键元素,并使用 [`scripts/xml_text_overlap_lint.py`](scripts/xml_text_overlap_lint.py) 统一检查 XML、越界、重叠、空白页和内容稀疏风险。**
112
112
 
113
113
  **CRITICAL — 创建前自检或失败排障时,MUST 按 [troubleshooting.md](references/troubleshooting.md) 检查 XML 转义、结构、shell 截断、图片 token、3350001 和布局风险。**
114
114
 
115
- **CRITICAL — 当前 Slide Engine 后端仍在灰度期间,`slides +replace-pages --help` 及其输出中的 `deprecated` 字段会提示改用 `+update-slide`,该提示在本 skill 生效期间暂不适用;MUST 忽略该提示并继续使用 `+replace-pages`,不得切换到 `+update-slide`。后端全量并由新版 skill 恢复路由后,再使用 `+update-slide`。**
116
-
117
- **编辑已有幻灯片页面**:单个标题、文本块、图片或局部元素优先用 [`+replace-slide`](references/lark-slides-replace-slide.md)(块级替换/插入,不动页序);一页改动很多、要改背景或删除若干元素,以及一页或多页的整页重建,优先用 [`+replace-pages`](references/lark-slides-replace-pages.md) 在原 presentation 内按页重建,避免 `slides +create` 生成新链接。选择 action 和完整读-改-写流程见 [`lark-slides-edit-workflows.md`](references/lark-slides-edit-workflows.md)。
115
+ **编辑已有幻灯片页面**:单个标题、文本块、图片或局部元素优先用 [`+replace-slide`](references/lark-slides-replace-slide.md)(块级替换/插入,不动页序);一页里改动很多(例如批量换字体)、要改背景、或要删掉若干元素时用 [`+update-slide`](references/lark-slides-update-slide.md) 整页覆盖(`slide_id` 和页序不变,但没写进 `--content` 的元素会被删除);**多页大改就对每一页各跑一次 `+update-slide`**。选择 action 和完整读-改-写流程见 [`lark-slides-edit-workflows.md`](references/lark-slides-edit-workflows.md)。
118
116
 
119
117
  **用户要求使用模板**:按 [lark-slides-pptx-template-workflows.md](references/lark-slides-pptx-template-workflows.md) 处理。
120
118
 
@@ -153,7 +151,7 @@ lark-cli auth login --domain slides
153
151
  - 创建:[`lark-slides-create.md`](references/lark-slides-create.md)、[`lark-slides-add-slide.md`](references/lark-slides-add-slide.md)(逐页添加 / 给已有 PPT 追加页面)
154
152
  - 删除页面:[`lark-slides-delete-slide.md`](references/lark-slides-delete-slide.md)
155
153
  - 阅读:[`lark-slides-xml-presentations-get.md`](references/lark-slides-xml-presentations-get.md)
156
- - 编辑:[`lark-slides-edit-workflows.md`](references/lark-slides-edit-workflows.md)、[`lark-slides-replace-slide.md`](references/lark-slides-replace-slide.md)、[`lark-slides-replace-pages.md`](references/lark-slides-replace-pages.md)
154
+ - 编辑:[`lark-slides-edit-workflows.md`](references/lark-slides-edit-workflows.md)、[`lark-slides-replace-slide.md`](references/lark-slides-replace-slide.md)、[`lark-slides-update-slide.md`](references/lark-slides-update-slide.md)
157
155
  - 历史版本:[`lark-slides-history.md`](references/lark-slides-history.md)
158
156
  - 截图:[`lark-slides-screenshot.md`](references/lark-slides-screenshot.md)
159
157
  - 图片:[`lark-slides-media-upload.md`](references/lark-slides-media-upload.md)
@@ -249,7 +247,7 @@ N. 结尾页:[结尾文案]
249
247
  | URL 格式 | 示例 | Token 类型 | 处理方式 |
250
248
  |----------|------|-----------|----------|
251
249
  | `/slides/` | `https://example.larkoffice.com/slides/xxxxxxxxxxxxx` | `xml_presentation_id` | URL 路径中的 token 直接作为 `xml_presentation_id` 使用 |
252
- | `/wiki/` | `https://example.larkoffice.com/wiki/wikcnxxxxxxxxx` | `wiki_token` | ⚠️ **不能直接使用**,需要先查询获取真实的 `obj_token` |
250
+ | `/wiki/` | `https://xxx.feishu.cn/wiki/wikcn_EXAMPLE_NODE_TOKEN_123456` | `wiki_token` | ⚠️ **不能直接使用**,需要先查询获取真实的 `obj_token` |
253
251
 
254
252
  > 带 `--presentation` 的 slides shortcut 都会自动解析以上两种 URL;直接调用原生 API 时仍需手动解析 wiki 链接。
255
253
 
@@ -258,7 +256,7 @@ N. 结尾页:[结尾文案]
258
256
  知识库链接(`/wiki/TOKEN`)不能直接当 `xml_presentation_id`。直接调用原生 API 前,先用 Wiki shortcut 查询节点,确认 `data.obj_type == "slides"`,再用 `data.obj_token` 作为真实 presentation ID。
259
257
 
260
258
  ```bash
261
- lark-cli wiki +node-get --node-token '<wiki_url>' --as user --format json
259
+ lark-cli wiki +node-get --node-token 'https://xxx.feishu.cn/wiki/wikcn_EXAMPLE_NODE_TOKEN_123456' --as user --format json
262
260
  ```
263
261
 
264
262
  节点解析必须与后续 Slides 操作使用相同身份;下游明确使用 `--as bot` 时,这里也改为 `--as bot`。
@@ -292,7 +290,7 @@ Shortcut 是对常用操作的高级封装(`lark-cli slides +<verb> [flags]`
292
290
  | [`+screenshot`](references/lark-slides-screenshot.md) | 把幻灯片页面截图保存为本地图片;用 `--slide-number` 指定页码(从 1 开始,多页重复传入)或用 `--slide-id` 指定页面;单张用 `--output .lark-slides/screenshots/<deck-or-task-id>/page-01`,批量用 `--output-dir .lark-slides/screenshots/<deck-or-task-id>`(一次最多 10 页);后续必须读取返回的 `output` / `screenshots[].path` |
293
291
  | [`+media-upload`](references/lark-slides-media-upload.md) | 上传本地图片到指定演示文稿,返回 `file_token`(用作 `<img src="...">`),最大 20 MB |
294
292
  | [`+replace-slide`](references/lark-slides-replace-slide.md) | 对已有幻灯片页面进行块级替换/插入(`block_replace` / `block_insert`),自动注入 id 和 `<content/>`,不改变页序 |
295
- | [`+replace-pages`](references/lark-slides-replace-pages.md) | 在原演示文稿内重建一页或多页:先创建新页到旧页前,再删除旧页;适合已有 Slides 的整页大改,不新建链接 |
293
+ | [`+update-slide`](references/lark-slides-update-slide.md) | 把一整页 XML 交给已有页面,页面变成 `--content` 描述的样子;能一次改样式/插入/删除/备注/背景,`slide_id` 和页序不变。**没写进 `--content` 的元素会被删除** |
296
294
 
297
295
  没有 Shortcut 覆盖时使用原生 API。高频资源:`slides +xml-get` 读取全文;`xml_presentation.slide.create/delete/get/replace` 管理单页。
298
296
 
@@ -311,7 +309,7 @@ lark-cli slides <resource> <method> [flags] # 调用 API
311
309
  4. **文本通过 `<content>` 表达**:必须用 `<content><p>...</p></content>`,不能把文字直接写在 shape 内;注意 `<content>` 只是 XML 元素,不是 `--parts` 的字段名——part 里装 XML 的字段,`block_replace` 是 `replacement`,`block_insert` 是 `insertion`
312
310
  5. **保存关键 ID**:后续操作需要 `xml_presentation_id`、`slide_id`、`revision_id`
313
311
  6. **删除谨慎**:删除不可逆,删前先回读确认 `slide_id`
314
- 7. **编辑已有页面优先原链接更新**:修改单个 shape/img 用 `+replace-slide`(`block_replace` / `block_insert`),不要整页重建;一页改动很多、要改背景或删除若干元素,以及一页或多页的整页重建,用 `+replace-pages`,不要用 `slides +create` 新建整份 PPT;追加/插入单页用 `+add-slide`、删除单页用 `+delete-slide`,只有这些 shortcut 未覆盖的参数才手动调 `slide.create` / `slide.delete`
312
+ 7. **编辑已有页面优先原链接更新**:修改单个 shape/img 用 `+replace-slide`(`block_replace` / `block_insert`),不要整页重建;一页改动很多或要改背景用 `+update-slide` 整页覆盖(保 `slide_id` 和页序),多页整页重建就对每页各跑一次 `+update-slide`,不要用 `slides +create` 新建整份 PPT;追加/插入单页用 `+add-slide`、删除单页用 `+delete-slide`,只有这些 shortcut 未覆盖的参数才手动调 `slide.create` / `slide.delete`
315
313
  8. **`<img src>` 只能用上传到飞书 drive 的 `file_token`,禁止使用 http(s) 外链 URL**:飞书 slides 渲染端不会代理外链图片,外链 src 在 PPT 里通常不显示或显示破图。流程必须是「先把图存到本地 → 用 `slides +media-upload` 上传,或在 `+create --slides` 的 XML 里写 `<img src="@./path">` 占位符自动上传 → 拿 `file_token` 写进 `<img src>`」。如果用户给了网图链接,先 `curl`/下载到 CWD 内再走上传流程,不要直接把外链 URL 塞进 `src`。**图片最大 20 MB**(slides upload API 不支持分片上传)。
316
314
 
317
315
  > **注意**:如果 md 内容与 `slides_xml_schema_definition.xml` 或 `lark-cli schema slides.<resource>.<method>` 输出不一致,以后两者为准。
@@ -11,14 +11,14 @@
11
11
 
12
12
  | 场景 | 推荐方式 |
13
13
  |------|----------|
14
- | 简单 XML(1-3 页、结构简单、几乎无复杂中文和特殊字符) | `slides +create --slides '[...]'` 一步创建 |
15
- | 复杂 XML(多页、含中文、大段文本、复杂布局、嵌套引号、特殊字符较多) | **两步创建**:先 `slides +create` 创建空白 PPT,再用 [`+add-slide`](lark-slides-add-slide.md) 逐页添加(`--slide @file` 可绕开 shell 转义) |
14
+ | 不超过 10 页 | 每页存一个 XML 文件,`slides +create --slide @page-01.xml --slide @page-02.xml ...` 一步创建 |
15
+ | 超过 10 页 | **两步创建**:先 `slides +create` 创建空白 PPT,再用 [`+add-slide`](lark-slides-add-slide.md) 逐页添加 |
16
16
  | 已有 PPT 继续追加或插入页面 | 使用 [`+add-slide`](lark-slides-add-slide.md),必要时配合 `--before-slide-id` |
17
17
 
18
- > [!WARNING]
19
- > `--slides '[...]'` 的风险点主要在 shell 参数传递,而不是单纯页数。即使只有 1 页,只要 XML 足够复杂,也建议使用两步创建法。
20
18
  > [!IMPORTANT]
21
- > `slides +create --slides` 底层会逐页创建,不是原子操作。中途失败时先记录 `xml_presentation_id`,回读确认当前状态,再继续修复或追加。
19
+ > `slides +create` 带页面时底层会逐页创建,不是原子操作。中途失败时先记录 `xml_presentation_id`,回读确认当前状态,再继续修复或追加。
20
+
21
+ **CRITICAL — 提交前必须先跑版式 lint**:把待提交的 `<slide>` XML 存成本地文件,运行 [`scripts/xml_text_overlap_lint.py`](../scripts/xml_text_overlap_lint.py),`summary.error_count` 必须为 0。
22
22
 
23
23
  ## 命令
24
24
 
@@ -26,31 +26,22 @@
26
26
  # 创建空白 PPT
27
27
  lark-cli slides +create --title "项目汇报"
28
28
 
29
- # 创建 PPT + 添加 slide 页面
30
- lark-cli slides +create --title "项目汇报" --slides '[
31
- "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data><shape type=\"text\" topLeftX=\"80\" topLeftY=\"80\" width=\"800\" height=\"120\"><content textType=\"title\"><p>封面</p></content></shape></data></slide>",
32
- "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data><shape type=\"text\" topLeftX=\"80\" topLeftY=\"80\" width=\"800\" height=\"120\"><content textType=\"title\"><p>第二页</p></content></shape></data></slide>"
33
- ]'
29
+ # 创建 PPT + 添加页面:每页一个 XML 文件,重复 --slide,顺序即页序
30
+ lark-cli slides +create --as user --title "项目汇报" \
31
+ --slide @.lark-slides/plan/project/slide-01.xml \
32
+ --slide @.lark-slides/plan/project/slide-02.xml
33
+
34
+ # 已有组装好的 JSON 数组:从文件或 stdin 读
35
+ lark-cli slides +create --as user --title "项目汇报" --slides @./deck.json
36
+ cat deck.json | lark-cli slides +create --as user --title "项目汇报" --slides -
34
37
 
35
38
  # 以应用身份创建(自动授权当前用户)
36
39
  lark-cli slides +create --title "项目汇报" --as bot
37
40
 
38
41
  # 预览(不执行)
39
- lark-cli slides +create --title "项目汇报" --slides '[...]' --dry-run
40
- ```
41
-
42
- 用 `--slides` 一步创建时,按页保存 XML,再用 `jq --rawfile` 组装参数,不要手写转义:
43
-
44
- ```bash
45
- lark-cli slides +create --as user --title "项目汇报" \
46
- --slides "$(jq -n \
47
- --rawfile s1 .lark-slides/plan/project/slide-01.xml \
48
- --rawfile s2 .lark-slides/plan/project/slide-02.xml \
49
- '[$s1, $s2]')"
42
+ lark-cli slides +create --title "项目汇报" --slide @./slide-01.xml --dry-run
50
43
  ```
51
44
 
52
- `--rawfile` 会把文件内容作为字符串读入 JSON,自动处理 XML 中的引号和换行;不要手动拼接带大量转义符的 JSON 字符串。
53
-
54
45
  ## 返回值
55
46
 
56
47
  工具成功执行后,返回一个 JSON 对象,包含以下字段:
@@ -59,15 +50,15 @@ lark-cli slides +create --as user --title "项目汇报" \
59
50
  - **`title`**(string):演示文稿标题
60
51
  - **`url`**(string,可选):演示文稿的在线链接,如有返回则务必展示给用户(需要 drive 相关权限;若获取失败则不返回此字段)
61
52
  - **`revision_id`**(integer):演示文稿版本号
62
- - **`slide_ids`**(string[],可选):仅传 `--slides` 时返回,成功添加的页面 ID 列表
63
- - **`slides_added`**(integer,可选):仅传 `--slides` 时返回,成功添加的页面数量
64
- - **`images_uploaded`**(integer,可选):仅 `--slides` 中含 `@<本地路径>` 占位符时返回,已上传的去重后图片数量
53
+ - **`slide_ids`**(string[],可选):带页面创建时返回,成功添加的页面 ID 列表
54
+ - **`slides_added`**(integer,可选):带页面创建时返回,成功添加的页面数量
55
+ - **`images_uploaded`**(integer,可选):页面 XML 中含 `@<本地路径>` 占位符时返回,已上传的去重后图片数量
65
56
  - **`permission_grant`**(object,可选):仅 `--as bot` 时返回,说明是否已自动为当前 CLI 用户授予可管理权限
66
57
 
67
58
  > [!IMPORTANT]
68
- > 不传 `--slides` 时,`slides +create` 只创建空白演示文稿。创建后用 [`+add-slide`](lark-slides-add-slide.md) 逐页添加 slide 内容。
59
+ > 不带页面参数时,`slides +create` 只创建空白演示文稿。创建后用 [`+add-slide`](lark-slides-add-slide.md) 逐页添加 slide 内容。
69
60
  >
70
- > 传了 `--slides` 时,CLI 先创建空白演示文稿,再逐页调用 slide 创建接口添加页面。如果某一页添加失败,CLI 会停止并报错,已创建的演示文稿和已添加的页面会保留。
61
+ > 带了页面时,CLI 先创建空白演示文稿,再逐页调用 slide 创建接口添加页面。如果某一页添加失败,CLI 会停止并报错,已创建的演示文稿和已添加的页面会保留。
71
62
  >
72
63
  > 如果演示文稿是**以应用身份(bot)创建**的,如 `lark-cli slides +create --as bot`,CLI 会**尝试为当前 CLI 用户自动授予该演示文稿的 `full_access`(可管理权限)**。
73
64
  >
@@ -83,27 +74,67 @@ lark-cli slides +create --as user --title "项目汇报" \
83
74
  | 参数 | 必填 | 说明 |
84
75
  |------|------|------|
85
76
  | `--title` | 否 | 演示文稿标题(不传则默认 "Untitled") |
86
- | `--slides` | 否 | slide 内容 JSON 数组,每个元素是一个 `<slide>` XML 字符串(最多 10 个;超过 10 页请先用 `+create` 创建空白 PPT,再用 [`+add-slide`](lark-slides-add-slide.md) 逐页添加) |
77
+ | `--slide` | 否 | 一页 `<slide>` XML,或 `@路径`;可重复,最多 10 次。格式见[页面输入形式](#页面输入形式) |
78
+ | `--slides` | 否 | 页面 XML 的 JSON 字符串数组,最多 10 个;支持 `@文件` 和 `-`(stdin)。格式见[页面输入形式](#页面输入形式) |
79
+
80
+ 10 页是 CLI 的上限,服务端每次只接收一页。超过 10 页时先用 `+create` 创建空白 PPT,再用 [`+add-slide`](lark-slides-add-slide.md) 逐页添加。
81
+
82
+ 两种形式的每一页都会在发请求前校验成「单个完整的 `<slide>` 文档」。不合格的页在创建演示文稿之前报错并指出页序号,不会留下空壳演示文稿。
83
+
84
+ ## 页面输入形式
85
+
86
+ 页面内容有 `--slide` 和 `--slides` 两种传法,二选一,同时传会报错。
87
87
 
88
- ## `--slides` 参数格式
88
+ 两种形式的 `@路径` 都必须是 CWD 内的相对路径(如 `./slide-01.xml`);绝对路径和 `../` 会被拒(报 `invalid file path`)。XML 写在别的目录时,先 `cd` 过去或把文件拷进 CWD 再执行。
89
+
90
+ ### `--slide`:一页一个文件
91
+
92
+ 可重复,重复次数即页数,出现顺序即页序。值是一页完整的 `<slide>` XML,或读取该 XML 的 `@路径`。
93
+
94
+ 文件内容就是这一页 XML 本身,外面没有引号或方括号:
95
+
96
+ ```xml
97
+ <slide xmlns="https://www.larkoffice.com/sml/2.0">
98
+ <data>…第1页…</data>
99
+ </slide>
100
+ ```
101
+
102
+ 文件内容不需要转义:引号、换行、中文原样写。
103
+
104
+ ### `--slides`:一个 JSON 数组
105
+
106
+ 值是 JSON 字符串数组,每个元素是一整页 XML,支持 `@文件` 和 `-`(stdin)。
107
+
108
+ 文件内容是一个 JSON 文档,XML 以 JSON 字符串出现,其中的 `"` 写作 `\"`,换行写作 `\n`:
89
109
 
90
110
  ```json
91
111
  [
92
- "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\">...第1页XML...</slide>",
93
- "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\">...第2页XML...</slide>"
112
+ "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data>…第1页…</data></slide>",
113
+ "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data>…第2页…</data></slide>"
94
114
  ]
95
115
  ```
96
116
 
97
- JSON string 数组,每个元素是一页 slide 的完整 XML。CLI 内部负责包装成 API 所需的 `{"slide": {"content": "..."}}` 格式并逐页调用。
117
+ 数组元素是页面 XML 原文。包装成 API 所需的 `{"slide": {"content": …}}` 并逐页调用由 CLI 完成。
118
+
119
+ > [!WARNING]
120
+ > `--slides '[...]'` 的风险点主要在 shell 参数传递,而不是单纯页数。即使只有 1 页,只要 XML 足够复杂,也建议改用 `--slide @page-01.xml` 逐页传文件。
98
121
 
99
- ### 本地图片:`@<path>` 占位符
122
+ ## 本地图片:`@<path>` 占位符
100
123
 
101
124
  `<img>` 元素的 `src` 属性如果以 `@` 开头,CLI 会把它当作本地文件路径,自动上传到当前演示文稿,并把占位符替换为返回的 `file_token`。
102
125
 
126
+ `slide-01.xml`:
127
+
128
+ ```xml
129
+ <slide xmlns="https://www.larkoffice.com/sml/2.0">
130
+ <data>
131
+ <img src="@./assets/chart.png" topLeftX="100" topLeftY="100" width="320" height="180"/>
132
+ </data>
133
+ </slide>
134
+ ```
135
+
103
136
  ```bash
104
- lark-cli slides +create --as user --title "图测试" --slides '[
105
- "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data><img src=\"@./assets/chart.png\" topLeftX=\"100\" topLeftY=\"100\" width=\"320\" height=\"180\"/></data></slide>"
106
- ]'
137
+ lark-cli slides +create --as user --title "图测试" --slide @./slide-01.xml
107
138
  ```
108
139
 
109
140
  行为:
@@ -120,11 +151,11 @@ lark-cli slides +create --as user --title "图测试" --slides '[
120
151
 
121
152
  ## 创建后续步骤
122
153
 
123
- 如果没有使用 `--slides`,`slides +create` 返回的 `xml_presentation_id` 用于后续操作:
154
+ 创建空白 PPT 时,`slides +create` 返回的 `xml_presentation_id` 用于后续操作:
124
155
 
125
156
  ```bash
126
157
  # 第 1 步:创建空白 PPT
127
- PRES_ID=$(lark-cli slides +create --title "项目汇报" | jq -r '.data.xml_presentation_id')
158
+ PRES_ID=$(lark-cli slides +create --title "项目汇报" --jq '.data.xml_presentation_id')
128
159
 
129
160
  # 第 2 步:逐页添加(--slide 支持 @file,复杂 XML 优先走文件)
130
161
  lark-cli slides +add-slide --as user \