@openpresentation / cli
这个 opf 命令,用于处理OPF演示文稿的代理和人员。创建甲板,验证它们,进行精确的编辑,
转换它们之间的形式和格式(JSON, YAML, Markdown, PDF, PPTX, PNG, SVG),分页内容,嵌入目录记录a
Deck用于脱机使用,填充模板,摄取数据,并检查绑定的模式,默认目录和示例
甲板。要求macOS、Linux或Windows的node22及以上版本。
CLI依赖于 @openpresentation/opf (core),它保存OPF模式、编目和验证器以及读写文本
格式,其Node构建读取和写入文件;CLI是对它的命令。它不需要API密钥或网络连接
运行时。 opf --version 报告命令行和安装的核心版本。验证和编辑从不渲染;成功的验证
不是目视验证。PDF, PPTX, PNG和SVG使用可选的对等体 @openpresentation/opf-render 和
@openpresentation/opf-pptx (见 绘图及PowerPoint); opf doctor 表示安装了什么。
安装
npm install -g @openpresentation/cli
opf --version
opf --help # every command; opf <command> --help (or -h) for one
或者将其作为开发依赖项安装并使用 npx --no-install opf. 兼容性矩阵
命名每个CLI附带的库版本。应用程序使用core的函数而不是命令:参见 从代码.
要从源代码验证独立包,请运行 pnpm install 和 pnpm test:cli:packed. 这就产生了
artifacts/cli/openpresentation-cli-<version>.tgz (使用它所依赖的核心tarball),可以使用它的绝对
路径。对于源代码开发,请运行 pnpm --filter @openpresentation/cli build 和 node packages/cli/dist/index.js --help.
安装代理技能
npx @openpresentation/cli@latest skills install
npx @openpresentation/cli@latest skills status
npx @openpresentation/cli@latest skills update
CLI将所有六个绑定的技能文件夹安装到当前项目的文件夹中 .agents/skills,包括参考资料、例子和
检查脚本。它不需要付费服务、提供商帐户或符号链接特权。一旦安装了CLI,这些命令
离线工作。
使用 --agent codex --global 个人法典技能, --agent claude-code 或者 --agent cursor 对于那些项目技能
目录,或 --directory <path> 用于另一个兼容代理。默认的 universal 目标使用 .agents/skills;其全球
目标是 ~/.agents/skills. 看到 座席技能安装
获取完整的目标映射和更新行为。安装程序保留AGENTS。Md和不相关的配置,并拒绝
覆盖本地修改或未托管的文件夹。 status 与调用的CLI的捆绑版本进行比较,而无需进行网络查找。
从MCP客户端使用OPF
claude mcp add opf -- npx -y @openpresentation/mcp # Claude Code; Cursor and others: command npx, args -y @openpresentation/mcp
OPF的MCP服务器是它自己的包, @openpresentation/mcp,
因此CLI保持精简:它没有MCP代码,也不依赖于它。会说话的代理 MCP 学习
并通过它检查OPF,而无需对文本进行脱壳和解析(start_here, validate_deck, get_schema, search_catalog,
convert, search_docs 和更多;文档、模式、示例、目录记录和技能 opf:// 参考资料)。 opf mcp 运行它
当安装在命令行旁边或工作目录时;没有它, opf mcp 打印 npx -y @openpresentation/mcp 和
以2退出。
每个命令共享的约定
- 一个输出约定。 写deck的命令在其输入后接受一个可选输出,而写stdout时没有可选输出
(
-说同样的话)。-i(--in-place)重写输入。format,embed和paginate采取--check什么也不写; 当情况发生变化时退出1。现有的输出需要--force. - 固定的标志含义。
--format仅为报告格式(json,text,github验证,patchdiff)。--from和--to姓名牌表格(json,yaml,md);名字结尾.json,.opf.yaml,.yml或者.opf.md表格上写着 开始于{或者[是JSON,还有什么需要的吗--from.--data-format csv|tsv|json的数据名称。fill和ingest. - 一个报告。
{ command, ok, input, outputs: [{ file, sha256, bytes, mediaType }], findings, counts, ... },在stdout上,或在 stdout携带甲板时错误。错误是{ command, ok: false, code, error, ... }On stderr,并且消息声明 修复(一个丢失的参数,最近的命令或标志:“你的意思是——检查吗?”,一个被删除的标志的替换)。 - 退出代码。
0成功了,可能会有警告。1无效的文档,失败的补丁测试,或以上的发现--fail-on <error|warning|info>(默认error)、现有的输出、合并冲突或--check这发现了一个变化。2使用、无效的JSON、YAML或Markdown文本、I/O或缺少可选对等项。 - 文档文本中没有遥测、自动上传或执行指令。使用
--在以。开头的文件名之前-.
创建和验证
opf create decision.opf.json --title "Launch decision"
opf create brief.opf.md --example compliance-readiness-review # opf catalog examples lists them
opf create - --title "Launch decision" | opf validate -
opf validate decision.opf.json
创建提供具有一个稳定幻灯片ID的最小甲板, slide-1; --title 设置甲板名称和可见幻灯片标题。
--example <slug> 复制core的捆绑示例套牌之一。将一副牌复制到另一种形式,使用 opf convert.
opf validate 是唯一的检查器。它读取每个文件作为严格的JSON文本(或YAML,或Markdown deck),根据其名称或 --from),
打印报告(valid, schemaValid, findings, counts, checks),输入的SHA-256摘要和核心版本。每一个
发现有一个稳定的 opf/<rule> Id,严重性,类别(format, references, policy, accessibility, layout,
content),一个JSON指针路径,源代码行和列,一个提示,有时建议修复。只有格式,参考和
默认情况下,策略发现是错误的,因此 valid keep意为“正确的OPF”。
opf validate deck.opf.json # everything, JSON report
opf validate deck.opf.json --format text # one line per finding
opf validate decks/ --format github --fail-on warning # every *.opf.* file in a folder, as CI annotations
opf validate a.opf.json b.opf.md - # several inputs: { command, ok, files, counts }
opf validate deck.opf.json --only format,references --ignore layout --config house-rules.json
opf validate --list-rules
搜索文件夹 *.opf.json, *.opf.yaml, *.opf.yml 和 *.opf.md (排序,不 node_modules 和点文件夹)。
退出状态是所有文件中最差的。 --only 和 --ignore 以逗号分隔的规则id、名称或类别名称为例,
而且可能会重复。 --config 的显式本地JSON文件 { catalogs, contracts, severity, only, ignore, ignorePaths, thresholds, chartPalette }. 验证是只读的,不获取任何东西,也不会重写文件。看到 验证指南.
转换
opf convert <input> <output> 格式的每一个变化,是由扩展名命名的格式还是由 --from 和 --to:
opf convert deck.opf.md deck.pdf
opf convert deck.opf.md slides/deck.png --slides 1,3-5 --scale 2 # slides/deck-1.png, -3, -4, -5
opf convert deck.opf.md "slides/slide-{n}.png" # slides/slide-1.png, slide-2.png, ... (always numbered)
opf convert deck.pptx deck.opf.md --signals signals.json
opf convert outline.md deck.opf.yaml # a plain .md input is OPF Markdown
opf convert deck.opf.json deck.opf.yaml --schema-comment
opf convert deck.opf.md - --to pdf > deck.pdf
输入: .json, .opf.yaml/.yml, .opf.md 和一个平原 .md, .pptx,或者 -. 输出:甲板形式, .pdf, .pptx, .png 或者
.svg (每张幻灯片的输出旁边有一个文件, slides/deck.png 给 slides/deck-1.png,……填充到所写的最大幻灯片号的宽度, -01 从十张幻灯片;一个选定的幻灯片被写入输出本身; {n} 在输出中是幻灯片号,所以 slides/slide-{n}.png 总是给它的文件和其他文件编号 {key},或者 {n} 在单个文件输出中,是一个使用错误), .zip (幻灯片格式为PNG,或
SVG与 --to svg),或 - 与 --to. 一个标志只在涉及其格式的地方应用,否则是一个使用错误: --split 和
--title 对于Markdown输入, --aliases YAML、 --signals 对于一个 .pptx 输入, --schema-comment 对于YAML输出,
--drop-unsupported 为降价输出,以及 --slides, --include-hidden, --scale, --raster, --text, --charts,
--images, --provenance, --paginate, --date, --fonts 和 --asset-dir 用于绘制和PowerPoint输出。 opf convert --help
列出每个文件所属的格式。在0.18中删除: render, export, import, from-md, to-md, from-yaml, to-yaml 和
create --from,所有 opf convert 现在。看到 文档/ cli.md.
使用JSON Patch编辑
创建 changes.json:
[
{ "op": "test", "path": "/slides/0/id", "value": "slide-1" },
{ "op": "replace", "path": "/slides/0/title", "value": "Approve the next milestone" },
{ "op": "add", "path": "/slides/-", "value": { "id": "next-steps", "title": "Next steps" } }
]
预览结果,保存一个单独的文件,或者更新源代码:
opf edit decision.opf.json --patch changes.json # stdout; nothing is written
opf edit decision.opf.json reviewed.opf.json --patch changes.json
opf edit decision.opf.json --patch changes.json -i --expect-sha256 "$EXPECTED_SHA256"
编辑器实现 JSON补丁(RFC 6902): add, remove, replace, move, copy,
和 test全部应用或完全不应用;补丁格式为JSON或YAML。结果必须通过之前的格式和引用检查
写好了,报告也带了 inverse,即撤消编辑的补丁。 --expect-sha256 从先前的文件中获取摘要
opf validate 报告并拒绝已更改的输入。写使用临时兄弟文件和原子发布;符号链接和
不定期的目的地被拒绝。没有持久的撤消历史;使用版本控制或保存单独的输出。
Diff,合并和格式化
opf diff before.opf.json after.opf.json # readable report
opf diff before.opf.json after.opf.json --format patch # JSON Patch from before to after
opf diff a.opf.json b.opf.json --exit-code # exit 1 when they differ
opf merge base.opf.json ours.opf.json theirs.opf.json merged.opf.json
opf merge base.opf.json ours.opf.json theirs.opf.json -i --prefer theirs --report conflicts.json
opf format deck.opf.json -i
opf format --check decks/*.opf.json # CI: exit 1 if any file would change
diff 火柴滑过 id,然后是内容相同,然后是内容相似。 merge 结合两个编辑的基础;块的冲突
写入(退出1),除非 --prefer ours|theirs 选择一方,每一次冲突都会被报道。 format 在canonical中重写一个桥牌
键的顺序和布局,保持其形式(opf convert 变化形式);它是幂等的。看到
补丁,diff,合并和格式化.
事实,分页和嵌入
opf stats deck.opf.json --format text --per-slide
opf paginate deck.opf.json paginated.opf.json
opf paginate deck.opf.json --check # CI: exit 1 when a slide overflows
opf embed deck.opf.json -i
opf embed deck.opf.json --check # CI: exit 1 when the deck is not self-contained
stats 报告中立的事实(幻灯片、章节、布局、文字、注释、图像、图表、表格、数据集、引文、变量、
资产,字体,估计说话时间)下 stats 在报告中;它从不验证、合成或评估任何东西。 paginate
将溢出的幻灯片分成连续的幻灯片,用字体测量 opf convert 当opf-render安装时绘制
(layout: "measured"),其他估计(layout: "estimated",有… hint 这将命名安装命令)。 embed 每一个副本
Catalog将deck引用传递地记录到其中一次,因此该文件在没有注册Catalog的情况下呈现相同的内容。
填充模板并摄取数据
opf fill quarterly.opf.json globex.json globex.opf.json # one JSON object, one deck
opf fill quarterly.opf.md clients.csv decks/qbr-{client}.opf.md # one deck per row, named by a column
opf fill quarterly.opf.json clients.csv all.opf.json --combine # one deck, a slide group per row
opf fill quarterly.opf.json --examples > preview.opf.json # no data: fill from each variable's example
export-rows | opf fill quarterly.opf.json - decks/deck-{n}.opf.json # data from stdin
opf ingest revenue.csv table.opf.json --as table
opf ingest revenue.csv --as chart --category Quarter --series '["Revenue","Costs"]' --into decision.opf.json -i
fill的第二个参数总是data,不管它的名字是什么(- 从stdin中读取,第三个是输出:一个甲板名称,
或文件名模式,其中 {n} 记录号是否填充到最大的宽度,如 opf convert 衬垫滑动号码)和 {column} 这一列值的一小部分。一个空白的
Cell保留声明的值;未填充的必需变量失败,除非 --partial. ingest 将CSV, TSV或JSON行转换为
表格或图表,单独或添加 --into 甲板(--path 替换一个); --dataset <id> 将行存储在桥牌的数据集中。这个
相同的输入给出相同的幻灯片id和字节。看到 模板和变量 和
数据导入.
发现格式选项
opf schemas
opf schema presentation '/$defs/Composition'
opf catalogs
opf catalog layouts
opf catalog fontSchemes roboto
opf catalog examples
它们检查运行CLI的核心的默认目录(完整的pptx)。画廊目录)和捆绑的示例甲板,并打印 需要的数据。没有什么是牵强的。
绘图及PowerPoint
PDF, PNG和SVG的需要 @openpresentation/opf-render;PPTX输出和a .pptx 输入也需要 @openpresentation/opf-pptx。他们
是 可选的对等依赖项,在命令需要时加载它们(首先在CLI旁边,然后在工作中)
目录),因此CLI保持较小。 opf doctor 报告每种格式,这个安装是否可以写入它并打印一个命令
对于正在使用的包管理器(npm, pnpm, yarn或bun)和CLI的安装方式(global, a
项目,或npx):
opf doctor --format text
opf doctor deck.opf.md # with a deck: a PDF needs sharp only when it has pictures
错过对等体的转换将退出 code: "peer-not-installed" 这是一个命令 install. 输出是
确定性:没有网络,没有系统字体,没有时钟(--date 提供日期 date: true 字段)。字体是渲染器的
捆绑开包加上 .ttf/.otf 每个文件中的文件 --fonts 文件夹;相对图像只能从输入文件夹中读取
(--asset-dir);url永远不会被获取。拉丁文、希腊文和西里尔文以外的脚本需要渲染器的可选Noto脚本包
(报告列举了他们的名字)。完整的参考资料在这里 文档/ cli.md.
Markdown和YAML
JSON仍然是deck的规范形式;YAML (deck.opf.yaml)及Markdown (deck.opf.md)是同一数据的创作形式;
每个读取或写入甲板的命令都读取和写入这三种内容。语法错误以 line:column (opf validate
将其报告为发现,退出1)。重写YAML文件的命令不保留其注释,而必须放置内容的命令
成一个 opf-slide/opf-block 栅栏,在标准上这么说。看到 减价指南 和 YAML指南.
从代码
CLI就是命令。应用程序调用核心 @openpresentation/opf 相反,命令运行的函数,所以命令
代码给出了相同的结果。在节点, validate, stats, paginate, embed 和 edit 时注册默认编目
不调用名称,就像命令一样:
import * as opf from "@openpresentation/opf";
await opf.convert("deck.opf.md", "deck.pdf");
const deck = await opf.open("deck.opf.md");
const { presentation } = opf.edit(deck, [{ op: "replace", path: "/name", value: "Q4" }]);
await opf.save(presentation, "deck.opf.md");
const { decks } = opf.fill(template, csvText);
看到 OPF文件在Node 选项和错误。
发展检查
pnpm test:cli 运行命令tests (test/*.test.mjs 和 test/cli.mjs),包括 test/files.mjs 用于绘图和
PowerPoint针对发布的opf-render和opf-pptx(设置 UPDATE_GOLDEN=1 在呈现器之后刷新固定的SVG摘要
或核心隆起)。 pnpm test:cli:packed:peers 使用两个对等点安装打包的CLI,并针对已安装的CLI重复这些检查
二进制文件。 pnpm test:cli:packed 打包CLI,将tarball和它所依赖的核心tarball安装到一个独立的全局前缀中,
执行可执行文件,确定安装包含一个核心,然后重新运行 test/cli.mjs 反对它。重建CLI
核心变化;工作区将CLI链接到内核 packages/javascript.