Tool · Node.js
compare-cli
Compare two contract versions (the negotiated text vs the ready-to-sign artifact) and
classify every difference as cosmetic, typographic,
or substantive. The exit code is the contract: 0
safe to sign, 2 substantive drift, 3
cosmetic-only, 4 clauses moved but content identical. The
pre-signature gate in the workflow.
npm i -g compare-cli, then
compare negotiated.docx ready-to-sign.pdf. Reads
.docx / .pdf /
.md / .txt / stdin on either side,
cross-format. Pair with --from-negotiation negotiation.json to
pull the agreed text from nda-review-cli's state file.
Try it live
Paste two versions and hit Run — you get the clause-aware verdict and the exit code that gates a signature.
Runs the real CLI on your input in a sandbox — no setup, nothing stored. Open in a new tab ↗
What it does
- Clause detection cascade. H2 (
## Title) → bold-numbered (**1. Title**) → ALL-CAPS standalone → synthetic single-clause fallback. Strict cascade — earlier tiers win, no shadowing. The same rule is implemented in template-vault-CLI (Python); the spec lives atdocs/clause-detection.md. - Five-class spectrum (locked).
clean,cosmetic(whitespace, curly quotes, em-dashes, NBSP),typographic(case, number format, Oxford comma),substantive(any word change, addition, deletion),moved(byte-identical body in a different position). Mapping to exit codes never changes within a major version. - Two normalization passes define the cosmetic / typographic / substantive boundary deterministically. What's not normalized away (singular/plural, tense, negation, sentence punctuation) is captured in COMPARE_SCHEMA.md §5–§6.
- Move detection via LIS over clause-title alignments. Exact, no fuzzy
threshold.
movedis suppressed when the body class is non-clean (substantive wins). - Intra-clause word diff in human output (added in 0.2.0): substantive
changes render inline as
[-removed-]{+added+}(or red/green color in a TTY).--no-intra-diffopts out. --from-negotiation NEG.jsonreads the agreed text from nda-review-cli'snegotiation.jsonwith a three-tier resolution (top-levelstatus: converged→ per-roundagreed: true→ per-roundclause_statusall"agreed"). Pair with--require-signoffsfor unattended pipelines.- Output formats: human (default, color-aware),
--json(stable shape locked across v1.x),--sarif(SARIF v2.1.0 for GitHub code-scanning).--checksuppresses all output for CI-gate-only use. - Track-changes metadata from
.docx<w:ins>/<w:del>surfaces in--jsonoutput asbase.track_changes/candidate.track_changes(added in 0.3.0). Author + date provenance alongside the text-diff verdict. - Clause filters:
--only-clauses Term,Paymentor--ignore-clauses Noticesnarrow the report and the exit-code calculation. Suppressed count surfaces in JSON for auditability.
Quickstart
# Install
npm i -g compare-cli
compare --version
# Headline use: negotiated.docx vs ready-to-sign.pdf
compare negotiated.docx ready-to-sign.pdf
# Same comparison, structured JSON
compare negotiated.docx ready-to-sign.pdf --json
# From the negotiation state file
compare --from-negotiation negotiation.json ready-to-sign.pdf
# Unattended pipelines: require both parties signed off
compare --from-negotiation negotiation.json ready-to-sign.pdf --require-signoffs
# CI gate: exit code only
compare base.docx cand.docx --check && echo "safe to sign"
# SARIF for GitHub code-scanning
compare base.docx cand.docx --sarif > drift.sarif For agents and automation
Agent affordances are baked in.
AGENTS.md
documents the stable --json shape, exit-code enumeration, and
the recommended invocation patterns (pre-signature gate, focusing on material clauses,
strict-mode for high-stakes pipelines). The five exit codes never re-number without a
major-version bump.
For MCP-driven agent loops,
compare-cli-mcp
wraps the CLI as an MCP server with three tools
(compare_files, compare_with_negotiation,
compare_demo) over stdio. Substantive drift is a successful tool
call returning structured content; only genuine errors (I/O, malformed input, no agreed
round) become MCP errors. Design contract:
docs/mcp.md.
Where it fits in the workflow
The pre-signature gate. Take the agreed text (from a clean
draft-cli render or a converged
nda-review-cli negotiation.json), compare against the ready-to-sign artifact
(PDF rendered by docx2pdf-cli, or the
.docx the counterparty mailed back). Gate the
sign-cli invocation on exit 0 (or accept 3 and 4 with
eyes open).
See the full workflow for the chained commands.
Repo
github.com/DrBaher/compare-cli · MIT licensed · Node.js · two runtime deps (jszip + pdfjs-dist) · npm-installable as compare-cli.