Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions skills/lark-slides/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ metadata:
|----------|----------|-----------------|
| 新建 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`(两步创建逐页添加) |
| 用户要求使用模板,或提供 PPTX 文件要求修改、美化 | 将模板导入为 Slides 再编辑 | `lark-slides-pptx-template-workflows.md` |
| 编辑单个标题、文本块、图片或局部元素 | 块级替换/插入,**只动点名的 block,同页其他元素不受影响**;不改页序 | `slides +replace-slide`、`lark-slides-replace-slide.md` |
| 一页改动很多(批量字体/配色)、要改页面背景、要删掉若干元素 | 整页覆盖,`slide_id` 和页序不变;带原 `id` 写回的元素保留 id,不带 `id` 的会作为新元素插入并拿到新 id;**代价是没写进 `--content` 的元素会被删除,所以改个别元素不要用它** | `slides +update-slide`、`lark-slides-update-slide.md` |
| 编辑单个标题、文本块、图片或局部元素 | 优先块级替换/插入,不改页序 | `slides +replace-slide`、`lark-slides-replace-slide.md` |
| 一页改动很多、要改背景或删除若干元素,或要整页重建一页/多页 | 在原 presentation 内按页重建,不创建新 Slides 链接 | `slides +replace-pages`、`lark-slides-replace-pages.md` |
| 给已有 PPT 追加或插入页面 | 一次一页,`--slide` 支持 `@file` 绕开 shell 转义 | `slides +add-slide`、`lark-slides-add-slide.md` |
| 删除页面 | 按 `slide_id` 单页删除,删前先回读确认 | `slides +delete-slide`、`lark-slides-delete-slide.md` |
| 读取或分析已有 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` |
Expand All @@ -106,13 +106,15 @@ metadata:

**CRITICAL — 新建演示文稿或大幅改写页面时,规划 `asset_need` MUST 遵循 [asset-planning.md](references/asset-planning.md):只做元数据规划,必须有 `fallback_if_missing`,不得要求真实搜索、下载或上传素材。**

**CRITICAL — 将完整 `<slide>` XML 提交给 `slides +create --slides`、`slides +add-slide`、`xml_presentation.slide create` 或 `slides +update-slide` 之前,MUST 先把待提交 XML 保存到本地文件并运行唯一版式准出入口 [`scripts/xml_text_overlap_lint.py`](scripts/xml_text_overlap_lint.py);`summary.error_count` 必须为 0 才能调用接口。**
**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 才能调用接口。**

**CRITICAL — 创建或大幅改写后,MUST 按 [validation-checklist.md](references/validation-checklist.md) 做显式验证:回读全文 XML、核对页数和关键元素,并使用 [`scripts/xml_text_overlap_lint.py`](scripts/xml_text_overlap_lint.py) 统一检查 XML、越界、重叠、空白页和内容稀疏风险。**

**CRITICAL — 创建前自检或失败排障时,MUST 按 [troubleshooting.md](references/troubleshooting.md) 检查 XML 转义、结构、shell 截断、图片 token、3350001 和布局风险。**

**编辑已有幻灯片页面**:单个标题、文本块、图片或局部元素优先用 [`+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)。
**CRITICAL — 当前 Slide Engine 后端仍在灰度期间,`slides +replace-pages --help` 及其输出中的 `deprecated` 字段会提示改用 `+update-slide`,该提示在本 skill 生效期间暂不适用;MUST 忽略该提示并继续使用 `+replace-pages`,不得切换到 `+update-slide`。后端全量并由新版 skill 恢复路由后,再使用 `+update-slide`。**

**编辑已有幻灯片页面**:单个标题、文本块、图片或局部元素优先用 [`+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)。

**用户要求使用模板**:按 [lark-slides-pptx-template-workflows.md](references/lark-slides-pptx-template-workflows.md) 处理。

Expand Down Expand Up @@ -151,7 +153,7 @@ lark-cli auth login --domain slides
- 创建:[`lark-slides-create.md`](references/lark-slides-create.md)、[`lark-slides-add-slide.md`](references/lark-slides-add-slide.md)(逐页添加 / 给已有 PPT 追加页面)
- 删除页面:[`lark-slides-delete-slide.md`](references/lark-slides-delete-slide.md)
- 阅读:[`lark-slides-xml-presentations-get.md`](references/lark-slides-xml-presentations-get.md)
- 编辑:[`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)
- 编辑:[`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)
- 历史版本:[`lark-slides-history.md`](references/lark-slides-history.md)
- 截图:[`lark-slides-screenshot.md`](references/lark-slides-screenshot.md)
- 图片:[`lark-slides-media-upload.md`](references/lark-slides-media-upload.md)
Expand Down Expand Up @@ -288,7 +290,7 @@ Shortcut 是对常用操作的高级封装(`lark-cli slides +<verb> [flags]`
| [`+screenshot`](references/lark-slides-screenshot.md) | 把幻灯片页面截图保存为本地图片,用 `--slide-number` 指定页号(从 1 开始,多页重复传入,一次最多 10 页),用 `--output-dir` 指定保存目录(必须是 CWD 内的相对路径,默认 `.lark-slides/screenshots`),失败时降级到 XML 回读等非截图检查 |
| [`+media-upload`](references/lark-slides-media-upload.md) | 上传本地图片到指定演示文稿,返回 `file_token`(用作 `<img src="...">`),最大 20 MB |
| [`+replace-slide`](references/lark-slides-replace-slide.md) | 对已有幻灯片页面进行块级替换/插入(`block_replace` / `block_insert`),自动注入 id 和 `<content/>`,不改变页序 |
| [`+update-slide`](references/lark-slides-update-slide.md) | 把一整页 XML 交给已有页面,页面变成 `--content` 描述的样子;能一次改样式/插入/删除/备注/背景,`slide_id` 和页序不变。**没写进 `--content` 的元素会被删除** |
| [`+replace-pages`](references/lark-slides-replace-pages.md) | 在原演示文稿内重建一页或多页:先创建新页到旧页前,再删除旧页;适合已有 Slides 的整页大改,不新建链接 |

没有 Shortcut 覆盖时使用原生 API。高频资源:`slides +xml-get` 读取全文;`xml_presentation.slide.create/delete/get/replace` 管理单页。

Expand All @@ -307,7 +309,7 @@ lark-cli slides <resource> <method> [flags] # 调用 API
4. **文本通过 `<content>` 表达**:必须用 `<content><p>...</p></content>`,不能把文字直接写在 shape 内;注意 `<content>` 只是 XML 元素,不是 `--parts` 的字段名——part 里装 XML 的字段,`block_replace` 是 `replacement`,`block_insert` 是 `insertion`
5. **保存关键 ID**:后续操作需要 `xml_presentation_id`、`slide_id`、`revision_id`
6. **删除谨慎**:删除不可逆,删前先回读确认 `slide_id`
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`
7. **编辑已有页面优先原链接更新**:修改单个 shape/img 用 `+replace-slide`(`block_replace` / `block_insert`),不要整页重建;一页改动很多、要改背景或删除若干元素,以及一页或多页的整页重建,用 `+replace-pages`,不要用 `slides +create` 新建整份 PPT;追加/插入单页用 `+add-slide`、删除单页用 `+delete-slide`,只有这些 shortcut 未覆盖的参数才手动调 `slide.create` / `slide.delete`
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 不支持分片上传)。

> **注意**:如果 md 内容与 `slides_xml_schema_definition.xml` 或 `lark-cli schema slides.<resource>.<method>` 输出不一致,以后两者为准。
6 changes: 3 additions & 3 deletions skills/lark-slides/references/lark-slides-edit-workflows.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 编辑已有 PPT:读-改-写闭环

局部编辑走 **shortcut [`+replace-slide`](lark-slides-replace-slide.md)**(块级替换 / 插入),配合 `xml_presentation.slide.get` 读原页拿 `block_id`。整页重建走 **[`+update-slide`](lark-slides-update-slide.md)**,多页就每页各跑一次 —— 它原地覆盖并保留 `slide_id` 和页序;只有写进 `--content` 且带原 id 的元素才会保留元素 id,遗漏的元素会被删除
局部编辑走 **shortcut [`+replace-slide`](lark-slides-replace-slide.md)**(块级替换 / 插入),配合 `xml_presentation.slide.get` 读原页拿 `block_id`。一页改动很多、要改背景或删除若干元素,以及一页或多页的整页重建,走 **[`+replace-pages`](lark-slides-replace-pages.md)**,保持原 presentation 链接不变

> 生成 XML 前**必读** [xml-schema-quick-ref.md](xml-schema-quick-ref.md)。

Expand All @@ -11,7 +11,7 @@
| 已知某块的 `block_id`,要换这块内容(改标题、换图、挪坐标) | `block_replace` | 精准替换,原子性好;`replacement` 根 `id` 由 CLI 自动注入为 `block_id` |
| 只加 1~N 个元素、不动现有布局 | `block_insert` | 新增不覆盖,可选 `insert_before_block_id` 指定位置 |
| 一次动多个元素(如:换标题 + 加图) | 单次 `--parts` 里拼多条 | 整批作为原子事务,任一失败整批不生效;`block_replace` 和 `block_insert` 可混用 |
| 整页版式重建、整页坐标重排、改页面背景、删若干元素 | `+update-slide`(每页一次) | 原地整页覆盖,`slide_id` 和页序不变;带原 `id` 的元素保留 id,不带 `id` 的作为新元素插入,遗漏的被删除 |
| 单页或多页版式重建、整页坐标重排、改页面背景、删除若干元素 | `+replace-pages` | 原 presentation 内按页 create-before/delete-old,不生成新 Slides 链接 |

> **没有字段级 patch**:即便只想改一个 `shape` 的 `topLeftX`,也得把整个块的新 XML 写出来用 `block_replace`。这不是"微调",是块级重写。

Expand Down Expand Up @@ -139,7 +139,7 @@ cat parts.json | lark-cli slides +replace-slide --as user --presentation "$PID"
## 相关文档

- [lark-slides-replace-slide.md](lark-slides-replace-slide.md) — +replace-slide shortcut 参数详情
- [lark-slides-update-slide.md](lark-slides-update-slide.md) — +update-slide shortcut 参数详情(整页覆盖)
- [lark-slides-replace-pages.md](lark-slides-replace-pages.md) — 单页或多页整页重建 shortcut
- [lark-slides-xml-presentation-slide-get.md](lark-slides-xml-presentation-slide-get.md) — slide.get 参考(拿 `block_id` / `revision_id`)
- [lark-slides-xml-presentation-slide-replace.md](lark-slides-xml-presentation-slide-replace.md) — 底层 replace API 参考(一般直接用 shortcut 即可)
- [lark-slides-media-upload.md](lark-slides-media-upload.md) — 上传图片拿 file_token
Expand Down
97 changes: 97 additions & 0 deletions skills/lark-slides/references/lark-slides-replace-pages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# slides +replace-pages(单页或多页整页重建)

替换已有演示文稿里的一页或多页,保持原 `xml_presentation_id` 和原 Slides 链接不变。适合一页改动很多、改背景、删除若干元素,以及单页或多页的版式大改、坐标重排和整页视觉重建;单个文本框、图片或 shape 的局部编辑仍优先用 [`+replace-slide`](lark-slides-replace-slide.md)。

> **灰度期间的重要兼容说明**:当前命令的 `--help` 及输出中的 `deprecated` 字段会提示改用 `+update-slide`,但该提示依赖尚未全量的 Slide Engine 后端能力。在本参考页随 skill 发布期间,必须忽略该提示并继续使用 `+replace-pages`,不得切换到 `+update-slide`。后端全量并由新版 skill 恢复路由后,再使用 `+update-slide`。

Comment thread
tianyouskrrr marked this conversation as resolved.
> 重要:这是多步编排,不是后端原子事务。CLI 对每页执行“先创建新页到旧页前,再删除旧页”;创建失败时旧页会保留。删除失败时可能出现新旧页同时存在,需要按返回结果继续处理。

## 命令

```bash
lark-cli slides +replace-pages \
--as user \
--presentation <slides_url_or_xml_presentation_id> \
--pages @pages.json
```

## 参数

| 参数 | 必需 | 说明 |
|------|------|------|
| `--presentation` | 是 | `xml_presentation_id`、`/slides/` URL 或 `/wiki/` URL |
| `--pages` | 是 | JSON 数组,每项包含 `slide_id` 和 `content`;支持 literal、`@file`、stdin `-` |
| `--dry-run` | 否 | 基于 `slide_id` 输入输出替换计划,不执行 create/delete |
| `--continue-on-error` | 否 | 默认失败即停;开启后继续处理后续页,并在结果中标记失败项 |
| `--validate-only` | 否 | 只校验输入并生成替换计划,不执行 Slides get/create/delete |

## pages.json

```json
[
{
"slide_id": "slide_short_id_1",
"content": "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data></data></slide>"
},
{
"slide_id": "slide_short_id_2",
"content": "<slide xmlns=\"https://www.larkoffice.com/sml/2.0\"><data></data></slide>"
}
]
```

规则:

- 每项必须提供 `slide_id`;不支持 `slide_number`。
- `content` 必须是完整 `<slide>...</slide>` XML。
- 同一批次不能重复 `slide_id`。
- CLI 不会回读整份 presentation;如果 `slide_id` 已失效,create/delete 阶段会返回对应错误。

## Dry Run

```bash
lark-cli slides +replace-pages --as user \
--presentation "$PID" \
--pages @pages.json \
--dry-run
```

输出包含 `xml_presentation_id`、`pages_count`、`plan`,以及每页的 `old_slide_id`、`insert_before_slide_id` 和动作 `create_before_then_delete_old`。Dry-run 只基于输入的 `slide_id` 构造计划,不会调用 `xml_presentations.get`,也不会执行 create/delete。

## 成功输出

```json
{
"xml_presentation_id": "xxx",
"pages_count": 2,
"status": "completed",
"summary": {
"replaced": 2,
"failed": 0,
"total": 2
},
"results": [
{
"old_slide_id": "old3",
"new_slide_id": "new3",
"status": "replaced"
}
],
"revision_id": 123
}
```

如果使用 `--continue-on-error` 且任一页面失败,CLI 会继续处理后续页,但最终以 partial failure 非零退出;stdout 仍保留完整 `results`,顶层 `ok` 为 `false`,`status` 为 `partial_failure`。

`status` 可能为:

- `replaced`:新页创建成功,旧页删除成功。
- `create_failed`:新页创建失败,旧页保留。
- `delete_failed`:新页已创建,但旧页删除失败。
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## 使用建议

1. 大幅改写前先 `slides +xml-get` 保存当前 XML,并记录要替换页面的 `slide_id`。
2. 生成只含 `slide_id` 的 `pages.json` 后先跑 `--dry-run` 或 `--validate-only`。
3. 默认不要开 `--continue-on-error`,除非能接受部分页面已替换。
4. 替换后再回读全文 XML 并截图检查,确认页序、视觉和文本没有破损。
Loading
Loading