genoffice Agent 技能实战指南:让 Claude Code / Codex / Cursor 在本地创建与编辑真实 Office 文件

  • 人工智能
  • AI 应用
  • 桌面应用
  • AI Agent
  • MCP 服务
  • AI 技能

【免费下载链接】genoffice

Free, open-source AI Office suite: Docs, Sheets, Slides, PDF, Markdown and HTML editors with a built-in AI agent, plus a `genoffice` CLI and agent skill so Claude Code, Codex and Cursor can create and edit real .docx/.xlsx/.pptx files locally. Bring your own key. macOS, Windows & Linux.

项目地址: https://gitcode.com/gh_mirrors/ge/genoffice
点击查看 免费下载

genoffice 是 GenOffice 随应用一同安装的本地 CLI,也是本仓库 skills/genoffice/SKILL.md 这一 Agent 技能(skill)文件的核心主题。本文以该技能文档为主体,结合 packages/cli 的源码实现,完整讲解如何让 Claude Code、Codex、Cursor 等编码 Agent 在本地用 genoffice 创建 docx/xlsx/pptx、在格式间转换、读取既有文件结构并执行结构化编辑,以及如何通过统一的 JSON 输出契约、批次语义和「完成前检查」质量门来保证每次产出真实、可用、可验证。读完本文,你将掌握这套 CLI 的全部命令、JSON 协议、典型工作流与常见错误的机器可读处理方式。

genoffice 是什么:一个为 Agent 而生的本地 Office 引擎

genoffice 与 GenOffice 一起安装,是 GenOffice 的命令行入口。它让你(或一个编码 Agent)在不打开图形界面的情况下,用 GenOffice 自己的引擎在本地完成以下工作:

  • 从简报(brief)构建演示文稿(pptx):经过可检查的大纲(outline)、逐页规格(page spec)与渲染管线;
  • 从 CSV 或 JSON 数据构建带公式的电子表格(xlsx);
  • 从 Markdown 或 HTML 构建 Word 文档(docx),或构建 PDF;
  • 在 pdf、docx、xlsx、pptx、md、html、csv 之间互相转换;
  • 读取既有文件(包括用户自己的 docx/xlsx/pptx 作为素材)的结构与文本,并施加结构化编辑;
  • 把结果直接在 GenOffice 编辑器中打开。

从源码看,CLI 的命令注册位于 packages/cli/src/cli.ts,通过 defaultRegistry() 注册了 info、convert、create、slides、sheet、docs、render、guide、search、image、media、open、selection、capabilities、install、mcp、skill 共 17 个命令,每个命令都是独立的 CommandDef。

隐私边界:所有命令都以无头(headless)方式运行在应用自带的引擎上;只有 search、image、media 三个命令会把查询词或所引用的文件发送到 GenOffice 中配置的提供商(provider)。其余操作全部在本地完成。

安装与启动器定位

技能文档给出的第一步是运行 genoffice --version。如果命令找不到,GenOffice 会在每次启动时把启动器目录写入:

  • macOS / Linux:~/.genoffice/launcher
  • Windows:%USERPROFILE%\.genoffice\launcher

读取该文件中的一行,然后在 bash 中用引号包裹运行 "<dir>/genoffice",或在 PowerShell / cmd 中用 "<dir>\genoffice.cmd" 代替下面的 genoffice。当该文件缺失时,各平台的默认位置为:

平台默认 CLI 位置
macOS/Applications/GenOffice.app/Contents/Resources/cli
Windows%LOCALAPPDATA%\Programs\GenOffice\resources\cli
Linux/opt/GenOffice/resources/cli

技能文档的元数据声明了版本约束:当前 bundled 版本 2.51.0,要求 CLI >=0.9.0(见 skills/genoffice/SKILL.md 头部 frontmatter)。

通用契约:--json、退出码与错误结构

技能文档反复强调一条铁律:当程序要读取输出时,永远加 --json。这是 Agent 与 CLI 之间稳定协作的基石,对应的类型定义就在 packages/cli/src/result.ts。

成功与部分成功的输出

一个 JSON 对象输出到 stdout:

{
  "status": "ok" | "partial",
  "command": "…",
  "summary": "…",
  "output_path": "…",   // 可选
  "warnings": [ … ],    // 可选
  "detail": { … }       // 可选
}
  • status: "partial":表示一次带 --best-effort / --stop-on-error 的 apply 虽然写入了文件,但丢失了部分操作(丢失的 op 在 detail.failures 中)。

失败输出

{
  "status": "error",
  "code": 1,
  "error": "op_rejected",
  "message": "人类可读",
  "suggestion": "一句话的下一步建议",
  "detail": { … }
}

退出码(与 EXIT 常量一一对应,见 packages/cli/src/result.ts):

退出码含义
0成功
1用法错误或操作被拒绝
2文件不存在 / 输出已存在 / 文件正被 GenOffice 打开
3转换失败
4应用不可用

字段语义:

  • error 是机器可读的原因字符串(对应下文「命令失败时」的表格),程序应该基于它分支;
  • suggestion 是下一步的一句话建议,当命令、选项、op 名、元素 id 或 sheet 名差一个拼写时,会包含 did you mean "…"?;
  • detail 以字段形式携带事实(如 failures[] 中的 index、op、error、reason、valid_range、available、supported、usage,以及 sheets、options、commands);
  • 绝不要解析 message——它是给人看的。

ErrorReason 的完整枚举同样定义在 packages/cli/src/result.ts,包括 unknown_command、invalid_json、unknown_op、op_rejected、target_not_found、sheet_not_found、resource_limit、outside_allowed_roots 等 20 种。

其他通用行为

  • --ops -、--cells -、--spec - 从 stdin 读取(--from 不支持);
  • --out 默认取输入文件所在目录、换新扩展名(convert),或原地编辑(apply);
  • 未知选项一律拒绝(退出码 1);
  • mcp 服务器默认运行在 stdio 上;mcp [--http <port> [--host <addr>] [--token <secret>]] 则改为提供 Streamable HTTP 服务。

命令总览:一张表看懂 18 个命令

技能文档给出了完整命令表,这里完整继承并补充参数要点:

命令作用
genoffice info <file> [--password <pw>]元数据与结构摘要:docx 的 blocks 和标题、pptx 的 slide、xlsx 的 sheet、pdf 的页
genoffice convert <file> --to <fmt> [--out <path>] [--force]格式转换:pdf→docx/pptx/xlsx、csv→xlsx、xls/xlsb/ods→xlsx、md→docx/html、docx→html/md、html→docx、xlsx→csv(--sheet),以及 docx/xlsx/pptx/md/html→pdf
genoffice create --type pptx --ops <file> --out <path>从一组 slide ops 构建新演示文稿
genoffice create --type pptx --spec <dir|file> [--outline <file>] --out <path>从逐页规格文件(每页一个,按名称排序)或单个 deck spec 文件构建演示文稿:px 定位的文本、形状与图片(即下文「设计演示文稿」的分阶段管线)
genoffice create --type xlsx --from <data.csv|table.json> [--header] [--decimal ,] --out <path>从 CSV 或二维数组 / {sheets:[{name,rows}]} 构建新工作簿;"=…" 单元格是公式;--header 冻结第 1 行并过滤范围
genoffice create --type docx --from <text.md|fragment.html> --out <path>从 Markdown 或受限 HTML 片段构建新 Word 文档
genoffice create --type pdf --from <document> --out <path>由 GenOffice 渲染器把任何 md/html/docx/xlsx/pptx 打印为 PDF
genoffice slides read <pptx> [--slide n] [--full|--max-chars n] [--layouts] / genoffice slides apply <pptx> --ops <file> [--dry-run]查看 id、几何信息与文本预览(默认裁剪到 300 字符、以 …(+n chars) 结尾并带 truncated: true;--max-chars 调整上限,--full 输出全文、每个表格行与演讲者备注),然后用 ops 编辑
genoffice slides audit <pptx> [--slide n] / genoffice slides render <pptx> --out <dir> [--scale 2]几何审计(越界、文本溢出、重叠):issues[] 带 code、level、path(s_n/e_*),越界与溢出场景会返回可直接传给 slides apply 的 suggest setTransform op;后者每页输出一张 PNG 供查看
genoffice render <file> --out <dir> [--page n] [--scale 2] [--el e_12 [--pad px]] [--grid [--cols 4] [--tile 320]]对 docx/xlsx/pptx/md/html/pdf 的每一页输出一张 PNG:在报告文档或工作簿「完成」之前先看渲染效果;--el(pptx)额外写出裁剪到单个元素的一页(<stem>-NN-e_12.png,id 来自 slides read);--grid 把所有页拼到一张联系表(<stem>-grid.png,行优先,瓦片位置在 grid.tiles)
genoffice slides check <outline.json|page.json> / genoffice slides replace <pptx> --slide n --spec <page.json>校验 deck 大纲(出错退出 1)或构建并审计一个页面文件、对照其大纲条目与 style.md 检查;用页面文件重建一个 slide,其余 slide 不动
genoffice sheet read <xlsx> [--sheet name] [--range A1:D20] [--cols A,C:E] [--max-rows n] [--where formula|error|empty|number|text] [--stats] [--formats] / genoffice sheet apply <xlsx> --ops <file>|--cells <file> / genoffice sheet check <xlsx>读取范围外加 features(冻结窗格、筛选、图表、表格、该 sheet 的规则数;范围中的合并单元格与链接;--formats 追加单元格格式、列宽、行高);用 --cols(只读这些列,列名在 columns 中)、--max-rows(rowsShown/rowsTotal 与带 --range 的 note)、--where(只读某一类单元格,输出 {ref, value, formula},无网格)或 --stats(计数、已用范围与 sheet 列表,无单元格)控制输出体积;用工作簿 DSL 或按单元格地址编辑;check 列出公式错误、指向缺失 sheet 的引用、损坏的 defined name、超出数据的图表范围、### 列(附 set_col_width 建议)、占位文本与既有规则
genoffice docs read <docx> [--range a-b] [--html] [--full|--max-chars n] [--comments] [--revisions] [--header-footer] [--sections] [--fields] [--notes] / genoffice docs apply <docx> --ops <file> [--dry-run] / genoffice docs check <docx>按索引读 blocks(预览裁剪到 200 字符、以 …(+n chars) 结尾并带 truncated: true;--max-chars 调整上限,--full 解除限制;另含评论线程、修订、页眉/页脚文本、每节的页面设置、带缓存结果的域、脚注/尾注),然后编辑
genoffice guide <slides|docs|sheets> [group|op|design|spec] [--json] [--index] [--fingerprint]每个域的操作参考(op reference),由 apply 校验所用的同一份定义生成(写 ops 前必读);按需输出一个分组或一个 op 的 JSON schema;slides design / slides spec 用于构建演示文稿
genoffice search <query> [--images] [--max n]通过 GenOffice 配置的提供商做网页 / 图片搜索;detail.results[] 为 {title,url,snippet}
genoffice image <prompt> [--out f.png] [--aspect 16:9] [--ref a.png,b.png] [--model <name>]用配置的提供商生成图片并保存;detail.mime、output_path
genoffice media <file|url> [--ask <question>]描述 / 提问图片、视频或音频文件;答案在 summary 与 detail.text 中
genoffice capabilities查看 GenOffice 中配置了哪些云功能(搜索、图片搜索、图片生成、媒体分析)以及应用是否安装;无网络调用
genoffice open <file> [--slide n [--el e_12]|--block n|--range [Sheet!]B2:D5|--page n]在 GenOffice 应用中打开文件(仅在用户要求在那里查看时);带目标时还会滚动并选中对应 slide 元素 / block / 范围 / 页(target_not_found / out_of_range 会带回合法 id 或范围)
genoffice selection <file> --json查看用户在编辑器中选中了什么:{slide, elements[], types[]}、{blocks:[a,b], text, collapsed}、{sheet, range, values?} 或 {page, text?}——在编辑前用它解析「这个」/「这里」;文件未在标签页打开时报 file_not_open_in_gui
genoffice skill list / genoffice skill install <agent|all> [--dir <path>] [--force] / genoffice skill path检测本机编码 Agent(Claude Code、Codex、Cursor、Gemini CLI、Copilot、OpenCode、Windsurf)及其已装技能版本;把本技能复制/更新到它们的技能目录,或打印 bundled 的 SKILL.md;未经此命令或「设置 → 集成」中的点击,不安装任何东西

guide 命令的实现值得注意:它从 executor 校验所依赖的同一份定义(pptx-ops 的 markdown、sheets 的 zod schema、docs 的 op registry 与工具 schema)生成目录,所以指南永远与 apply 实际接受的保持一致、不会漂移(见 packages/cli/src/commands/guide.ts);--fingerprint 输出目录指纹(对目录内容做 sha256 后取前 12 位,见 packages/cli/src/op-catalog.ts),任何 op 或字段变更都会反映在指纹上。

命令选择速查:「Which command」

面对不同任务,技能文档给出了清晰的路径选择表,这里完整保留:

任务命令路径不适用
从简报(哪怕极短)出演示文稿guide slides design → style.md + outline.json → 逐页 slides check → create --type pptx --spec → render --grid → slides audit编辑已存在的 deck(slides apply);夹具 deck(create --type pptx --ops)
修改既有 deck 的文字、图片或某一页slides read → slides apply --ops → slides audit → render --page整包重设风格(applyTheme op,或走分阶段重建路径)
从数据构建工作簿create --type xlsx --from data.csv|table.json → 用 sheet apply --ops 做格式/图表 → sheet check修既有文件里的单个单元格(sheet apply --cells)
编辑既有工作簿的单元格、格式、图表、规则sheet read → guide sheets <op> → sheet apply --ops → sheet checkrefresh_pivot、会话表格与形状(会被拒绝:需要编辑器)
从文本构建 Word 文档create --type docx --from report.md|fragment.html → docs check → render真实网页(convert page.html --to docx)
编辑既有 Word 文档docs read → docs apply --ops → docs check读取其文本(convert --to md 或 docs read --full)
读取用户文件作为素材convert --to md/csv 或 <domain> read --full --json对 Office 文件 unzip/cat;render(是像素,不是文本)
改变文件格式convert <file> --to <fmt>任何内容修改(先编辑、后转换)
查看页面效果render(--page、--el、--grid)提取文本或 id(read)
把用户指到某个位置,或基于其选中内容行动open <file> --slide/--el/--block/--range/--page → selection <file> --json读取内容(read);用户未打开的文件(selection 需要标签页)
查询 op 字段guide <domain> [group|op] [--json]凭本文件猜:指南由校验器生成、永远最新
把本技能交给另一个 Agent(或新机器)skill list → skill install <agent>(或 skill path 后复制文件)手写技能;install-cli(那是把 genoffice 放进 PATH)

技能安装命令与「设置 → 集成」面板共享同一个台账(ledger,位于 userData/app-settings.json),因此 CLI 安装会显示为「已安装」而非「外部」,见 packages/cli/src/commands/skill.ts。

必须知道的领域行为(Behaviour to know)

Word(docs)

  • 同一批(batch)内的 block 索引是活索引——insert_content 插入两个 block 后,后面的索引整体后移两位;目标匹配不到任何 block 会导致整批失败(退出码 1)。
  • findReplace 够不到表格单元格(请对表格用 replace_blocks);受限集合之外的 HTML 标签被静默剥离。
  • convert docx→md 输出 GFM:& < > 转成实体、公式变成 $…$、图片被丢弃并计入 detail.skipped。
  • create --from x.md 会内嵌相对路径引用的本地图片。
  • insert_image 接受本地路径(相对于当前目录,其次相对于 ops 文件)、data: URL 或 http(s) URL(png/jpg/gif),默认追加到末尾(除非给了 afterBlockIndex);edit_chart 的目标是 docs read 中 kind 为 chart 的 blocks;set_header_footer 写纯文本,支持 {PAGE} / {NUMPAGES} 标记,view: "first" 开启「首页不同」。
  • 评论 id 来自 docs read --comments;add_comment 把新线程锚定到某个 block 或其中一段精确 text 上(occurrence 从多个匹配里选一个),不改动文档文本;对带回复的线程根节点做 delete_comment 需要 withReplies: true。
  • 修订 id(r1、r2…)来自 docs read --revisions,是位置性的,任何编辑后都要重新 read 再 accept_changes / reject_changes。
  • insertField 在本地计算 SEQ 编号、REF 文本、DATE 与 MERGEFIELD;PAGE / NUMPAGES / AUTHOR 类结果是占位符,由 Word 打开时重算(docs check 把它们报为 info)——交接文件时要说明这一点。
  • edit_note 是单个注释内的 findReplace({ id, find, replace, matchCase? },脚注与尾注 id 相同时才需要 kind),保留注释的 id、引用标记与格式;findReplace 本身从不触及注释文本。
  • define_style 只打补丁给定字段(既有样式保留其余部分);applyStyle 接受 docs read --styles 中的段落样式 id,当样式是标题样式时会把 blocks 变成标题。
  • set_watermark 传 text: null 即移除水印;insert_picture / insert_text_box 的长度可用 2.54cm / 1in / 72pt / 96px 或磅值。
  • set_page_setup 修改纸张 / 方向 / 边距 / 分栏 / titlePg / 页码,作用于所有节或某一节(section: N 或 blockIndex),长度写作 "2.54cm" / "1in" / "72pt";insert_section_break 在某 block 后拆分节(拆分出的副本随后用 set_page_setup section: N 修改);docs read --sections 列出各节及其 block 范围。
  • 原生表格支持结构 op:insertTableRow / deleteTableRow / insertTableColumn / deleteTableColumn(0 基,position: "before"|"after",count)、mergeTableCells / splitTableCell(网格 range / cell;切割已有合并单元格会被拒绝)、setTableCellFormat(填充、垂直对齐、边框、width 用 twips 或 "2.5cm")、setTableStyle(样式 id 来自 docs read 的 tableStyles,外加 look 标志);用 nodeType: "table" 定位,docs read 会显示每张表的 rows、cols 与 merged 单元格。

Excel(sheet)

  • ops 按顺序执行,每个都看到前一个的结果:insert_rows / delete_cols 之后的 ops 寻址的是位移后的网格(位移后写入的公式按原样存储,位移前写入的公式像既有公式一样被平移);批次内早先新增或重命名的 sheet 用新名称寻址。
  • 规则、链接、注释、筛选与视觉元素必须排在其所在 sheet 的任何行列操作之后;defined-name ops 不能与 sheet 或行列 ops 混在同一批。
  • 除了单元格,sheet apply --ops 还能写图表(add_chart、edit_chart 作用于 xl/charts/chartN.xml)、图片与形状、Excel 表格、冻结窗格、隐藏行列、带勾选项的筛选、条件格式、数据验证、超链接、注释、页面设置、sheet 保护、defined name 与标签页顺序/可见性(genoffice guide sheets 有全部字段)。
  • --cells 的 style 与 format_range.format 是同一对象({bold, fillColor, numberFormat, …})。
  • 颜色是 #RRGGBB 或跟随工作簿主题的槽位:"accent1"、"accent1+40%"(变浅)、"dk2-25%"(变深)或 {theme, tint};fill: {pattern: "lightGray", fg, bg?} 或 fill: {gradient: {angle, stops: [{position, color}]}} 写图案与渐变填充,--formats 会以槽位、tint 与解析后的 rgb 回显。
  • sheet read 分开返回原始值(0.25、序列日期)与公式;features 提供 sheet 级信息(冻结窗格、筛选、图表、表格与规则数,以及范围内的合并单元格与链接);--formats 追加样式单元格、列宽(px)与行高(pt)。
  • convert --to csv 返回显示文本(百分比、日期)、UTF-8 带 BOM、CRLF 行尾,默认活动 sheet(除非 --sheet)。
  • create --from x.csv:首行 sep=; 会被识别并移除;ISO 日期(2024-01-01、2024-01-02 09:30)变成带日期格式的真实日期;--decimal , 把 1.234,5 读成 1234.5。
  • 本地引擎无法求值的公式(FILTER、SORT、UNIQUE、LET…)会不带缓存值写入,由 Excel 打开时计算;溢出公式(spill)以动态数组存储,在 Excel 365 中会溢出;formulas_not_cached 警告会点名这些单元格。

PowerPoint(slides)

  • 图片类 ops(addPicture、replacePicture、addMedia、setImageFill、setBackground)在 bytes 中接受本地路径或 data URL;扩展名自动推断。
  • setText 的 runs 默认继承元素第一个 run 的样式(除非显式设置某字段,如 bold: false)。
  • 同一 apply 批次内的 ops 按顺序执行,因此后面的 op 可以寻址前面 op 添加的 slide;原子模式下只要有一个 op 未应用就什么都不写;--best-effort(旧名 --isolation per_op)与 --stop-on-error 会写入已应用的部分并返回 status: "partial"。
  • 新建元素得到新的 e_* id:再次定位它们之前要重新跑 slides read。
  • convert pptx→pdf 像应用的导出一样渲染:每 slide 一张位图,无文本层。
  • 每个 EMU 长度字段(box、offset、dx/dy、wEmu/hEmu、colWidthsEmu、insets)也接受带单位的字符串:"2.54cm"、"1in"、"10mm"、"12pt"、"96px"。
  • slides read 列出每页的 animations[](seq、el、effect、kind、trigger、durationMs、delayMs、direction);addAnimation / removeAnimation / reorderAnimation 编辑一条时间线项(presetXml 可原样透传 PowerPoint 导出的效果);insertEquation 从 LaTeX 加入排版公式(PowerPoint 会渲染它,预览显示线性文本)。

文本元素的样式来源是分层追溯的:effective(第一个 run 的字号/字体族/颜色/加粗/斜体与段落对齐)带 src 标明每个值来自何处——run、paragraph defRPr、shape lstStyle、layout placeholder、master placeholder、master titleStyle/bodyStyle、presentation defaultTextStyle、theme major/minor。setFont 写在 run 层并覆盖以上所有层;applyTheme 改变主题字体与颜色。带超链接的元素还带 link(url、slide 跳转或 PowerPoint action:nextslide / previousslide / firstslide / lastslide / lastslideviewed / endshow);setLink 与 setText 的 link 字段都能写这三类链接。

应用内转换(→pdf、docx→html、html→docx、create --type pdf、render)

每次调用启动一个隐藏的 GenOffice 进程,耗时 1–6 秒,超时上限 180 秒,可以安全并发。html→docx 走 html2docx,适合真实网页;含 <formula> 的受限 HTML 片段则走 create --type docx --from fragment.html。

云功能(search、image、media)

--images 返回 detail.images[] {title,imageUrl,sourceUrl,source,width,height};提供商可能返回少于 --max 的结果。image 以提供商的真实格式保存(output_path 会告诉你;请求 .png 可能回 .jpg,记在 detail.note);--aspect / --size 在本地校验。

四步工作流(Workflow)

技能文档定义了 Agent 操作的标准节奏:

  1. 用 genoffice info 或 genoffice <domain> read --json 了解结构:block 索引(docx)、s_<n> / e_* id 与 EMU 几何(pptx)、sheet 名与单元格值(xlsx)。
  2. 用 genoffice guide <domain> 查 op 字段(单个 op 的 schema 用 guide <domain> <op> --json),然后自己写 ops JSON。
  3. 批次较大时先 genoffice <domain> apply --dry-run;被拒绝的 op 以 op_rejected 返回并附 executor 的 usage 行——修复该 op 后重发整个批次。默认是原子性的:被拒时文件未被触碰,detail.batch 为 {total, applied: 0, failed, skipped}。--best-effort 应用所有能应用的 op,--stop-on-error 按顺序应用到第一次拒绝为止;两者都会写文件并以 status: "partial"(退出码 0)作答,丢失的 op 在 detail.failures、计数在 detail.batch——程序必须检查 status,不能只看退出码。

批次的三种模式在 packages/cli/src/batch.ts 中实现:atomic、best_effort、stop_on_error;--isolation per_op 是 --best-effort 的前身、含义相同,且不能与 --stop-on-error 混用。

  1. 执行下面的「完成前检查」质量门,然后报告输出路径。

常见陷阱对照表(Pitfalls)

技能文档用一张表总结了最容易踩的坑,这里完整保留并补充源码佐证:

陷阱规则
slides read/audit/render/replace --slide n 与 op 目标 { "slide": n } 是 0 基;render --page n 是 1 基;docx block 索引是 0 基s_0 就是 PNG 的第 1 页
--ops -、--cells -、--spec - 读 stdin(--from 不支持);其他任何值都必须是存在的文件不存在的路径报 file_not_found,而不是空批次
结构性编辑会重编号:addElement 后新 e_* id、加 slide 后 s_*、insert_content/delete_blocks 后 docx block 索引同一批内索引是活的(后面的 op 看到前面的结果);下一批之前重新 read
EMU 字段(offset、box、dx/dy、wEmu/hEmu、colWidthsEmu、insets)接受整数或单位字符串 "2.54cm"、"1in"、"10mm"、"12pt"、"96px"不要自己乘以 914400;slides read 返回的就是 EMU 整数
CSV 导入:首行 sep=; 被识别并移除,ISO 日期变成真实日期,--decimal , 处理 1.234,5--header 冻结第 1 行并加筛选;不加则第 1 行是数据
本地引擎无法求值的公式(FILTER、SORT、UNIQUE、LET、LAMBDA…)不带缓存值写入formulas_not_cached 警告列出它们;sheet read 在 Excel 打开文件前显示公式且无值。不是错误
sheet apply 按文件中当前标签页名寻址 sheet,拼写与标签一致sheet_not_found 携带 detail.sheets 和 did you mean
结构性 sheet ops(插/删行、列、sheet)会位移同批后续 ops 的地址;defined-name ops 不与 sheet 或行列 ops 混用用位移后的坐标写后续 ops(或把结构 op 放最后);规则、链接、注释、筛选与视觉元素放在其 sheet 的行列 op 之后
GenOffice 在标签页中打开了文件 → apply 拒绝(退出码 2,file_open_in_gui)请用户关闭该标签页,或用 --out other.ext;仅当用户接受编辑器可能覆盖时才用 --force
create/convert/image 从不覆盖(退出码 2,output_exists);apply --out 指向既有文件也拒绝换一个名字,或用户要求替换时用 --force
apply --best-effort / --stop-on-error(旧 --isolation per_op)返回 status: "partial" 且退出码 0;check/audit 带问题也退出 0读 status、detail.batch、detail.failures / detail.issues;退出码 0 不代表「干净」
deck spec 是 1280×720 画布上的 px;ops 是 EMU同一个文件里绝不混用两者
convert pptx→pdf 无文本层;convert docx→md 丢图片(detail.skipped)需要每个字时用 docs read --full
docs findReplace 跳过表格单元格;insert_content 中未知 HTML 标签被静默剥离对表格 block 用 replace_blocks;待在受限 HTML 集合内(guide docs)

命令失败时怎么办(When a command fails)

按 error 分支、照 suggestion 行事,然后重发整个批次(原子 apply 什么都没写)。detail 以字段携带事实,绝不解析 message。错误对照表完整如下:

error下一步命令
unknown_command, unknown_option用 suggestion 里的 did you mean;detail.commands / detail.options 列出合法项;技能比应用旧时运行 genoffice <command> --help
missing_argument, invalid_argument修正 message 点名的 flag;genoffice <command> --help 显示所有 flag
invalid_json重新序列化 ops 文件;经 --ops - 管道时检查引号
unknown_opdetail.failures[].supported 与 did_you_mean;genoffice guide <domain> 查列表
op_rejecteddetail.failures[].usage 是 executor 的 usage 行;genoffice guide <domain> <op> --json 查 schema;修复该 op
target_not_founddetail.failures[].available 列出该 slide 上的 id / 匹配的 blocks;否则 genoffice <domain> read <file> --json 重新定位
out_of_rangedetail.failures[].valid_range(或 detail.valid_range);read 显示当前计数
sheet_not_founddetail.sheets 有文件中实际的标签名;照抄使用
file_not_found检查路径(相对当前目录);对 --ops 而言 - 是 stdin
output_exists换 --out,或用户要求替换时用 --force
file_open_in_gui请用户关闭标签页,或用 --out 写入;--force 仅在同意时
file_not_open_in_guiselection/open --el 需要文件在标签页中:先 genoffice open <file>,再请用户选中
outside_allowed_roots待在 GENOFFICE_ALLOWED_ROOTS 内;不要尝试其他位置
resource_limit包内部件过多/过大、压缩比不合理或条目路径逃逸归档;detail 点名条目与限额。不要重试,告诉用户
unsupporteddetail.supported 列出该命令接受什么;从上表选另一条路线
conversion_failed, app_unavailable文件或应用的问题:重试一次;若 capabilities --json 显示应用缺失,告诉用户(PDF 与 →html/html→ 路线需要 GenOffice)

成功结果仍可能携带 warnings[]({code, message, suggestion?}):formulas_not_cached、op_warning(sheets op 被调整过)、images_dropped(convert docx→md)、output_renamed(image 以提供商的真实扩展名保存)。读它们、报告重要的、不要重试。

「完成前」质量门:三行检查,每次必做

技能文档要求每个产物固定做三项检查:

产物1. 检查2. 查看3. 报告
Deckslides audit deck.pptx --json → detail.issues 为空(否则应用 suggest ops)render deck.pptx --out shots --grid --json,打开联系表.pptx 路径与任何你保留原样的内容
工作簿sheet check book.xlsx --json → 无 formula_error、missing_sheet_ref、number_overflow(应用 set_col_width 建议)render book.xlsx --out shots --json,看 sheet 的 PNG.xlsx 路径;如有未缓存公式要点名
文档docs check report.docx --json → 无你修得了的 broken_ref、placeholder_left、field_not_evaluatedrender report.docx --out shots --json,看第 1 页和最后一页.docx 路径

注意:check/audit 无论有没有发现都会以退出码 0 结束,发现项在 detail.issues[] 里,带稳定的 code、path,且尽可能带一条可直接传给 apply 的 suggest op。除非用户要求看文件,否则不要运行 genoffice open。

读取用户的文件:素材输入的正确姿势

用户交给你的素材(要转成幻灯片的报告、要总结的工作簿)由你直接读取:md、txt、csv、pdf 与图片直接打开。Office 文件是打包的 XML,必须先经过 CLI:

  • docx:genoffice convert file.docx --to md --out file.md 取全文(图片被丢弃),或 genoffice docs read file.docx --full --json / --html 取带索引的 blocks。
  • xlsx:genoffice convert file.xlsx --to csv --sheet <name> --out file.csv 取整张 sheet 的显示文本,或 genoffice sheet read file.xlsx --range A1:H200 --json 取原始值(不加 --range 时停在 500 行并说 truncated: true;先用 --stats 估量工作簿大小,用 --cols/--max-rows 翻页宽表/长表,用 --where formula 只看公式)。
  • pptx:genoffice slides read file.pptx --full --json 取每页文本、表格与演讲者备注;需要看页面时 genoffice slides render file.pptx --out shots。

数据与措辞取自这些素材;绝不要自己 cat 或 unzip Office 文件本身。技能文档里这句「never cat or unzip the Office file itself」与 packages/cli/src/commands/convert.ts 中「Office 文件是 zipped XML,先走 CLI」的实现思路一致——CLI 的引擎负责解包、解析与安全边界。

设计演示文稿:分阶段管线(Deck 从简报诞生)

只要用户要演示文稿(无论多短),不要手工摆放 ops:要走 GenOffice 应用自己用的分阶段管线。你是模型,genoffice 是引擎,每个阶段都是 CLI 在下一阶段开始前检查的一个文件。Ops(create --ops、slides apply)只用于编辑已存在的 deck。这条管线的完整描述同样存在于 packages/pipelines/src/slides/guides/design.md(由 genoffice guide slides design 输出)。

  1. 每会话跑一次 genoffice guide slides design,再跑 genoffice guide slides spec。跑一次 genoffice capabilities --json:它会告诉你 GenOffice 是否配置了搜索、图片搜索与图片生成;仅在已配置时才用它们获取事实与照片,否则规划无照片页面。
  2. 为 deck 建一个文件夹。先把样式表写进 deck/style.md(颜色、字体、布局变体、一句话风格)。然后写大纲 deck/outline.json(核心钩子 + 每页一条:标题、类型、布局、带真实数字的简报、image_queries),并运行 genoffice slides check deck/outline.json --json;修掉每个错误再继续。只有用户要求审阅大纲时才展示大纲。
  3. 一步一页:重读 deck/style.md 与该页的大纲条目,确定它的照片,写 deck/pages/NN.json(一个页面对象,回显条目的 title、type、layout),运行 genoffice slides check deck/pages/NN.json --json;它会在上一级找到 outline.json 与 style.md,对照条目 N 与配色检查页面。修到 detail.audit、detail.outline.findings 与 detail.style.offPalette 都为空(与大纲不一致会退出 1),再做下一页。绝不要在一个文件里写多页,也不要一步写多页。
  4. genoffice create --type pptx --spec deck/pages --outline deck/outline.json --out deck/deck.pptx --json(大纲页没有对应文件或页面与条目不一致时拒绝运行)。然后 genoffice slides render deck/deck.pptx --out deck/shots --json 看 PNG;genoffice slides audit deck/deck.pptx --json 看几何发现。修页面在其文件中改,genoffice slides replace deck/deck.pptx --slide n --spec deck/pages/NN.json --json 重建单页。最多两轮修复。
  5. 报告路径。照片来自 genoffice search --images 结果、genoffice image 或用户给的本地文件;绝不用灰框代替照片。数字来自用户素材或 genoffice search;数字为示意时要明说。

管线文件之间的关系:slides check、create --spec 与 slides replace 会在页面文件旁与上一级查找 outline.json 与 style.md,把每个页面(文件 NN.json 即条目 pages[N-1])对照其大纲条目与样式表颜色检查,并在 detail.notes 中说明哪个文件缺失。outline.json 的字段为 topic、core_hook(带张力、数字或反直觉对比的一句话)、pages[](每页 title、type(cover/content/data/closing)、layout(来自样式表库的该类型变体)、brief、image_queries)。检查器强制执行的规则包括:全 deck 要有 core hook;内容页不得连续重复同一布局变体且全 deck 至少用 3 个变体;按内容选变体(三个并列点→three_column_cards,一个关键数字→hero_big_number,对比→two_column_comparison 或 two_by_two_grid,序列→timeline_horizontal,指标→kpi_cards_row);禁止占位符(「XX%」、「lorem」),每个数字与名字都来自已有素材。

编辑既有演示文稿

单页重写、换标题、换图:用 ops 而非分阶段管线,并保持 deck 自己的设计。

  1. genoffice slides read deck.pptx --slide n --full --json 取元素 id 与当前文本;仅凭文字看不出页面样貌时 genoffice slides render deck.pptx --slide n --out shots --json。
  2. 在既有元素上用 setText(未指定样式的 runs 继承原字体、字号与颜色),新内容用 addElement / addPicture,删减用 deleteElement。用户想保留原文件时用 --out 写。
  3. 编辑后 genoffice slides audit deck.pptx --slide n --json:同一文本框里更长的句子会溢出,应用它返回的 suggest ops(放大或移动框),再渲染一次查看。
  4. 被编辑元素的 id 会变:第二轮 ops 前重新 slides read。slides replace --slide n --spec 从 spec 重建页面,只用于分阶段管线建的 deck,不用于重设用户带来的 deck 的风格。

三个开箱即用的示例

用 ops 建 deck(既有 deck 的编辑或夹具;给人用的演示文稿走上面的分阶段路径):

[
  {
    "op": "addElement",
    "target": { "slide": 0 },
    "kind": "textbox",
    "offset": { "x": 914400, "y": 685800, "cx": 7315200, "cy": 914400 },
    "paragraphs": [{ "runs": [{ "text": "Q3 Review", "bold": true, "fontSize": 36 }] }]
  },
  { "op": "addBlankSlide", "target": { "slide": 0 } },
  {
    "op": "addTable",
    "target": { "slide": 1 },
    "rows": 3,
    "cols": 3,
    "offset": { "x": 914400, "y": 1828800, "cx": 7315200, "cy": 2286000 }
  }
]
genoffice create --type pptx --ops deck.json --out q3.pptx --json

带公式的工作簿,然后格式化表头:

echo '[["item","qty","price"],["Apple",2,1.5],["Total","=SUM(B2:B2)",""]]' > table.json
genoffice create --type xlsx --from table.json --out sales.xlsx
echo '[{"op":"format_range","range":"A1:C1","format":{"bold":true,"fillColor":"#FFFF00"}}]' | genoffice sheet apply sales.xlsx --ops - --json

从 Markdown 建 Word 文档,然后在 block 0 后插入一段:

genoffice create --type docx --from report.md --out report.docx
echo '[{"op":"insert_content","afterBlockIndex":0,"html":"<p>Executive summary.</p>"}]' | genoffice docs apply report.docx --ops -

路径规则(Path rules)

  • 传绝对路径或相对当前目录的路径;genoffice 从不在 --out 路径或被编辑文件之外写入。
  • create 和 convert 在没有 --force 时拒绝覆盖已有输出。apply 默认原地编辑(除非给 --out);--out 指向另一个既有文件也需要 --force。
  • genoffice 拒绝改写 GenOffice 窗口当前打开的文件(退出码 2,消息「GenOffice has this file open」)。请用户关闭该标签页、用 --out 写到别的路径,或仅在用户接受编辑器可能覆盖时传 --force。
  • 若环境中设置了 GENOFFICE_ALLOWED_ROOTS,genoffice 只在这些目录内读写(否则退出码 2);请待在范围内。每条执行的命令都会记录到 ~/.genoffice/cli-audit.jsonl(GENOFFICE_AUDIT_LOG 可重定向或禁用)。GENOFFICE_USER_DATA 把 genoffice 指向非默认的 GenOffice 配置(打开的文档注册表、AI 设置)。

审计日志的实现见 packages/cli/src/audit.ts:每行一个 JSON 记录(command、argv、status、code、output_path、ms、cwd,外加时间戳与 pid),让放开 Agent 操作的用户事后能看到它碰过什么;日志超过 2 MB 会滚动为 .1 文件,且审计写入失败绝不拖垮命令本身。

  • 图片类 ops(addPicture、setImageFill、addMedia)的 bytes 字段接受本地文件路径,genoffice 负责读取。

限制与边界(Limits)

  • 转 PDF 的应用内路线:转 PDF 在 GenOffice 应用内运行(隐藏进程,每次数秒),需要已安装 GenOffice,或用 GENOFFICE_APP_BIN 指向它;docx→html 与 html→docx 同理。这意味着这几条转换路线在本仓库的 CLI 包之外依赖应用二进制(packages/cli/src/commands/convert.ts 的 APP_ROUTES 与 NODE_ROUTES 区分了「本进程内完成」与「交给应用无头导出」两类转换)。
  • Excel 高级 op 的约束:add_pivot 在 targetCell 写入透视表单元格(该处无值或公式,且 sheet 须已存在于文件中),外加一个 Excel 会刷新的原生透视表;源公式从文件求值,所以要放在更早的批次里。add_sparkline 每数据行写一个单元格内迷你图(每个 op 至多 200 行)。convert_to_values 用工作簿引擎从文件计算的值替换公式(错误结果保留公式;单元格编辑放在更早的批次)。set_page_setup 还接受 printTitles、header/footer 与 rowBreaks/colBreaks。仍需要实时编辑器的 Excel op(refresh_pivot、对会话创建的表格与形状的编辑)会被拒绝并给出原因。add_conditional_format 与 set_data_validation 是在 sheet 已有规则之上追加(set_data_validation 对已有规则的范围会替换之,null 移除之);clear_conditional_formats 从零开始。
  • 公式求值:写入后会用工作簿引擎求值公式,因此 sheet read 与缓存值读取者能看到数字。

结语:把 SKILL.md 当作 Agent 的操作手册

这份技能文档的精髓是「模型负责思考,genoffice 负责执行」:模型决定要什么(结构、样式、内容),CLI 以可校验的 JSON ops 与规格文件为输入,以机器可读的 JSON 结果为输出,并在每一步(大纲、逐页规格、批次、质量门)都提供检查点。仓库侧的实现与之严格对应:result.ts 定义契约、batch.ts 定义三种批次语义、op-catalog.ts 保证指南与校验器不漂移、audit.ts 保证每次执行可追溯。对任何接入 Claude Code、Codex 或 Cursor 的 Agent 而言,genoffice skill install <agent> 是把它装进技能目录的正规入口,而本文覆盖的每一个命令、陷阱与错误处理分支,都可以从 skills/genoffice/SKILL.md 原文档与 packages/cli 源码继续深入核对。

  • 人工智能
  • AI 应用
  • 桌面应用
  • AI Agent
  • MCP 服务
  • AI 技能

【免费下载链接】genoffice

Free, open-source AI Office suite: Docs, Sheets, Slides, PDF, Markdown and HTML editors with a built-in AI agent, plus a `genoffice` CLI and agent skill so Claude Code, Codex and Cursor can create and edit real .docx/.xlsx/.pptx files locally. Bring your own key. macOS, Windows & Linux.

项目地址: https://gitcode.com/gh_mirrors/ge/genoffice
点击查看 免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值