Revise CLI menu
JSON output
The --json contract: one envelope for every command.
Add --json to any command and revise prints exactly one JSON object on
stdout, and nothing else on stdout or stderr. Every command uses the same
envelope, so a script or an agent can handle every result the same way.
revise status contract.docx --json{
"schema": 1,
"ok": true,
"command": "status",
"meta": { "version": "3.0.0", "build": "3881be46a" },
"data": {
"file": "/work/contract.docx",
"format": "docx",
"mode": "suggest",
"blockCount": 68,
"wordCount": 2174,
"trackedChangeCount": 0,
"checkpoint": 0,
"sourceFidelity": {
"fidelity": "exact",
"regeneratedBlockIds": [],
"changedDomains": [],
"convertedReason": null
}
},
"warnings": [],
"error": null
}The contract is also a JSON Schema, shipped in the package:
revise/cli-output.schema.json.
The envelope#
| Key | Type | Meaning |
|---|---|---|
schema | 1 | The version of this contract. |
ok | boolean | true exactly when error is null. |
command | string or null | The command that ran, by its canonical name: status, xml patch, skill install; call for the tool shorthand; help for help and any --help; version for version and --version. null when the command was not recognized. |
meta | object | version (the revise package version) and build (the commit it was built from). |
data | object or null | The command's result. Present on failure too whenever there is something to report, such as what was saved before the failure. null when there is nothing. Its presence does not mean success. |
warnings | array | Things worth knowing that did not stop the command. |
error | object or null | Why the command failed. |
Compatibility#
All seven keys are always present. Within schema 1, fields may be added;
existing fields keep their names, types, and meanings. Ignore fields you
don't know, and handle error and warning codes you don't know generically.
Breaking changes come with a new schema number and a new major version of
revise.
Inside data, every documented key is present. A value that does not apply
or is unknown is null; an empty list is []; a zero count is 0. Keys are
camelCase, except inside a tool's own result (see Tool calls).
Counts end in Count. Paths are absolute; package part names (like
word/document.xml) are relative to the package.
The output is UTF-8 with one trailing newline. It is indented when stdout is a terminal and on one line otherwise; both parse the same way. Don't rely on key order.
Exit codes#
| Code | ok | Meaning |
|---|---|---|
0 | true | Done, including when there was nothing to do. |
1 | false | Failed, and nothing was saved: a usage error, a missing file, a refused edit. |
2 | false | Partly done: some of what was asked was saved or written, and some was not. data says what happened; error says what didn't. A redline that was written but failed its check is also 2. |
70 | false | An internal error, or a save whose outcome is uncertain (save_uncertain, with details.file and details.saved: null). Check the file before going on; the next revise command on it finishes or undoes the save. |
A signal, a crash while starting up, or a closed stdout can still prevent a complete envelope.
Errors#
{
"code": "change_not_found",
"message": "Not pending: prop_17915. 1 other change was accepted and saved.",
"hint": "revise changes contract.docx",
"details": { "notFound": ["prop_17915"], "failed": [] }
}| Key | Meaning |
|---|---|
code | Stable and snake_case. Branch on this. |
message | One or two sentences for a person or a model. The wording may change. |
hint | A command to run next, shell-quoted, or null. Advice, not an instruction. |
details | Structured facts about the failure, or null. |
Warnings#
Same code, message, and details as errors, without hint. In human
output (without --json), warnings go to stderr as
warning[code]: message, and errors (partial results too) as
error[code]: message followed by a hint: line. A command that fails with
exit 1 prints nothing on stdout.
Saving#
Commands that can change the document report:
| Key | Meaning |
|---|---|
file | The document. |
saved | true when this command wrote the file and recorded a checkpoint. false when it saved nothing. |
checkpoint | The checkpoint the file is at now, saved or not. Undo with revise undo <file>. |
Commands that write another file report output (its path) and
outputWritten. If such a command fails after writing the file (for
example new when its page setup fails), it exits 2 with that receipt:
outputWritten: true, and null for what it could not determine.
undo and restore move the file back to an earlier checkpoint and discard
the later ones: they don't add a checkpoint.
Vocabulary#
| Term | Meaning |
|---|---|
| block | One unit of the document: a paragraph, heading, list item, table, or image. Block ids stay the same across commands until the block is removed. Block indexes start at 0. |
| tracked change | A Word revision waiting to be accepted or rejected. Each has a change id. |
| mode | suggest (edits become tracked changes) or edit (edits apply directly). |
| checkpoint | A saved state in the file's history. 0 is the file as revise first read it. |
| section | The part of the document under one heading. Not a Word page-layout section. |
Commands#
Reading#
status: file, format, mode, blockCount, wordCount,
trackedChangeCount, checkpoint, and sourceFidelity: for a .docx, how
an export now would relate to the file it came from (otherwise null):
fidelity:"exact"(reproduces the original file byte for byte),"grafted"(the original file plus your edits; untouched content is byte for byte), or"converted"(written fresh).regeneratedBlockIds: blocks an export would rewrite.changedDomains: other parts it would rewrite ("styles","numbering", …).convertedReason: why it is"converted", ornull.
outline: file, blockCount, wordCount, sectionCount, sections
(each: title, level (1–3), startIndex, endIndex (inclusive),
startBlockId, endBlockId, blockCount, wordCount), and nextOffset:
pass it to --offset for the next sections, null at the end.
grep: file, pattern, regex, ignoreCase, view, matchCount,
and blocks in document order (each: blockId, blockIndex, matchCount,
text, matches). text is the block in the view; in tracked, changes are
inline as [-deleted-]{+inserted+}. matches lists each match (text,
change: "deleted", "inserted", or null for text no change touches,
and changeId).
read and search are tool calls.
Editing#
replace-all: file, find, replace, matchedBlockIds (blocks that
contain find), replacedOccurrences, regions (occurrences per part:
body, header, footer, footnote, endnote; parts with none left
out), nearMisses (text looser matching would have replaced; each: text,
count, reason: case or characters), changeIds (tracked changes
created), failures (blocks that could not be edited; each: blockId,
code, message), saved, checkpoint. Some failures: exit 2. All
failed: exit 1. Run as replace-text, its 3.0 name, the envelope's
command is replace-text.
mode: file, mode, changed (whether this command switched it). The
mode is revise's setting, not part of the file.
tools: tools (each: name, summary). tools <name>: name,
description, inputSchema.
Review#
changes: file, section and blocks (the filters, or null),
trackedChangeCount, and changes in document order (each: changeId,
type, author, blockId, blockIndex, section, deleted, inserted).
deleted and inserted are the full text, never shortened.
accept, reject: file, action, dryRun, resolved (change
ids accepted or rejected), wouldResolve (with --dry-run: what would be;
otherwise []), notFound (requested ids that are not pending), failed
(pending changes that could not be resolved; each: changeId, code,
message), saved, checkpoint. If some ids were not found or failed while
others were resolved: exit 2. If none were resolved: exit 1.
diff: file, since (the --since checkpoint, or null for the
pending tracked changes), changedParagraphCount, text. text is for
reading: [-removed-] and {+added+} inline, which can be ambiguous if the
document itself contains those markers.
history: file, checkpoint (current), checkpoints (each:
checkpoint, at (ISO 8601, UTC), command, summary).
undo, restore: file, checkpoint (now), from (before),
discarded (checkpoint numbers removed), saved.
Output#
render: file, output (the image), outputWritten, mimeType,
width, height, pages (1-based), totalPages, view, description,
placeholderImageCount, failedImageCount.
export: file, output, outputWritten, format, byteCount,
final (whether the output shows no tracked changes: only a .docx can
hold them, so every other format is true), view (tracked, accepted,
or original: what the output shows),
trackedChangeCount (tracked changes in the written file, as revise reads it
back; Word stores a replacement as a deletion and an insertion, so this can
be higher than the source's count; 0 for other formats; null if a .docx
could not be read back), docxExport, and summary. For .docx output, docxExport says what the export did:
method ("graft": untouched content copied from the original file;
"regenerated": written fresh), exact, regeneratedBlockCount,
fallbackCode (why it regenerated, or null). summary describes the
written .docx (read back from it). Both are null for other formats.
Create and convert#
new: output, outputWritten, format, mode, checkpoint,
summary. checkpoint and summary are null when setting up the file
failed after it was written (exit 2). Page options are checked before
anything is written.
convert: input, inputFormat, output, outputWritten, format,
byteCount, final, view (as for export). input is null when the
document came from stdin
(-); inputFormat is the format read (docx, odt, rtf, html, md,
or txt), from --from, from stdin's bytes, or from the input's extension.
Writing to stdout (- as the output) can't be combined with --json.
compare: original, revised, output, outputWritten, author,
inlineChangeCount, insertedBlockCount, deletedBlockCount,
unmarkedBlockCount (changed blocks that can't carry a tracked change),
untrackedRegions (parts that differ but can't be tracked, taken from the
revised file), and verification: scope ("normalized_text"),
acceptAllMatchesRevised, rejectAllMatchesOriginal. The check compares
text with whitespace normalized; it does not check formatting or comments. A
redline that fails it is still written: exit 2, redline_unverified.
summary (in new and export): pageCount (null when not
measured), wordCount, pageSize, orientation, pageInches (width,
height), marginsInches (top, right, bottom, left), title,
headingCounts ({"H1": 1, "H2": 4}), lists (each: itemCount), tables
(each: rowCount, columnCount), imageCount, headersFooters (each:
side, slot, text), trackedChangeCount.
Raw package#
xml ls: file, parts (each: path, byteCount).
xml cat: file, part, match, fragments (the distinct elements
that contain match: several matches in one paragraph show it once),
truncated (more than 20 such elements; the first 20 are shown).
xml patch: file, part, replacementCount, saved, checkpoint,
copiedFrom.
copiedFrom (replace-all, call, accept, reject, xml patch):
with --out, the original the copy was made from, and file is the copy the
edit was saved to; otherwise null. When the edit fails outright (exit 1),
no copy is left behind.
Everything else#
examples: examples, each { description, command }, plus docs
(a page to read more) on some.
skill: markdown. skill install (its own command name):
output, outputWritten.
help and --help: commands and globalOptions, or command for
one command's help (each command: name, usage, summary, options).
version: version, build.
Tool calls#
call, the tool shorthand (revise replace contract.docx '{…}'), read,
and search run an editing tool and report:
| Key | Meaning |
|---|---|
file, saved, checkpoint | As for every command that can change a document. |
tool | The tool that ran. |
message | The tool's summary, for reading; may span lines. null if none. |
changeIds | Tracked changes this call created. An edit that extended an existing change creates none, so an empty list does not mean nothing changed: check saved. |
html | The blocks the call returned, as HTML with block ids, or null. |
result | The tool's own structured result, or null. Its keys are the tool's own and include snake_case ids such as search_result_id, which later calls take as input. |
view | read and search only: the view html shows (tracked, accepted, or original). |
viewMatches | search only: blocks the search tool can't see in the view (each: query, blockId, blockIndex, text, changeIds). Tracked: matches inside deleted text. Original: every match in the original text, and html and result are null (no search_result_id). |
A search_result_id stays valid across commands until the document changes.
revise remembers the 20 most recent searches per file; an older id is
refused with unknown_search_result.
When a tool refuses a call, the command exits 1 with error.code
tool_error, the tool's own code in error.details.toolCode, and a data
receipt showing saved: false.
Error codes#
| Code | When |
|---|---|
usage | Wrong arguments, a missing argument, or an unknown option. |
unknown_command, unknown_tool | No such command or tool. |
file_not_found | A file the command needs does not exist: the document, an input, --from, or @file.json. |
checkpoint_not_found | No such checkpoint. |
unsupported_format | revise can't read or write that format. |
read_only_format | revise reads the format but can't save it in place. |
import_failed, read_failed | The file did not open or could not be read. |
would_overwrite | The output exists; add --force. |
same_file | The output is the input. |
file_busy | Another revise command held the file too long. |
file_changed | Another program saved the file while revise worked on it. Nothing was written. |
write_failed, commit_failed | The file or its history could not be written. The document was left as it was; a file new had already created is reported with outputWritten: true (exit 2). |
io_error | The system refused a read or write (permissions, a full disk). details: errno, syscall. |
save_uncertain | A save failed and could not be rolled back. Exit 70. The next command on the file finishes or undoes it. |
invalid_regex | grep --regex got a pattern that does not compile. |
invalid_json | Tool input is not a JSON object. |
invalid_selection | accept/reject got a selection that can't be combined, or a block range written last..first. |
section_not_found | --section or --except-section matched no heading. The message lists the headings. |
section_ambiguous | The --section text is in more than one heading. Name one by its number or full title. |
block_not_found | --blocks named a block id the document doesn't have. |
tool_error | A tool refused the call; see details.toolCode. |
unknown_search_result, stale_search_result | The search result id is unknown, or the document changed since that search. |
change_not_found | Some requested change ids are not pending. |
change_not_resolved | Some pending changes could not be accepted or rejected. |
replace_failed | Some blocks could not be edited. |
redline_unverified | The redline was written but failed its check. |
page_setup_failed | new wrote the file, but applying the page setup failed. |
no_package | The file is not a .docx, so it has no package XML. |
no_such_part | No such part in the package. |
malformed_xml | A patch would produce XML that does not parse. |
find_not_found, find_ambiguous | xml patch --find matched nothing, or more than once without --all. |
body_shape_changed | xml patch on word/document.xml would add or remove paragraphs; use the tools. |
canvas_missing | Rendering needs the optional @napi-rs/canvas package. |
render_failed, page_out_of_range, too_large | Rendering failed, the page does not exist, or the image would be too big. |
internal | A bug. Run again with REVISE_DEBUG=1 for a stack trace on stderr. |
Warning codes#
| Code | When |
|---|---|
file_changed_outside | The file changed since revise last saw it, and revise re-read it. details: keptBlockCount, changedBlockIds, newBlockCount, removedBlockIds. Read changed and new blocks again before editing them. |
save_recovered | An earlier command was interrupted after writing the file; revise finished recording it. |
changes_accepted | The output format can't hold tracked changes (anything but .docx), so it shows them accepted. details: trackedChangeCount. |
font_fallback | A PDF used fallback fonts. details: fonts. |
untracked_regions | compare: parts that differ but can't carry tracked changes. details: regions. |
summary_unavailable | export wrote the file but could not read it back to describe it. |
export_note, engine_warning | Anything else the export or engine reported. |