Wolf Runtime / CLI reference
Work with office documents from the terminal
Render, recalculate, convert, inspect, and edit documents with structured requests and JSON receipts. Use semantic transactions and private sessions for agent workflows, or compatibility shims for existing headless scripts.
Start with the released binary
Obtain the release artifact for your platform from your Wolf Runtime distribution channel. Check its digest against the release SHA256SUMS before execution, install it as wolfin a dedicated directory on PATH, and run wolf --version and wolf --help. Available targets: Linux x86_64/arm64 (musl), macOS x86_64/arm64, and Windows x86_64.
Run the examples below in order in a fresh directory. They use relative, quoted input paths, distinct output directories, and explicit receipt files. All snippets are POSIX shell; use Python 3, jq, and GNU coreutils. Verification scope.
Prepare the example files
Run these examples in a new working directory with wolf on PATH. Use a POSIX shell, Python 3, jq, and sha256sum (GNU coreutils). The sample has one visible paragraph and a small workbook. Output directories are distinct from the sources.
mkdir -p receipts
python3 - <<'PY'
from zipfile import ZipFile
parts = {
'[Content_Types].xml': '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>',
'_rels/.rels': '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>',
'word/document.xml': '<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>Revenue report: Old title</w:t></w:r></w:p><w:sectPr><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440"/></w:sectPr></w:body></w:document>',
}
with ZipFile('report.docx', 'w') as package:
for name, text in parts.items():
package.writestr(name, text)
with open('budget.csv', 'w') as f:
f.write('Item,Amount\nRevenue,42\n')
PY
wolf convert 'budget.csv' --to xlsx --outdir workbook --receipt receipts/prepare.jsonrender: document pages
Render DOCX, XLSX, PPTX, PDF, ODT/ODS/ODP, legacy DOC/XLS/PPT, or standalone EMF/WMF. Choose pdf, png, svg, jpeg, tiff, or bmp. The PDF example produces report.pdf and a render report; per-page outputs use a 1-based, document-width-padded page number. Use --pages, --dpi or --scale-to for page selection and size; use --sheet and --range for spreadsheets.
wolf render 'report.docx' --to pdf --outdir rendered --clock '2026-10-01T00:00:00Z' --receipt receipts/render.jsonrecalc: formula caches
Recalculate XLSX and save a new workbook. Pin the clock and seed, including in JSON requests. Use --iterative, --max-iterations and --max-change for iterative calculation. Network functions are not called and evaluate to #BLOCKED!.
wolf recalc 'workbook/budget.xlsx' --outdir calculated --clock '2026-10-01T00:00:00Z' --seed 0 --receipt receipts/recalc.jsonconvert: document formats
Use render for PDF and images. Contract pairs are listed below; a listed pair can still be refused if the linked engine does not implement it. Same-format DOCX/PPTX saves preserve package-part bytes; XLSX conversion recalculates formula caches. Use --sheet to choose a CSV worksheet.
wolf convert 'report.docx' --to docx --outdir saved --receipt receipts/convert.json| Target | Accepted input formats |
|---|---|
| docx | doc, odt, docx |
| xlsx | xlsx, xls, xlsb, ods, csv |
| pptx | ppt, odp, pptx |
| odt | docx, odt |
| csv | xlsx, xlsb, xls, ods |
edit: literal text replacement
Edit one DOCX or PPTX with an ordered array of case-sensitive replace-text operations. Use body or body+headers for DOCX, slides or slides+notes for PPTX, and all or first for occurrence. Matches spanning separate text runs are skipped and reported; no-match or split-run warnings mean partial (exit 1).
cat > edits.json <<'JSON'
[{"op":"replace-text","find":"Old title","replace":"New title","scope":"body","occurrence":"all"}]
JSON
wolf edit 'report.docx' --edits edits.json --outdir edited --receipt receipts/edit.jsonextract: text, structure, markdown, chunks
Extract DOCX, XLSX, PPTX, or PDF into UTF-8 text, engine-owned structure JSON, CommonMark/GFM markdown, and provenance-bearing chunks JSON. Legacy DOC/XLS/PPT accept markdown and chunks only. Structure includes visibility labels; text extraction is not a hidden-content filter. PDF structure includes layout elements and table geometry; DOCX structure includes paragraph line counts and line geometry.
wolf extract 'report.docx' --what text,structure,markdown,chunks --outdir extracted --receipt receipts/extract.jsonrasterize: PDF to PNG
Rasterize PDF pages, with --colorspace gray|rgb, --alpha, --clip x,y,w,h in pixels, and --no-annotations. Use --single-file for the first selected page or --stdout for concatenated PNG streams. When writing pixels to stdout, put the receipt in a file.
wolf rasterize 'rendered/report.pdf' --dpi 72 --colorspace gray --no-annotations --outdir raster --receipt receipts/rasterize.jsonextract: barcodes
For PNG, JPEG, or PDF, choose barcodes and optionally --multi. Results include base64 payload bytes and page-image coordinates. The text-only sample verifies a legitimate no-detection result; it is not a barcode recognition claim.
wolf extract 'raster/report-1.png' --what barcodes --multi --outdir barcodes --receipt receipts/barcodes.jsonobserve: semantic document view
Observe one DOCX, XLSX, or PPTX. Select semantic addresses with repeatable --target, bound the view with --depth and --max-nodes, and include page images with --render png|svg. Addresses include para:@1 (DOCX), sheet:Data/cell:A1 (XLSX), and slide:@1/shape:Title (PPTX). Take resolved addresses from the returned view before editing.
wolf observe 'report.docx' --target 'para:@1' --depth 2 --outdir observed --receipt receipts/observe.jsontransact: digest-bound changes
Apply Agent API operations to one DOCX, XLSX, or PPTX. Place --sha256 before its input: the digest applies to the next input. Use --plan to resolve without committing and --invariants for declared constraints. A failed invariant is exit 7 and writes no document. XLSX transactions also require a pinned clock and seed.
cat > ops.json <<'JSON'
[{"op":"replace-text","target":"para:@1","find":"Old title","replace":"New title","occurrence":"all"}]
JSON
digest=$(sha256sum 'report.docx' | cut -d ' ' -f 1)
wolf transact --sha256 "$digest" 'report.docx' --ops ops.json --outdir transacted --receipt receipts/transact.jsondiff: semantic changes
Compare two documents of one format: DOCX, XLSX, PPTX, or PDF. Read change records in the diff receipt. For PDF, add --visual pdf|png and optionally --dpi for overlays; PDF text reflow across a page break does not count as a move.
wolf diff 'report.docx' 'transacted/report.docx' --outdir compared --receipt receipts/diff.jsonsession: open, transact, undo, redo, list, close
Hold one DOCX, XLSX, or PPTX in a private worker. Capture session.id from open. Bind live edits to --revision, without a file digest. A successful transaction, undo, or redo advances the revision. A file is published only at close; --discard ends a session without publication. Use close --all only when you intend to close every session in your registry.
wolf session open 'report.docx' --receipt receipts/session-open.json
sid=$(jq -r '.session.id' receipts/session-open.json)
wolf session list --receipt receipts/session-list.json
wolf transact 'report.docx' --session "$sid" --revision 0 --ops ops.json --outdir session-view --receipt receipts/session-transact.json
wolf session undo "$sid" --receipt receipts/session-undo.json
wolf session redo "$sid" --receipt receipts/session-redo.json
wolf session close "$sid" --outdir session-saved --receipt receipts/session-close.json
wolf session open 'report.docx' --receipt receipts/session-discard-open.json
sid=$(jq -r '.session.id' receipts/session-discard-open.json)
wolf session close "$sid" --discard --receipt receipts/session-discard.jsonsearch: index and query
Build a deterministic .wolfindex from DOCX, XLSX, PPTX, or PDF. Only reader-visible content is indexed; hidden channels are excluded. Query with --in and bound results with --limit (1 to 1000). Read ranked hits, snippets, and source locators from search.hits.
wolf search --index 'search/report.wolfindex' 'report.docx' --receipt receipts/search-index.json
wolf search --query 'Revenue' --in 'search/report.wolfindex' --limit 5 --receipt receipts/search-query.jsonocr: optional recognition engine
Recognize one PNG, JPEG, TIFF, or PDF using separately installed wolf-ocr. Resolve the engine through WOLF_OCR, beside wolf, or PATH, in that order. Choose pdf, json, txt, or hocr; --lang accepts joined language codes and --force recognizes PDF pages that already have text. With no available engine, expect ocr-unavailable, exit 4, and no output. This example points WOLF_OCR at a nonexistent file to check that refusal explicitly, even on hosts with an installed engine. Remove that assignment for recognition.
status=0
WOLF_OCR='./missing-optional-engine' wolf ocr 'raster/report-1.png' -o 'recognized/report.txt' --format txt --lang eng --dpi 300 --receipt receipts/ocr.json || status=$?
test "$status" -eq 4
jq -e '.errors[] | select(.code == "ocr-unavailable")' receipts/ocr.jsonlifecycle: verified publication
For DOCX and PPTX, inspect digest-bound ops, plan, approve through a trusted host when needed, apply to managed storage, verify untouched parts, attest digests, and commit with explicit --approved. Never skip or replay a phase. Discard ends a live transaction without publication. Approval is a host action, not an agent tool. PDF uses the separate wolfpdf.lifecycle module; XLSX uses wolfxl operations.
digest=$(sha256sum 'report.docx' | cut -d ' ' -f 1)
wolf lifecycle inspect --sha256 "$digest" 'report.docx' --ops ops.json --receipt receipts/lifecycle-inspect.json
tx=$(jq -r '.lifecycle.transaction' receipts/lifecycle-inspect.json)
wolf lifecycle plan "$tx" --receipt receipts/lifecycle-plan.json
wolf lifecycle approve "$tx" --approved-by 'example-host' --reason 'Approve the demonstrated title change' --expires-in-s 900 --receipt receipts/lifecycle-approve.json
wolf lifecycle apply "$tx" --receipt receipts/lifecycle-apply.json
wolf lifecycle verify "$tx" --receipt receipts/lifecycle-verify.json
wolf lifecycle attest "$tx" --receipt receipts/lifecycle-attest.json
wolf lifecycle commit "$tx" --approved --outdir verified --receipt receipts/lifecycle-commit.json
wolf lifecycle inspect --sha256 "$digest" 'report.docx' --ops ops.json --receipt receipts/lifecycle-discard-inspect.json
tx=$(jq -r '.lifecycle.transaction' receipts/lifecycle-discard-inspect.json)
wolf lifecycle discard "$tx" --receipt receipts/lifecycle-discard.jsonJSON requests and stdin
Use --request file.json or --request - instead of argv options. Request documents carry contract_version, document_kind, verb, inputs, output_dir, and options; optional receipt_path and report_path select destinations. Do not combine two stdin consumers such as --request - and --edits -. Receipts are JSON on stdout unless --receipt selects a file.
cat > request.json <<'JSON'
{"contract_version":"v1","document_kind":"request","verb":"extract","inputs":[{"path":"report.docx","format":"docx"}],"output_dir":"from-request","options":{"what":["text"]},"receipt_path":"receipts/request.json"}
JSON
wolf extract --request request.json
wolf extract --request - < request.jsonsoffice: headless conversion
Invoke a shim directly with wolf shim NAME, or install the same binary under the five shim names in a dedicated directory. soffice supports conversion to pdf, odt, docx, pptx, xlsx, and csv, profile bootstrap, and only the two specified native macro operations. Filter names and arbitrary Basic scripts are refused.
wolf shim soffice --headless --convert-to pdf --outdir shim-pdf 'report.docx'pdftoppm: page images
Accept PNG, JPEG (including -jpegopt quality=85), PPM, gray/mono, TIFF, page ranges, sizing, cropping, and -hide-annotations. With no prefix, pixel streams go to stdout; -singlefile writes only the first selected page.
mkdir -p shim-images
wolf shim pdftoppm -r 72 'rendered/report.pdf' -f 1 -l 1 -png 'shim-images/report'pdfinfo: page metadata
Read native-compatible Key: value lines, including Pages and Page size. Use -f/-l for per-page size and rotation. Use -v for the compatibility version, with wolf identity on the next stderr line.
wolf shim pdfinfo 'rendered/report.pdf'pdftotext: text and layout
Extract UTF-8 text with LF line endings and form-feed page separators. Use -layout, -f/-l, or -bbox-layout for layout XHTML with flow/block/line/word boxes in points. A destination of - writes stdout. Plain -bbox and -tsv are refused.
mkdir -p shim-text
wolf shim pdftotext -bbox-layout 'rendered/report.pdf' 'shim-text/report.xhtml'pdfimages: embedded images
List embedded images with -list; extract with -j, -j -p, -png, or -all. These are source images, not page screenshots. Unsupported image encodings are refused before outputs. The text-only sample has no embedded images.
wolf shim pdfimages -list 'rendered/report.pdf'Shared options and format-specific modes
| Option | Behavior |
|---|---|
| --outdir DIR / --stem NAME | Choose output directory and stem. Do not use the source directory for mutating examples. |
| --format FORMAT / --sha256 HEX | Declare or digest-bind the next input. Put these options before that input. |
| --pages FIRST-LAST / --pages N | Select an inclusive, 1-based page range. |
| --dpi N / --scale-to PX / --scale-to-x PX / --scale-to-y PX | Size raster pages; scaling overrides DPI, and -1 on one axis keeps the aspect ratio. |
| --sheet NAME / --range A1 | Select worksheets (repeat --sheet) and a rendered cell range; use one --sheet for CSV conversion. |
| --comments annotations|balloons|none | Render DOCX comments; none is the default. Refused on other formats and document conversion. |
| --editing-language double_byte|single_byte | Choose XLSX recalculation editing-language semantics; default double_byte. |
| --font-dir DIR / --system-fonts / --locale BCP47 | Add font directories in order, opt into system fonts, or choose the locale. CLI defaults: bundled fonts, system fonts off, en-US. |
| --clock UTC / --timezone IANA / --seed N | Pin reproducibility inputs. Otherwise the clock comes from SOURCE_DATE_EPOCH or wall time; timezone defaults to UTC and seed to 0. |
| --timeout-ms N / --max-pages N | Bound processing time and selected pages. Default processing deadline: 120,000 ms; zero is invalid. |
| --report PATH / --receipt PATH | Write the render report or receipt to an explicit path. Do not mix JSON receipts with binary stdout. |
| --target ADDRESS / --depth N / --max-nodes N / --channel NAME | Select and bound Agent API observations or diffs; repeat --target and --channel where needed. |
| --dml-rendering-mode drawing_ml|vml | DOCX-only opt-in DrawingML selection. |
| --dml-effects-rendering-mode none|simplified|fine | DOCX-only effects selection. |
| --dml-3d-effects-rendering-mode basic|advanced | DOCX-only 3D effects selection. |
| --metafile-rendering-mode vector|vector_with_raster_fallback|raster | DOCX-only embedded metafile paint selection. |
| --emf-plus-dual-rendering-mode emf_plus_with_fallback|emf_plus|emf | DOCX-only dual metafile selection. |
| --ink-rendering-mode ink_ml|fallback_picture | DOCX-only ink paint selection. |
| --svg-text-output-mode placed_glyphs|text|paths | DOCX-only SVG text selection. |
| --numeral-format european|arabic_indic|eastern_arabic_indic|context | DOCX-only numeral selection. Unhonorable opt-in modes receive typed unsupported refusals. |
Duplicate output stems are refused before writing. For page images, numbering is padded to the total document page count: pages 2 and 3 of a 12-page document become stem-02.png and stem-03.png. Raster dimensions are ceil(points × dpi / 72).
Fixed admission ceilings: 10,000 document pages, 33,554,432 decoded input-image pixels, and 134,217,728 output-raster pixels. Selecting one page does not bypass the document ceiling. These ceilings cannot be raised through options. Input and package byte/ratio budgets also apply.
Receipts, render reports, and exit handling
Read status, exit, errors, warnings, and the verb-specific summary. Each written output has a path, format, source, size, and SHA-256. Bind results to request_identity, input digests, and engine identities. A failed one-shot run writes no document outputs; a partial run writes outputs and reports the loss. A failed session publication leaves the session open and restores replaced targets.
| Exit | Category | Meaning |
|---|---|---|
| 0 | succeeded | All requested outputs written without error-severity loss. |
| 1 | partial | Outputs written with reported loss, unsupported formulas, unreadable parts, or skipped edits. Inspect the receipt and render report. |
| 2 | usage | Malformed or unsupported arguments, invalid request, or output-stem collision. |
| 3 | input | Missing, unreadable, invalid, digest-mismatched, or over-budget input. |
| 4 | unsupported | Unsupported verb/format pair or unavailable optional engine. |
| 5 | output | Write failure, unwritable destination, or forbidden source overwrite. |
| 6 | timeout | Processing exceeded its finite deadline. |
| 7 | invariant | A transact invariant failed; no document was written. |
| 70 | internal | Engine fault; inspect the diagnostic in the receipt. |
Inspect render_report for omissions, approximations, font substitutions, and warnings. Any error-severity loss means partial (exit 1). Equal input bytes, effective determinism, request identity, and engine versions yield reproducible outputs and reports; receipt timestamps and timings are excluded from byte comparisons.
Shims retain native-compatible exits: soffice uses 0/1; Poppler shims use 0 for success, 1 for input/output failure, and 99 for malformed or unsupported arguments. Shim omissions go to stderr, even with exit 0. Set WOLF_REPORT_DIR to retain shim reports and receipts. Unsupported forms never fall back to installed LibreOffice or Poppler.
MCP and engine-specific APIs
The CLI examples cover the released native binary. Install the separate wolfsuite-control[mcp] package for wolfsuite-agent-mcp or python -m wolfsuite.agent_mcp. Configure the approved engine wheels and a workspace root before starting the network-denied stdio server. Use the nine domain tools, wolf_session, and lifecycle tools with workspace-relative document paths. MCP sessions use server-derived ownership, live revisions, and local AF_UNIX transport on Linux.
The WolfPDF actions in the agent contract are separate engine requests, not additional wolf verbs: text/fonts, annotations, forms, navigation/metadata, attachments, layers, page geometry/imposition, images, signatures, output transforms, tagging, compare, and stamps. Invoke PDF verified operations through python -m wolfpdf.lifecyclewith its JSON phase request. For XLSX verified operations use the wolfxl operations API. Engine modules and MCP startup require their own package qualification.
Verification scope
Examples exercised against wolf-v0.2.0, native Linux x86_64, commit dca4e8b4c0bda23232a9ed1bd52e2f44d9eb2d90. Binary SHA-256: 4271ab09784c4fba174859d6b4ccd718e8c345104a336c5703a2c6eb01b2ea1b. The displayed snippets are the same data used by the executable verification procedure.
- OCR was checked as an explicit ocr-unavailable refusal. Recognition requires the optional engine and language models.
- The barcode example checks an empty detection result on a page without barcodes.
- Sessions were exercised with a short private Unix socket registry. Keep WOLF_SESSION_DIR short enough for the operating system socket-path limit.
- Other platforms, every conversion pair, advanced render modes, arbitrary documents, separate engine modules, and MCP startup are outside this example qualification.
- Requests containing new or planned contract surfaces need their own capability proof before production use.