Changelog
What's new across the suite.
Notable releases for each CLI plus this site. Filed in reverse chronological order. Subscribe by watching @DrBaher on GitHub for everything.
- sign-cli v0.7.0 June 3, 2026 sign-cli
sign-cli v0.7 — verification is now cryptographic (and a security hardening pass)
Heads-up: this release changes behavior in ways you should read before upgrading. A signed PDF that previously verified
okagainst a non-cryptographic or forged signature will now correctly fail — that is the fix, not a regression.Verification is now genuinely cryptographic (breaking)#
Through 0.6.x,
verify/request verify-signed-pdf(and thepdf_inspect_signaturesMCP tool) only recomputed the SHA-256 over the PDF’s/ByteRangeand compared it to themessageDigestembedded in the PKCS#7 — it never verified the signature value itself against the signer certificate’s public key. A fully forged PKCS#7 with no private key could reportverdict=ok.0.7.0 performs real RSA/ECDSA verification (
createVerify) of the signed attributes against the signer cert’s public key. Forged and tampered signatures now fail as they should. If a PDF you relied on suddenly fails, it was never cryptographically signed.MCP & provider hardening (breaking)#
- MCP HTTP server binds
127.0.0.1by default (was0.0.0.0). Pass--http-bind 0.0.0.0to expose it; the hosted container entrypoint already does, so Railway/hosted deployments are unaffected. profile_show {show_secrets:true}now requires authentication — over HTTP that means a configured--http-auth-token. Provider API keys are no longer reachable unauthenticated.- Default provider is now the offline
localPAdES signer (was Dropbox Sign). A brand-new user’s firstrequest create/sendno longer demands hosted-provider credentials — “no signup, no keys” works out of the box. Resolution order is unchanged; only the final fallback did. signer_fetch_documentabsolute output paths now requireSIGN_ALLOW_ABSOLUTE_DOCS=1and are refused in--read-only.
0.7.1 — standalone binaries#
v0.7.1is build-tooling only (no runtime change) and attaches standalone executables to the GitHub release —sign-darwin-arm64,sign-linux-x64,sign-win32-x64.exe— for runningsign-cliwithout a Node install. - MCP HTTP server binds
- site v0.1.0 May 23, 2026 site
contract-ops-mcp — one MCP server for the whole suite
The suite already had two MCP servers (
sign-cli’s 19-tool signing server,compare-cli-mcp’s drift gate). Now there’s a unifying one: contract-ops-mcp.Wire it up once and an agent gets the whole suite as tools:
{ "mcpServers": { "contract-ops": { "command": "npx", "args": ["-y", "contract-ops-mcp"] } } }- Curated, typed tools for the common operations —
extract_contract,lint_contract,compare_versions,fill_template,convert_to_pdf,review_nda,template_vault_*,contract_vault_*, and read-onlyverify_signature/verify_receipt/audit_show— each returning structured JSON. - Escape hatches for the long tail:
catalog(cli)(any CLI’s full--catalog json) andrun(cli, args), plussuite_statusfor what’s installed. - Discovery-driven — the tools ride the suite’s uniform
--catalog jsoncontract (the same one the weekly drift-check guards), so they stay in sync as the CLIs evolve. - Signing stays human-gated. Only
sign-cli’s read/verify ops are exposed; request/sign stay behindsign-cli’s own MCP with its per-signer approval tokens, so this server can never become an unguarded signing path. - Filesystem lockdown via
CONTRACT_OPS_MCP_BASE_DIR; no-shellexecFile.
It needs the CLIs installed —
curl -fsSL https://cli.drbaher.com/install.sh | sh, or run everything in theghcr.io/drbaher/contract-opsimage. See the MCP page. MIT, on GitHub. - Curated, typed tools for the common operations —
- template-vault-cli v0.5.1 May 23, 2026 template-vault-cli
template-vault-cli v0.5 — agent discovery + a local-first hardening pass
template-vault-cli shipped two releases:
- 0.5.0 — agent discovery.
template-vault --catalog jsonnow answers the suite-wide discovery contract ({name, bin, version, description, commands, exitCodes}, walking the live argparse tree including nested subcommands), so an agent learns every command and flag at startup. This had been onmainsince 0.4.8 but was never published — 0.5.0 releases it to PyPI. - 0.5.1 — a local-first hardening pass. Because the vault is plain files on your machine, 0.5.1 tightens the boundaries:
- Path containment —
category/name,compose --as,upload --category, and a custom sources registry are validated as single path segments, so a crafted reference can’t escape the vault with a../../etc/passwd-style value. - URL-scheme validation —
importand the LLMbase_urlaccept onlyhttp/https(nofile://local reads), and thebase_urlrefuses plainhttpto a non-loopback host, so an API key is never sent in cleartext (http://localhoststays allowed for local models like Ollama). - Owner-only permissions — new vault directories are created
0700and.vault.json/meta.json/ template files0600(best-effort POSIX; ACLs apply on Windows). - Supply-chain hardening — every GitHub Action pinned to a full commit SHA, least-privilege
publish.ymlwith PEP 740 build attestations, plus CodeQL (security-extended), a Bandit gate,CODEOWNERS, and weekly Dependabot.
- Path containment —
On the site, the tool page gains a “hardened for a local-first vault” note,
llms.txtrecords the safety properties, and the registry tracks 0.5.1. The 25-command surface is unchanged. - 0.5.0 — agent discovery.
- contract-lint-cli v0.1.0 May 22, 2026 contract-lint-cli
contract-lint-cli joins the suite — a pre-signature quality gate
contract-lint-cliis the ninth CLI in the suite — and the gate the workflow was missing.Until now the only pre-signature gate was compare-cli, which catches drift between versions. Nothing checked a contract’s internal consistency. contract-lint fills that slot:
- Eight deterministic rules. Errors:
placeholder(leftover[Bracketed]/{{mustache}}/TBD) andbroken-xref(a Section/Exhibit/Schedule reference with no target). Warnings (on by default):unused-definition,double-definition,numbering,party-consistency,date-sanity.undefined-termships off by default. - A real CI gate.
--fail-on error|warning|nonesets the threshold,--checkis exit-code-only. Exit0clean ·1findings at/above the threshold ·2bad usage. No model, no network, byte-stable (timestamp-free) output. - Machine-readable. A human table by default;
--json(locked schema) and--sarif(2.1.0) for tools and agents.contract-lint --catalog jsonandcontract-lint rules --jsonare the discovery surface.
The mental model:
compare-cligates drift between versions; contract-lint gates defects within one document. Run both after draft and before sign —draft → contract-lint / compare → docx2pdf → sign. It also stands alone as a deterministic CI check for any team that drafts contracts.It’s wired into the suite the same way as every other CLI: a tool page, the playground (paste a contract → see findings), the registry,
llms.txt, and the install + workflow pages. Stdlib-only Python, single file, MIT —pipx install contract-lint. - Eight deterministic rules. Errors:
- contract-vault-cli v0.4.2 May 22, 2026 contract-vault-cli
contract-vault-cli v0.2 → v0.4 — obligation lifecycle, recurring obligations, reminders
contract-vault-cli moved fast from its 0.1 register into a full post-signature obligation tracker (0.2 → 0.4.2). Highlights:
- Obligation lifecycle (0.2.0). Every obligation now carries a stable
id, astatus(open/done/waived), and an optionalowner.obligation <deal> <id> --status … --owner …tracks it;due/obligationsare now status-aware — only open obligations by default, so completing one drops it off the calendar. Lifecycle survives a re-ingest/recompute (carried forward by id). - Recurring obligations + per-obligation reminders (0.3.0). Obligations can recur (
weekly/monthly/quarterly/semiannual), and each can set its own reminder lead-times (--reminders 30,7). - The
reminddigest (0.3.1).contract-vault remindlists the obligations whose reminder window is open right now — a digest built for cron jobs and agents (pair with--json). - Corpus-wide reminder policy (0.4.0).
config reminderssets default reminder lead-times once for the whole vault, instead of per obligation. - Scheduling guide (0.4.1). A bundled
docs/SCHEDULING.md+ examplecontract-vault-remind.shshow how to run the reminder digest from cron. - Adoption hardening (0.4.2). Validated end-to-end against the real
extract-clifor the first time (tolerates its evolving output shape), anddue --format icsis now Windows-safe (no\r\r\n).
On the site, the tool page and
llms.txtnow cover the obligation lifecycle, recurrence, and theremind/config reminderssurface, and the registry tracks v0.4.2. The page also leads with contract-vault’s standalone value — a git-backed register that never lets a renewal or obligation slip — with its place in the contract-ops suite as a secondary note. - Obligation lifecycle (0.2.0). Every obligation now carries a stable
- site v0.7.0 May 22, 2026 site
Site — contract-vault-cli joins the suite as the eighth CLI
contract-vault-cli is the eighth CLI: the suite’s post-signature (“manage-out”) layer. The pipeline used to end at sign-cli with an executed agreement — but that’s exactly when the obligations begin. contract-vault registers each signed contract in a git-backed vault and surfaces what you’d otherwise miss: auto-renewal notice deadlines, expirations, payment dates, and obligations — as a queryable portfolio and an
.icscalendar. It’s the sibling of template-vault: template-vault stores the blanks, contract-vault stores the signed instances. It ingests extract-cli output and keeps the suite’sconfidence/sourceenvelope (with a humanacceptworkflow that promotes fields tosource: manual).What changed on the site:
- New tool page at
/tools/contract-vault-cli/, mirroring the sibling skeleton (TL;DR, try-it-live explorer embed, what-it-does, quickstart, agent affordances, where-it-fits, repo link). - Registry entry in
src/data/registry.ts— PyPIcontract-vault, repoDrBaher/contract-vault-cli— version / stars / downloads fetched at build time alongside the other seven. Fallback0.1.8. - Homepage — hero, TL;DR, the “eight tools at a glance” table, the ToolCard grid (now eight cards), and “why eight small tools” all rebalanced from seven to eight, with contract-vault last.
- Workflow diagram extended to a data-driven eight-box SVG:
ingest → store → draft → review → compare → convert → sign → manage. - Workflow walkthrough gains a “8 — Manage (post-signature)” step (register the signed contract, project its renewals calendar, gate on missed notices).
- Playground gains an eighth tab (
?cli=contract-vault) — a read-only explorer over a seeded register; the/playpage and tour now cover all eight zero-config demos. - Install page — new
contract-vault-clisection (pipx, with the[docx]extra), prerequisites, and Updating / Uninstalling commands. - Sibling pages, OG images, sidebar, footer, search,
built-for-agents,llms.txt, content config, the cli-link plugin, changelog index/RSS, and thepackage.jsondescription all move to the eight-CLI narrative. (Also backfilled the changelog badge color forextract-cli, which had been missing.) - Icon — a signed contract behind a clock (the renewals/deadlines this layer watches) in the suite palette.
On the repo side,
contract-vault-clialso shipped v0.1.8: thecontract-vault --catalog jsondiscovery contract (generated by walking the live parser across all 18 commands), anAGENTS.md, anllms.txt, and the suite-standard packaging keywords — so it answers the same agent contract as the other seven. - New tool page at
- site v0.6.0 May 22, 2026 site
Site — extract-cli joins the suite as the seventh CLI
extract-cli is the seventh CLI: the suite’s open-loop front door. The rest of the pipeline is a closed loop that only handles documents authored from its own templates;
extract-cliingests any document — a counterparty’s foreign paper in.md/.txt/.html/.docx/.pdf— and emits structured JSON the pipeline can consume: parties, dates, term, governing law, and a clause map normalized onto the suite’s canonical clause vocabulary. Every field carries aconfidenceand asource, so downstream tools verify, don’t trust. It sits upstream of review, feeding nda-review-cli and compare-cli.What changed on the site:
- New tool page at
/tools/extract-cli/, mirroring the sibling skeleton (TL;DR, try-it-live playground embed, what-it-does, quickstart, agent affordances, where-it-fits, repo link). - Registry entry in
src/data/registry.ts— PyPIextract-cli, repoDrBaher/extract-cli— version / stars / weekly-downloads fetched at build time alongside the other six. Fallback0.1.8. - Homepage — hero, TL;DR, the “seven tools at a glance” table, the ToolCard grid (
lg:grid-cols-3, now seven cards), and “why seven small tools” all rebalanced from six to seven, withextract-clifirst. - Workflow diagram rebuilt as a data-driven seven-box SVG:
ingest → store → draft → review → compare → convert → sign. - Workflow walkthrough gains a “0 — Ingest any contract” front-door step (extract feeds review/compare; the closed loop still starts at step 1 if you’re authoring from your own template).
- Playground gains a seventh tab (
?cli=extract); the/playpage and tour now cover all seven zero-config demos. - Install page — new
extract-clisection (pipx, with[docx,pdf]extras), prerequisites, and Updating / Uninstalling commands. - Sibling pages, OG images, sidebar, footer, search,
built-for-agents,llms.txt, content config, the cli-link plugin, and thepackage.jsondescription all move to the seven-CLI narrative. - Icon — a document-under-a-magnifier motif (with JSON braces in the lens) in the suite palette.
On the repo side,
extract-clialso shipped theextract --catalog jsondiscovery contract, anAGENTS.md, anllms.txt, and the suite-standard packaging keywords (v0.1.7) — so it answers the same agent contract as the other six — alongside a round of clause-detection breadth from a real-corpus survey (v0.1.8). - New tool page at
- site May 20, 2026 suite
Suite — interactive playgrounds, uniform discovery, and a polish pass
A communication, onboarding, and discoverability pass so the suite is easy to try, easy to drive, and consistent end to end.
- Run any of the six in your browser. The new playground executes the real CLIs on your own input in a sandbox — draft, compare, docx2pdf and a template-vault explorer share one runner, alongside the existing nda-review and sign hosted demos. Each tool page also has a “Try it live” embed.
- Uniform agent discovery. All six CLIs now answer
<cli> --catalog jsonwith one shape —{ name, bin, version, description, commands|flags, exitCodes }— so an agent discovers the surface the same way everywhere instead of special-casing each tool. Added it to template-vault, draft, and compare; aligned nda-review and sign to match. - A friendly first run. Running
draftorcomparewith no arguments now prints a short “here’s what I do, try the demo, here’s where I fit” hint instead of a terse error — matching template-vault and nda-review. - One name. Standardized the prose name to contract-ops across every repo’s docs, and gave each repo a consistent “part of the suite” cross-link.
- More ways in. A 5-minute tour of the whole suite and a recipes page for real situations (an incoming third-party NDA, a CI drift gate, an agent loop, batch convert + sign).
- Accuracy fixes. Corrected the per-CLI exit-code matrix (
draft-cliis0–4, not0–5) and refreshedllms.txtto reflect the uniform discovery contract.
- site v0.5.0 May 20, 2026 site
Site — template-vault-cli joins the suite as the sixth CLI
Following compare-cli joining as the fifth CLI, template-vault-cli is the sixth: the Git-backed, clause-aware storage layer at the start of the workflow. Your house templates and forked public sources (Common Paper, YC SAFE, Bonterms) live in one searchable, version-tracked vault;
template-vault get <ref>resolves a template to hand to draft-cli. The full pipeline is nowstore → draft → review → compare → convert → sign.What changed on the site:
- New tool page at
/tools/template-vault-cli/, mirroring the sibling skeleton (TL;DR, what-it-does, quickstart, agent affordances, where-it-fits, repo link). - Registry entry added in
src/data/registry.ts— PyPItemplate-vault-cli, repoDrBaher/template-vault-CLI— with version / stars / weekly-downloads fetched at build time alongside the other five. Fallback0.4.8. - Homepage — hero, TL;DR, and “why six small tools” rebalanced from five to six; the ToolCard grid stays
lg:grid-cols-3, now a clean 2×3 with template-vault first. - Workflow diagram rebuilt as six boxes, one per CLI:
store → draft → review → compare → convert → sign. - Workflow walkthrough gains a “Store & version” step at the front (the compare drift-gate step was already integrated); step anchors carry explicit ids so they stay stable.
- Install page — new
template-vault-clisection (pipx, with the[docx]extra), prerequisites, a config-locations row, and Updating / Uninstalling commands. - Sibling tool pages cross-link template-vault as the source of templates;
built-for-agents,llms.txt, OG images, sidebar, footer, 404, compare, principles, and thepackage.jsondescription all move to the six-CLI narrative. - Icon — a stacked-versions motif in the suite palette (cream bg,
#1f7d5dprimary).
Suite description is now: “Six composable, local-first CLIs for the contract operations workflow.” Storage is an explicit step instead of an implicit prerequisite.
- New tool page at
- site May 20, 2026 suite
Suite — uniform demos, stdin piping, and one shared LLM config
A consistency pass across the six CLIs so the suite behaves like one thing instead of six tools that happened to ship together. These changes are on each repo’s
mainand land in their next published releases.- A zero-config
demoon every CLI. Addeddocx2pdf demo(converts a bundled sample with whatever backend is installed) and a non-interactivenda-review-cli demo(reviews the bundled sample NDA against the bundled default policy). template-vault-cli, draft-cli, compare-cli, and sign-cli already had one — now all six do. - The pipeline actually pipes. docx2pdf-cli and nda-review-cli now read from stdin (
-), joiningdraft-cliandcompare-cli. The full chain composes end to end:template-vault get … | draft - | nda-review-cli review --file - | compare … | docx2pdf - - | sign …. - Configure your LLM once for the whole suite. draft-cli now reads the suite-shared
~/.config/contract-ops/llm.json(the environment still wins), matchingtemplate-vault-cliandnda-review-cli.template-vault-cli’s setup docs and error messages now point at that shared path too. - Honest agent contract on the site. Built for agents gained a per-CLI exit-code matrix, and
llms.txtwas corrected — the exit codes are not uniform across the suite (compare-clireuses0–4as drift severities;template-vault-cliuses0/1/2), so agents should branch per CLI.
- A zero-config
- template-vault-cli v0.4.8 May 19, 2026 releaseinterop
template-vault-cli v0.4.8 — cross-CLI interop: schemas, INTEROP doc, shared LLM config
v0.4.8 turns
template-vault-cli’s outputs into a contract the rest of the suite can build on.- Six JSON Schemas in
docs/spec/(JSON Schema 2020-12) for the data template-vault produces:meta.schema.json,vault-config.schema.json,info-json.schema.json,find-json.schema.json,history-json.schema.json,stats-json.schema.json. Stable since this version, with a semver commitment — a backward-incompatible change requires a major version bump. Downstream tools (e.g.nda-review-clireadinginfo --json) can validate against the schema files directly instead of trusting field shapes by convention. docs/INTEROP.md— the cross-CLI contract document and citation point for the schemas, the shared LLM-config lookup, and the suite-wide UX conventions (--whyto stderr,--jsonon stdout,-q/--silentaliases,--no-color,NO_COLOR, exit codes).- Shared LLM config —
~/.config/contract-ops/llm.jsonis now the suite-wide provider config location, shared withnda-review-cli. Configure it once and LLM features light up across every Python tool in the suite that adopts the same lookup order.
template-vault-clistructures existing templates; it does not generate clause text. Theaskcommand remains opt-in and metadata-only by default. Install:pipx install template-vault-cli. - Six JSON Schemas in
- compare-cli v0.3.0 May 18, 2026 releasedocx
compare-cli v0.3.0 — surface .docx track-changes metadata
A minor release that makes
.docxtrack-changes visible without changing what the gate decides.- New
extractDocxTrackChanges(buf)— parses<w:ins>and<w:del>elements fromword/document.xmland returns a flat, document-ordered list of{ op: "ins" | "del", text, author, date }. Robust to malformed input (non-zip or missingdocument.xmlreturns an empty array rather than throwing). readInputon a.docxpopulatestrack_changeson the returned side object. Non-.docxinputs don’t have the field; consumers should treat missing as[].--jsonoutput now includesbase.track_changesandcandidate.track_changesas stable arrays.
Informational only. Track-changes presence does not change the exit-code classification — the text diff remains the source of truth in v0.3.x (still
0match ·2substantive ·3cosmetic ·4moved). A future version may use track-changes as ground truth where both sides carry it. Install:npm i -g compare-cli. - New
- site v0.4.1 May 18, 2026 site
Site — compare-cli joins the suite as the fifth CLI
compare-cli is the pre-signature gate: 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 —
0safe to sign,2substantive drift,3cosmetic-only,4clauses moved but content identical.What changed on the site:
- New tool page at
/tools/compare-cli/— mirrors the sibling tool-page skeleton (TL;DR, what-it-does, quickstart, agent affordances, where-it-fits, repo link). - Registry entry added in
src/data/registry.ts— npmcompare-cli, repoDrBaher/compare-cli. Version, GitHub stars, and weekly downloads now fetched at build time alongside the other four CLIs. Fallback version0.2.1. - Sidebar Tools section adds
compare-clias the fifth entry underdraft-cli/nda-review-cli/docx2pdf-cli/sign-cli. - Footer Repos column adds the
compare-cliGitHub link. package.jsondescription updated to list five CLIs.
What’s NOT in this PR (deliberate scope cut, follow-ups welcome):
- Homepage hero rewrite (“Four CLIs” → “Five CLIs”). The current copy still reads as four; would benefit from a paragraph re-balance.
- ToolCard grid layout reflow to fit a fifth card cleanly (probably a 1 / 2 / 5 or 1 / 2 / 3 wrap).
- Workflow diagram — currently doesn’t have a pre-signature gate box; adding
compare-clithere is a real design question (does it sit between docx2pdf and sign? After sign as a verify step? Both?). - Use-cases page —
compare-cliis a natural fit for the “vendor onboarding” and “negotiated contract” flows but the prose hasn’t been updated. - Compare-vs-SaaS page — no
compare-clirow in the feature-comparison table yet. built-for-agents.astro— should call outcompare-cli-mcpand thecompare_files/compare_with_negotiation/compare_demotools alongside the existing MCP discovery snippets.
The tool page works on its own. The narrative integration above is the next step.
- New tool page at
- draft-cli v0.9.0 May 17, 2026 releasedocx
draft-cli v0.9.0 — smart run-merge for cross-run .docx placeholders
Real-world Word documents split bracketed placeholders across multiple
<w:r>runs because brackets and inner text carry different styling. The Common Paper Mutual NDA template splits[Fill in: today's date]into three runs —[,Fill in: today's date,]— each with its own<w:rPr>. Up to v0.2.0,draft-clidetected this and skipped substitution with a warning, leaving the user to retype the placeholder in Word. Fine for the rare case, but a blocker on most production contracts.v0.9.0 changes the default: when a placeholder spans multiple runs inside the same paragraph,
substituteDocxXmlnow collapses the contributing runs into one that uses the first contributing run’s<w:rPr>. Mid-placeholder styling variations are lost (if[was bold and the inner text was italic, the merged run is bold); styling on the runs flanking the placeholder is preserved (any trailing text from the last contributing run keeps its<w:rPr>as a second run). Each merge emits adocx run merge applied for "<key>"warning so the rewrite is visible.New
--strict-runsflag restores v0.2.0 behavior: cross-run placeholders are skipped (not merged) and emit askippedwarning. Use it when you want every style boundary inside placeholders preserved and you’re willing to retype them in Word.Cross-paragraph placeholders are still skipped regardless of
--strict-runs— collapsing runs across a<w:p>boundary would destroy paragraph structure.API change:
substituteDocxXml’s return shape goes from{ xml, warnings }to{ xml, merged, skipped }. New fifthoptsargument:{ mergeRuns?: boolean }(defaulttrue).Verified end-to-end on the actual Common Paper Mutual NDA
.docxthat triggered the bug report: all 7 placeholders substituted with no leftover brackets. 288 tests passing (6 new for cross-run scenarios).Install:
npm i -g @drbaher/draft-cli. The locked decision Q1.1 in PARAM_SCHEMA.md was revised to document the new default. - site v0.4.0 May 17, 2026 site
Site — draft-cli joins the suite as the fourth CLI
draft-cli is the templated drafting step at the start of the contract pipeline: fill placeholders in markdown or
.docxtemplates, hand the filled draft to nda-review-cli for policy review or directly to docx2pdf-cli for PDF rendering.What changed on the site:
- New tool page at
/tools/draft-cli/— mirrors the sibling tool-page skeleton (TL;DR, what-it-does, quickstart, agent affordances, where-it-fits, repo link). - Homepage hero rewritten — “Three CLIs” → “Four CLIs” with
draft-cli’s tagline added to the “drafting an NDA, reviewing what comes back, negotiating, converting to PDF, signing” narrative. - ToolCard grid went from 3 columns to a responsive 1 / 2 / 4 layout. The card body was rebalanced so the tags row, install command, and “Read more” link sit at the same vertical position across cards even when taglines have different lengths.
- Workflow diagram — step 1 box now reads
draft-cli/draftinstead ofnda-review-cli/draft. The bottom-strip caption updates from “house policy” to “your template” to match. - Workflow walkthrough — step 1 rewritten around
draft template.docx --params deal.json, with a clarifying note thatnda-review-clistill ships bundled NDA templates and can render them directly via its owndraftsubcommand for the NDA-specific case. - Install page — new
draft-cliinstall section first (npm / pnpm / yarn / npx tabs), prerequisites list updated to list Node.js first, configuration-locations table row added, Updating + Uninstalling commands updated. - Sibling tool pages cross-link
draft-cliwhere the pipeline narrative calls for it. - Vendor-onboarding use case updated to chain
draft …thennda-review-cli review …rather than a singlenda-review-cli draftcall. - Built-for-agents discovery lists
draft --list-placeholders --jsonalongside the sibling CLIs’ discovery commands. - OG images, llms.txt,
og-default.svg, sidebar, footer, 404, compare, principles, package.json description — all updated to the four-CLI narrative. - Icon — bracket motif (suite palette: cream bg,
#1f7d5dprimary), tuned for legibility at the 40 × 40 ToolCard size.
Suite description is now: “Four composable, local-first CLIs for the contract operations workflow.” Same shape as before, with templated drafting as the first explicit step instead of an implicit prerequisite.
- New tool page at
- docx2pdf-cli v0.2.2 May 15, 2026 releaseagentcatalog
docx2pdf-cli v0.2.2 — `--catalog json`, agent-doc reorg, telemetry shipped
The agent-discovery + telemetry-on-npm release.
--catalog json— machine-readable flag inventory matching the cross-suite contract (parallelssign --catalog jsonandnda-review-cli --catalog json). Stable across minor versions. Complements the existing--capabilities(feature contract) and--doctor(host readiness). Agents call this at startup rather than parsing--help.--retries <n>— retry network backends (gotenberg,convertapi) with non-busy backoff (Atomics.wait). Advertised viasupports.retries: truein--capabilities.- JSON success telemetry — every success row in
--jsonmode now carriesbackend,input,output,outputBytes, anddurationMs. Failure rows carryexitCodeso a batch consumer can branch per file. NDJSON shape is documented in docs/reference/json-output.md. CliError.kind— structured error class (e.g."NO_BACKEND") so library callers branch on error type, not message text.- Doc reorg adopted — new
AGENTS.md(replaces the priordocs/AGENT_INTEGRATION.md),docs/setup/per-backend (LibreOffice, Gotenberg, ConvertAPI, Pages, Word),docs/reference/for concept docs (backends, doctor JSON shape, exit codes, json-output), and a newschemas/doctor.schema.jsonso the--doctoroutput is now formally schema-validated. - README restructured around audience: “Run this” (
docx2pdf --doctor) → “Where to go next” decision tree → human quickstart → agent affordances. Human path precedes the agent section now.
Install:
npm i -g docx2pdf-cli(already on npm). - nda-review-cli v0.5.1 May 15, 2026 releaseagentcatalog
nda-review-cli v0.5.1 — `--catalog json`, `sample-nda`, `doctor --check-llm`, doc reorg
Cuts the agent-discovery + onboarding-polish work as v0.5.1.
nda-review-cli --catalog json— machine-readable inventory of every subcommand and flag, including the nestednegotiate <sub>tree (23 top-level commands, 12 nested negotiate subcommands). Stable across minor versions. Matches the cross-suite contract used bysign --catalog jsonanddocx2pdf --catalog json. Agents call this at startup rather than parsing--help.sample-nda --out PATH— drops the bundled sample NDA fixture into a user-chosen path so first-run users have something substantial to pointreviewat without knowing the fixture’s filesystem location. The fixture is a representative SaaS-style mutual NDA with clauses that reliably trip rule-engine findings (jurisdiction mismatch, indefinite-survival carve-out, term length).doctor --check-llm— sends a 1-token round-trip to the configured LLM provider (fromconfig/llm.jsonorNDA_LLM_*env vars) to confirm reachability, model name, and auth. Closes the most common LLM-setup stumble: “I edited config/llm.json, did it work?”--helpepilogs with concrete examples for the four most user-facing subcommands:review,draft,doctor, andnegotiate init. Replaces a README round-trip with in-place discovery.- First-run hint adapts to invocation form — detects whether the user invoked as
./nda_review_cli.pyornda-review-cli(pipx) and prints the matching prefix in every example. Disambiguates the three onboarding paths (tutorial/quickstart/setup --quick --yes). - Wheel-bundling fix —
pyproject.toml’s manifest now uses atemplates/*.mdglob so all bundled templates (including Common Paper Mutual NDA v1.0) ship in the wheel. The previous per-file allowlist silently omitted templates. - Sandboxed web demo under
web/with one-click deployment to Railway / Fly.io / Render. Stdlib-only Python service wrapping the CLI behind three browser flows (draft / review / negotiation simulator). Per-session UUID sandboxes auto-expire after 30 minutes. - Doc reorg adopted — new top-level
AGENTS.md,docs/setup/(per-LLM-provider setup: Anthropic, OpenAI, Ollama, OpenAI-compatible, plusintegrations.jsonhooks for handing off todocx2pdf-cliandsign-cli), anddocs/reference/for concept deep-dives (policy, stance, fatigue, scoring, state-file, exit codes, LLM data-flow). README trimmed from 619 to 280 lines.
Install: clone the repo or
pipx install git+https://github.com/DrBaher/nda-review-cli.git. PyPI publishing is being set up — once enabled,pipx install nda-review-cliwill fetch the latest release directly. - sign-cli v0.6.1 May 15, 2026 releasepadesverification
sign-cli v0.6.1 — `pdf inspect` for ANY signed PDF + pre-sign visibility + verify `--recipient`
A small, focused release that closes three real-world gaps surfaced in production signing flows.
sign pdf inspect— new top-level command that inspects PADES signatures on any signed PDF (yours, Adobe’s, DocuSign’s, Dropbox Sign’s, SignWell’s). Returns per-signature signer CN/email, cert subject + issuer, validity window, fingerprint, trust label (self_signed_local/self_signed_other/ca_signed/unknown), message-digest match, and parse warnings. Pure read — no DB interaction, no audit events. Pairs withrequest verify-signed-pdf(which adds request-level signer-match against the local DB); usepdf inspectwhen you don’t have a request to bind against — e.g. inspecting an incoming counterparty PDF. Companion: new MCP toolpdf_inspect_signaturesand HTTP routePOST /v1/pdf/inspect-signatures— samevalidateDocumentPathguard as the other PDF surfaces.- Pre-sign signature visibility —
signer fetch-document(CLI + MCPsigner_fetch_document+ HTTPPOST /v1/signer/fetch-document) now includes anexistingSignaturesfield in every response. Fields:count,hasSignature,allDigestsOk(false if any prior signature is broken — tamper or parse failure),signers[](subject / issuer / validity / fingerprint / trust / per-signer digestOk),warnings[]. So a signer fetching a PDF for countersignature can see what they’re about to countersign before they sign. Best-effort: if inspection throws on a malformed PDF, the field is populated with a degenerate summary plus a warning rather than failing the fetch. request verify-signed-pdf --recipient <email>— narrows thesigner_matchcheck to a single recipient instead of requiring the full persisted-signer roster. Mirrors the semantics ofrequest show --recipient. Useful mid-flight on multi-signer requests (verify Alice’s signature without failing because Bob hasn’t signed yet). Refuses unknown recipients withSIGNER_NOT_RECIPIENTrather than silently passing on vacuous truth.
Fixed#
request verify-signed-pdfno longer falsely reportssigner_mismatchagainst per-signer certs whose subjects contain RFC 4514 escapes — Node’sX509Certificate.subjectreturns the LDAP DN string, which backslash-escapes reserved chars (+,<,>,,). A per-signer cert subject likeCN=Baher Test \<baher\+dcc@example.com\>was being compared with a rawsubject.includes("baher+dcc@example.com")and failing — even though the signature was cryptographically valid (digest_ok: true). The matcher now strips backslash escapes before the substring check. Surfaced by a real-world signing test against GBrain agreements on 2026-05-14.
Docs#
- The doc reorg adopted across the three-CLI suite this week is captured in this release block too — new top-level
AGENTS.md,docs/setup/for provider-specific setup (Dropbox / DocuSign / SignWell / embedded), anddocs/reference/for concept docs (audit-chain, exit-codes, profiles, security model, security controls, legal posture, architecture, comparison).
Install:
npm i -g @drbaher/sign-cli(now published under the scoped name on npm — the unscopedsign-clibelongs to a different project that has nothing to do with this one). - sign-cli v0.6.0 May 14, 2026 releasemcpsecurityprofiles
sign-cli v0.6 — cross-surface parity, profiles, path-traversal guards
The biggest
sign-clirelease since the offline PAdES signer landed.- Cross-surface parity. Every operationally-useful CLI command now exists as both an MCP tool and an HTTP route. The MCP surface grew from 8 to 19 tools (added:
pdf_detect_signature_field,pdf_detect_date_field,pdf_inspect_signatures,profile_list,profile_show,pdf_stamp_text,preview,document,signer_reissue_token,audit_scan,request_receipt). The HTTP surface grew to 20 routes under/v1/*, all with the same input shape, the same path-traversal guards, and the same read-only gating. - Named profiles.
sign profile init / list / show / use / set / unset / deletebundlesprovider,dbPath,strictProvider, and acredentialsblock under a name. Credentials use{{env:VAR}}references that resolve from the shell at call time — secrets never live in the profile file. Activate via--profile prod,SIGN_PROFILE=prod, or implicitly via a project-levelsign-profile.json(git/npm-style upward-walk discovery). - Path-traversal guards on every input and output.
validateDocumentPath/validateOutputPathreject paths that escape the working directory; opt out withSIGN_ALLOW_ABSOLUTE_DOCS=1. Closes the gap where a malicious or buggy MCP client could read arbitrary files viapdf_pathor write sealed PDFs anywhere on disk. - One-shot
sign document. Takes a.docx(or.pdf), converts via the bundleddocx2pdf-cli, auto-places, stamps, PAdES-seals, and verifies the chain — all in one call against a scoped temp database that’s deleted on exit. sign previewfor offline placement iteration. Stamps a signature image or rendered name onto a PDF without producing a PAdES envelope or touching the DB. Surfaces the same quality warnings (STAMP_OFF_PAGE,STAMP_OVERLAPS_TEXT) as the sealed flow.- Auto-place with multi-candidate selectors.
--auto-placeacceptstrue,first,last,all,page:N, orindex:N. Closes theAUTO_PLACE_AMBIGUOUSfoot-gun where the user knew the rule but had no way to tell the CLI. - Date detection +
pdf stamp-text. Detection now recognizes date anchors alongside signature anchors (English, French/EU conventions).sign pdf detect-date-fieldreturns ranked date candidates with analreadyFilledflag;sign pdf stamp-textstamps plain text without an envelope. Skips already-filled anchors by default. - Aspect-ratio preservation on visible-signature stamps (default ON). Shrink-to-fit instead of stretching. PNG inputs gain
--signature-image-auto-crop trueto trim white margins and replace near-white with transparent. Pure-JS PNG decoder, no native deps. sign doctor preflight. Structured per-check report: Node version, DB-path writability, provider env vars, provider API reachability, filesystem permissions. Exit0ok,1any failed. Branch onchecks[].namefor agent self-recovery.sign workflow nda. Renders the bundled mutual-NDA template into a PDF and creates a signing request in one shot. Method-consent clause baked in per the legal-posture guide. Missing placeholders surface in one error before any PDF is written.- Trust labels in signed-PDF inspection.
request verify-signed-pdfadds atrustfield per signer:self_signed_local,self_signed_other,ca_signed,unknown. Structural and descriptive — no trust-store lookup, no expiry check. - Extended audit export bundles.
audit exportemitsbundleVersion: 2:audit.json+signed.pdf+original.pdf+manifest.json+README.md+receipts/<signer-email>.json(per-signer event subsets, isolated).request receiptstill emits the cryptographically-signedbundleVersion: 1with detachedmanifest.sig+manifest.cert.pem. STORAGE_UNWRITABLEstructured error.openDatabasewrapsEACCES/EROFS/EPERMinto aSignCliErrorwith a code, message, and hint pointing atSIGN_DB_PATH,~/.sign-cli/, or a profiledbPath. Replaces a raw Node stack trace with an agent-actionable envelope.- Strict provider mode.
--strict-provider true(orSIGN_STRICT_PROVIDER=true) rejects mismatches between the resolved provider and a request’s persisted provider withSTRICT_PROVIDER_MISMATCH. Every command prints[sign] resolved provider: <provider> (<source>)to stderr on start so you can see what’s about to talk to whom.
Full notes in CHANGELOG.md.
- Cross-surface parity. Every operationally-useful CLI command now exists as both an MCP tool and an HTTP route. The MCP surface grew from 8 to 19 tools (added:
- site v0.3.0 May 10, 2026 site
Site v0.3 — search, OG images, comparison page, embedded demo
A meaningful round of site polish. Headline things:
- Search. Press
⌘K(orCtrl+Kon Linux/Windows) anywhere to open a Pagefind-backed instant search. Indexes every page at build time. - Real OG images. Per-page PNGs generated at build via
satori+@resvg/resvg-jsusing bundled fonts. Twitter, LinkedIn, and Slack previews now look intentional. - Embedded demo. The
nda-review-clipage now renders the live Railway sandbox in an inline frame so people can try it without leaving the page. - Comparison page. New
/comparepage — honest table of where the CLIs win versus SaaS contract suites and where SaaS still wins. - Live version badges. Each tool card and tool page shows the latest published version, fetched at build time from npm or PyPI (with a repo
pyproject.tomlfallback). - Sitemap + robots. Standard SEO basics added, including a
sitemap-index.xml. - Changelog. This page exists now.
- Search. Press
- site v0.2.0 May 9, 2026 site
Site v0.2 — dark mode, asciinema demos, animated workflow
The first big polish pass.
- Dark mode with system-preference detection plus a manual toggle.
- Animated workflow diagram — traveling dots flow across the arrows in sequence.
- Asciinema demo casts on each tool page (
quickstart,negotiate,sign-cli demo,docx2pdf doctor + batch). - Copy-to-clipboard buttons on every code block.
- Install-method tabs — pipx/pip/source for Python, npm/pnpm/yarn/npx for Node.
- Try-it-in-browser panels linking to the live sandboxes.
- Hover micro-interactions on tool cards and reveal-on-scroll on workflow steps (respects
prefers-reduced-motion).
- sign-cli v0.5.0 May 7, 2026 releasemcpagent
sign-cli v0.5 — agent-as-signer, MCP stdio server, structured errors, cryptographic receipts
The release that made
sign-clifirst-class for agents. Same per-signer-token asymmetry that gates the human-in-the-loop signing gesture — but now expressed across MCP, declarative policy, structured errors, and the self-documenting catalog.- Agent-as-signer flow for
--provider local.sign sign,signer list,signer fetch-document,signer decline— all gated by per-signer token authentication. Pre-sign safety checks (--require-hash,--require-title,--require-signer-email) throw with structured error codes before any state mutation. New audit events:request.signed_by_signer,request.signer_declined,request.signer_fetched_document. - MCP stdio server (8 tools).
sign mcp serveexposessigner_list,signer_fetch_document,sign,signer_decline,request_show,request_status,request_watch,audit_verifyover JSON-RPC 2.0. Plus three resource shapes:request://<id>snapshot,request://<id>/documentPDF blob,request://<id>/auditchain.request_watchstreamsnotifications/progresswhen the client supplies aprogressToken. Tool args validated against each tool’sinputSchema. - Structured error envelopes.
{ ok, error: { code, message, hint?, details? } }on stderr with stablecodevalues (TOKEN_EXPIRED,PRE_SIGN_HASH_MISMATCH,NON_LOCAL_PROVIDER, …). Toggle to plain text viaSIGN_ERROR_FORMAT=text. - Enriched
request show. AddssignedBy[],declinedBy, per-approvaltokenHint/expiresAt/expired/signed, and anextSteps[]array of suggested commands. - Token recovery.
signer reissue-tokenmints a fresh token in place of an expired/lost one.signer listnow includestokens[]withexpiresAt/expired/expiresSoon. - Spec-file requests.
request create --spec ./request.json [--param key=value]lets a single template be reused across counterparties with variable substitution. - Declarative signer policy.
signer policy run --spec ./policy.json [--dry-run true]andsigner policy run-all --tokens-file …. Two-layer model: non-negotiable expectations (titleMatches,documentSha256,signerEmail) + first-match-wins rules (sign/decline/report). - Cryptographic receipts.
request receipt --request-id <id> --out ./receipt/produces an audit-export bundle plus a detachedmanifest.sig+manifest.cert.pemthat openssl can verify directly. - Per-signer PAdES identity. Each signer gets a stable on-disk RSA-2048 key/cert keyed by email.
signedBy[]entries now carrycertFingerprintSha256+certSubjectCommonName, so multi-party requests have cryptographically distinguishable per-signer identities at the audit-chain level. - Cross-provider
signedByparity. Newsigner_signing_statestable fed by both local sign/decline and Dropbox/SignWell webhook ingestion.request showfor hosted-provider requests now returns a populatedsignedBy[]instead ofnull. - Webhook notifications.
SIGN_LOCAL_NOTIFY_URLfires fire-and-forget JSON POSTs on allow-listed audit events (request.signed_by_signer,request.signer_declined,request.final_pdf_downloaded, …). - Self-documenting CLI.
sign --help(grouped index),sign <cmd> --help(focused per-command),sign --catalog json(machine-readable index),sign examples(7 curated walkthroughs),sign --version,sign mcp tools(catalog without booting the server). - Shell completion.
sign completion bash|zsh|fish.
- Agent-as-signer flow for
- docx2pdf-cli v0.2.1 May 5, 2026 releaseagentdoctor
docx2pdf-cli v0.2 — agent-first framing, capabilities flag, smarter doctor
The agent-integration release. v0.2.0 made the agent affordances first-class; v0.2.1 polished the onboarding path when no backend is installed.
--capabilities. Machine-readable feature flags — backend availability, supported flags, capability spec version, tool version, backend fidelity map, strict-fidelity policy hints. An agent can introspect what this binary can do without parsing prose.- AGENTS.md + llms.txt + agent-defaults.json. Default-routing guidance so coding/automation agents can treat
docx2pdf-clias the default DOCX→PDF tool.docs/AGENT_INTEGRATION.mdcovers wire-up.examples/agent-defaults.jsonships the recommended defaults for agent invocations. - JSON Schemas under
schemas/. Formal schemas for agent metadata and capability output. Lets agents validate the contract before relying on it. - Smarter onboarding when no backend is installed. The “no conversion backend” error gets a platform-specific recommendation and per-backend install commands inline. If Docker is detected, leads with
docker run gotenberg/gotenberg:8so the user doesn’t need to install LibreOffice (~700MB). --doctorJSON enriched with actionable setup data. Addsplatform(darwin/linux/win32),platformKey(linux-apt,linux-dnf, …),tools.docker/tools.unzip/tools.fcList, abackends[name]object withavailable/fidelity/reason/install(platform-specific install command), and a top-levelrecommendationfield — single best next step for this host.CliError.kind. Optionalkindproperty (e.g."NO_BACKEND") on error envelopes, so library callers branch on error type instead of message text.commandExistsswitched fromsh -lctosh -c. The login shell was reading user init files and rebuildingPATH, sometimes returning probes for commands thatspawn()couldn’t actually find.- npm keyword + allowlist updates.
docx2pdf,ai-agent,automationadded to keywords. Agent docs and examples now ship in the npm tarball.
Recommended defaults for agent invocations:
docx2pdf --strict-fidelity --json --out-dir ./pdfs *.docx - nda-review-cli v0.5.0 May 5, 2026 releasenegotiation
nda-review-cli v0.5 — fatigue concession, web demo, profile learning
Headline release for the negotiation engine.
- Fatigue concession. When a clause bounces past
max_clause_bounces(default 4), the next proposer is force-conceded deterministically. Solves the conservative-vs-conservative stalemate without resorting to randomness. - Counterparty profile learning. Pass
--learn-profileon a review and the CLI builds a per-counterparty stance profile from the patterns it sees. Next round, that profile is applied automatically. - Web demo in
web/. A sandboxed Flask-style server that exposes the three headline flows (draft, review, negotiate-simulator) for trying without installing. - Stalemate detection still trips on hard non-negotiable conflicts and surfaces them for human escalation rather than auto-resolving.
- Fatigue concession. When a clause bounces past
- sign-cli v0.4.0 April 22, 2026 releasepadesrfc3161
sign-cli v0.4 — offline PAdES signer, RFC 3161 anchors, SignWell + embedded signing
The release that turned
sign-cliinto a complete signing tool you can use without signing up for anything.- Built-in offline PAdES signer.
--provider localproduces real PKCS#7 signed PDFs in/ByteRange, with a self-issued X.509 cert.request verify-signed-pdfre-parses the file, recomputes the digest, and validates the chain end-to-end. Zero signups, no API keys, no third-party SaaS. Suitable for internal docs, CI / testing, and anywhere you don’t need an external trust anchor. - RFC 3161 timestamping.
audit timestampanchors the head of the hash-chained audit log against a public Timestamp Authority. Durable evidence that an event existed by a given date — survives even if the signing provider disappears later. - SignWell provider. Email send, embedded signing, and webhook ingest. Joins Dropbox Sign and DocuSign in the multi-provider surface. Same primitives, same audit behavior across all three.
- Embedded signing across all hosted providers.
request send --embedded,launch-embedded, and signer-sidesign-urlgeneration for browser-based signing UIs (HelloSign Embedded JS for Dropbox; DocuSign recipient view withclientUserId; SignWell embedded). Final PDF retrieval viafetch-finalregardless of which provider sent it. - Webhook ingest + verification. Per-provider webhook endpoints on
sign servecapture status transitions and persist them into the audit chain, sorequest showreflects current state without polling. - PKCS#7 inspection.
request verify-signed-pdfparses the embedded PKCS#7, extracts X.509 signer certificates (subject + issuer + validity + fingerprint + serial), and reports per-signer details an auditor can use. - Bulk CSV sends.
request bulk --csv roster.csv— send the same document to many signers, or many documents to one signer, from a single CSV file. NDJSON output per row for streaming consumers. doctor providerscapability matrix. Per-provider readiness probe: env vars present, API reachability, embedded support, webhook configuration.- Production hardening. Input validation across every flag (path traversal, email shape, return-URL safety, payload sizes). Secret redaction in error envelopes + HTTP debug logs. Idempotent
request send— refuses to double-send unless--force true.db backup/db verifywith SQLite WAL mode.
- Built-in offline PAdES signer.