feat: 使用本地 SVG 引擎实现 PPTX 预览与编辑 - #161
Conversation
改动细节: - 引入 pptx-svg WASM,在本地将 PPTX 渲染为逐页 SVG 并按文件指纹缓存 - 新增演示文稿对象检查与稳定对象 ID,支持精确修改文本 run 后导出新 PPTX - 新增 pptx-editor 任务技能并接入内置技能注册 - 更新文件预览面板,支持幻灯片全页预览、缩放及视觉/内容视图切换 - 移除 LibreOffice、soffice、Quick Look 和 Office 转 PDF 的原生及 TypeScript 链路 - 旧版 .ppt 改为提示另存为 .pptx,不再调用外部转换器 - 补充 PPTX 缓存、对象检查、编辑导出、预览界面和旧链路移除测试
There was a problem hiding this comment.
Pull request overview
This PR replaces the previous LibreOffice/Quick Look Office preview pipeline with a fully local PPTX pipeline based on pptx-svg WASM, enabling cached per-slide SVG rendering plus stable object IDs for precise text-run edits and PPTX re-export, and updates the renderer preview UI + skills registry accordingly.
Changes:
- Introduces a local PPTX presentation model (
preparePptxPreview, inspection, and text-run editing) and adds a newpptx-editortask skill. - Refactors Office preview IPC + shared types to support
"presentation"(PPTX SVG) and"content"previews, removing the native LibreOffice conversion entrypoint. - Updates file preview UI/tests and i18n strings to align with the new preview behavior and removes LibreOffice-related messaging.
Reviewed changes
Copilot reviewed 23 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shared/office-preview.ts | Updates shared preview/result types for presentation SVG previews and removes PDF/image preview fields. |
| src/renderer/i18n/zh-CN/index.ts | Removes LibreOffice/PDF unavailability string. |
| src/renderer/i18n/ja/index.ts | Removes LibreOffice/PDF unavailability string. |
| src/renderer/i18n/en/index.ts | Removes LibreOffice/PDF unavailability string. |
| src/renderer/i18n/i18n-types.ts | Regenerates types to remove the deleted i18n key. |
| src/renderer/components/file-preview/FilePreviewPanel.tsx | Implements PPTX visual preview via per-slide SVGs and removes PDF/image Office fallback UI. |
| src/renderer/components/file-preview/tests/FilePreviewPanel.office.test.tsx | Updates tests to validate content-only Office previews and PPTX SVG slide rendering. |
| src/main/skills/pptx-editor.ts | Adds a new mutating task skill for inspecting/editing PPTX text via stable object IDs. |
| src/main/skills/index.ts | Registers the new pptx-editor skill. |
| src/main/skills/tests/pptx-processor.test.ts | Adds a spec test for the new pptx-editor skill shape/category/tools. |
| src/main/presentation/pptx.ts | Introduces the local PPTX renderer adapter, preview caching, object inspection, and text editing/export. |
| src/main/presentation/tests/pptx.test.ts | Adds unit tests for PPTX preview caching, inspection IDs, and edit/export behavior. |
| src/main/office-preview/paths.ts | Deletes LibreOffice path resolution helper (no longer needed). |
| src/main/office-preview/content.ts | Removes legacy PPT conversion and updates unsupported messaging + cache version bump. |
| src/main/office-preview/tests/paths.test.ts | Removes tests for deleted LibreOffice path resolution. |
| src/main/office-preview/tests/content.test.ts | Updates legacy PPT handling test to assert “unsupported” without external converter. |
| src/main/native/index.ts | Removes TypeScript bridge types/exports for the native Office conversion entrypoint. |
| src/main/native/tests/exports.test.ts | Updates tests to accept native bindings without the removed Office converter. |
| src/main/ipc/file-handlers.ts | Switches PPTX visual preview to local WASM SVG pipeline and non-PPTX to content-only; merges PPTX visual+content. |
| package.json | Adds pptx-svg@0.6.4 dependency. |
| pnpm-lock.yaml | Locks pptx-svg@0.6.4 with Node engine requirements. |
| native/filework-native/src/office_preview.rs | Deletes Rust napi LibreOffice/Quick Look conversion implementation. |
| native/filework-native/src/lib.rs | Removes the office_preview module export. |
| docs/plans/2026-06-29-office-preview-pipeline.md | Removes the old LibreOffice-based preview pipeline plan doc. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (2)
src/main/skills/pptx-editor.ts:49
- Search matching currently lowercases text with toLocaleLowerCase(), which can produce locale-dependent results. Prefer toLowerCase() for deterministic matching across environments.
? item.objects.filter((object) =>
object.textRuns.some((run) =>
run.text.toLocaleLowerCase().includes(normalizedSearch),
),
src/main/skills/pptx-editor.ts:59
- Notes matching uses toLocaleLowerCase(), which can be locale-dependent. Use toLowerCase() for consistent matching behavior.
item.objects.length > 0 ||
item.notes.some((note) =>
note.toLocaleLowerCase().includes(normalizedSearch),
),
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (extracted) { | ||
| result.contentPreviewPath = extracted.contentPreviewPath; | ||
| } | ||
|
|
||
| return `${visualMessage}. ${installHint} ${contentMessage}`; | ||
| if (contentResult.status === "rejected") { | ||
| result.contentPreviewError = getErrorMessage(contentResult.reason); |
There was a problem hiding this comment.
已在 168a114 修复:内容解析 fulfilled 但返回 unsupported(含 parse-error)时,将 preview.message 保留到 contentPreviewError。新增 fs:prepareOfficePreview IPC 回归用例覆盖视觉成功、内容解析失败的组合。
改动细节: - 将幻灯片 SVG 安全清洗后以内联方式渲染,保留本地对象元数据 - 支持鼠标或键盘选择形状与文本片段,并显示选中高亮 - 将选中对象、源文件路径与修订标识注入 pptx-editor 输入 - 增加 sourceRevision 校验,阻止过期对象 ID 写入已变化的 PPTX - 补充 SVG 安全、选择交互、聊天注入和过期修订回归测试
改动细节: - 选中幻灯片元素后在元素附近显示轻量输入框 - 根据元素位置自动选择上下方并处理左右边缘,缩放时保持输入框可读尺寸 - 支持 Enter 发送、Shift+Enter 换行、Esc 或关闭按钮取消 - 就地请求直接提交到当前 Chat 会话,不再覆盖底部输入框草稿 - 会话执行中拒绝重复提交并保留就地输入内容 - 补充浮层定位、选择上下文和当前会话提交回归测试及多语言文案
- 编辑工具成功导出后自动打开新 PPTX,并通过预览修订号刷新同路径内容 - 解析 OOXML 图片关系并按文件头识别媒体类型,替换本地 SVG 灰色占位 - 为固定尺寸 SVG 补充 viewBox 与等比缩放,保证幻灯片完整展示 - 补充结果重放、失败结果、同路径刷新、图片内联和响应式预览回归测试
- 移除 editPptxText 的 outputPath 参数,禁止 Agent 反复生成重命名副本 - 导出结果通过临时文件原子替换源 PPTX,失败前不破坏原文件 - 保留 sourceRevision 校验,并返回原路径触发右侧预览刷新 - 更新技能说明与原地编辑回归测试
- 将对象、文本和备注搜索统一改为 locale 无关的 toLowerCase 匹配 - PPTX 内容解析返回 unsupported 时保留 message 到 contentPreviewError - 补充 Turkish locale 搜索与 fulfilled parse-error IPC 回归测试
改动概览
实现说明
PPTX 预览与编辑链路现在为:
PPTX → 本地 WASM 解析 → OOXML 图片关系解析 → 安全内联 SVG → 响应式等比展示 → 元素选择 → 就地 Chat → 当前对话 → 稳定对象 ID → 文本回写 → 原子替换源文件 → 同路径刷新预览
预览缓存以文件路径、mtime、大小、内容哈希和渲染器版本生成指纹。选中元素时会携带 sourceRevision;写入前再次校验源文件修订,避免外部修改 PPTX 后使用过期对象 ID。全部解析、选择和回写均在本机执行。
编辑时先在源文件目录生成临时 PPTX,导出完成后再原子替换源文件;导出或临时写入失败时不会提前破坏原文件。工具不再接受另存路径,结果中的 outputPath 固定返回源路径,用于触发右侧预览刷新。
工具结果监听直接使用事件携带的 toolName,兼容历史结果重放。仅成功的 editPptxText 结果会刷新预览;失败结果不会误触发预览切换。同一路径再次打开时通过 fileRevision 让预览组件重新挂载,确保删除文本等修改立即可见。
PPTX 对象、文本 run 和备注搜索统一使用 toLowerCase(),不依赖进程默认 locale。视觉 SVG 渲染成功但内容提取返回 unsupported/parse-error 时,会继续展示幻灯片,同时把失败 message 放入 contentPreviewError 供诊断和 UI 使用。
就地输入支持 Enter 发送、Shift+Enter 换行、Esc 或关闭按钮取消。当前会话执行中会拒绝重复提交,并保留尚未发送的就地输入内容。
验证
当前边界
预览中可选择形状、图片、图表和文本片段作为 Agent 上下文;当前编辑工具只对外开放精确文本 run 修改,形状、图片和图表的属性写入尚未开放。当前图片预览支持 PNG、JPEG、GIF、WebP;其他嵌入媒体格式仍保留占位。