{"id":49907778,"url":"https://github.com/drbaher/docx2pdf-cli","last_synced_at":"2026-05-31T21:00:42.262Z","repository":{"id":355681000,"uuid":"1229112410","full_name":"DrBaher/docx2pdf-cli","owner":"DrBaher","description":"Agent-first DOCX → PDF CLI. Six hybrid backends, strict-fidelity guard, machine-readable --capabilities + --doctor JSON. Part of the eight-CLI contract-ops suite — cli.drbaher.com","archived":false,"fork":false,"pushed_at":"2026-05-31T17:45:55.000Z","size":251,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-31T19:12:06.320Z","etag":null,"topics":["agent-first","ai-agent","automation","cli","contract-automation","contract-ops","document-conversion","docx","docx-to-pdf","gotenberg","legal-tech","libreoffice","llm","local-first","mcp","nodejs","pdf","pdf-converter"],"latest_commit_sha":null,"homepage":"https://cli.drbaher.com/tools/docx2pdf-cli/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DrBaher.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-04T17:59:31.000Z","updated_at":"2026-05-31T17:45:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DrBaher/docx2pdf-cli","commit_stats":null,"previous_names":["drbaher/docx2pdf-cli"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/DrBaher/docx2pdf-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrBaher%2Fdocx2pdf-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrBaher%2Fdocx2pdf-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrBaher%2Fdocx2pdf-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrBaher%2Fdocx2pdf-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DrBaher","download_url":"https://codeload.github.com/DrBaher/docx2pdf-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrBaher%2Fdocx2pdf-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33748607,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-first","ai-agent","automation","cli","contract-automation","contract-ops","document-conversion","docx","docx-to-pdf","gotenberg","legal-tech","libreoffice","llm","local-first","mcp","nodejs","pdf","pdf-converter"],"created_at":"2026-05-16T11:12:32.174Z","updated_at":"2026-05-31T21:00:42.256Z","avatar_url":"https://github.com/DrBaher.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/icon.svg\" width=\"120\" alt=\"docx2pdf-cli\"\u003e\n\u003c/p\u003e\n\n# docx2pdf-cli\n\n\u003e Part of the contract-ops CLI suite. [**draft-cli**](https://github.com/DrBaher/draft-cli) (fill placeholders) → [**nda-review-cli**](https://github.com/DrBaher/nda-review-cli) (review, redline, negotiate) → **docx2pdf-cli** (DOCX → PDF) → [**sign-cli**](https://github.com/DrBaher/sign-cli) (signing + audit). Storage layer: [**template-vault-cli**](https://github.com/DrBaher/template-vault-cli). Drift detection: [**compare-cli**](https://github.com/DrBaher/compare-cli). [Showcase site](https://cli.drbaher.com/).\n\n[![npm version](https://img.shields.io/npm/v/docx2pdf-cli.svg)](https://www.npmjs.com/package/docx2pdf-cli)\n[![npm downloads](https://img.shields.io/npm/dw/docx2pdf-cli.svg)](https://www.npmjs.com/package/docx2pdf-cli)\n[![CI](https://github.com/DrBaher/docx2pdf-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/DrBaher/docx2pdf-cli/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\nHonest, batch-aware DOCX → PDF converter with hybrid backends. Strict-fidelity guarantees, machine-readable JSON output, and a `--doctor` probe so an agent can self-check what backends are usable before invoking. Six pluggable backends covering Linux, macOS, Windows, and Docker.\n\n## Run this\n\n```bash\ndocx2pdf --doctor\n```\n\nTells you which backends are usable on this machine and prints a `recommendation` field — the single best next step (Docker-Gotenberg in ~30 seconds if Docker is available, otherwise LibreOffice). Once at least one backend is available:\n\n```bash\ndocx2pdf contract.docx contract.pdf\n```\n\n## Where to go next\n\n| If you are… | Start here |\n|---|---|\n| **A new user** evaluating the tool | [Quick start](#quick-start) below, then [Diagnostics](#diagnostics) |\n| **An operator** setting up a backend | [docs/setup/](docs/setup/) — LibreOffice / Gotenberg / ConvertAPI / Pages / Word |\n| **An LLM agent** driving the CLI | [AGENTS.md](AGENTS.md) → [`docx2pdf --capabilities`](#capability-discovery) → [docs/reference/](docs/reference/) |\n| **A contributor** | [docs/reference/](docs/reference/) (concept docs), the npm package, the CI workflows |\n| **Adding a new CLI to the suite** | The [build-a-CLI playbook](https://cli.drbaher.com/build-a-cli) — the conventions every suite CLI follows |\n\nConcept deep-dives live in [docs/reference/](docs/reference/); per-backend setup in [docs/setup/](docs/setup/).\n\n## Install\n\n```bash\nnpm i -g docx2pdf-cli\ndocx2pdf --doctor\n```\n\nYou'll also need at least one backend runtime. Easiest path: LibreOffice via `brew install --cask libreoffice` (macOS) or `apt install libreoffice` (Debian/Ubuntu). Or run Gotenberg in Docker for zero system mutation. The `--doctor` JSON's `recommendation` field picks the right one for your host.\n\nFrom a clone:\n\n```bash\ngit clone https://github.com/DrBaher/docx2pdf-cli.git\ncd docx2pdf-cli \u0026\u0026 ./install.sh\n```\n\n## Quick start\n\n### Single file\n\n```bash\ndocx2pdf contract.docx contract.pdf\n```\n\n### Batch mode (parallel, NDJSON output)\n\n```bash\ndocx2pdf --concurrency 4 --json --out-dir ./pdfs ./drafts/*.docx\n```\n\nOne bad file doesn't stop the rest. With `--json`, each file emits one NDJSON line plus a final summary. Exit code `0` only if every file succeeded.\n\n### Strict fidelity (refuse silent text-only fallback)\n\n```bash\ndocx2pdf --strict-fidelity contract.docx contract.pdf\n```\n\n### Pin a specific backend\n\n```bash\ndocx2pdf --backend gotenberg contract.docx contract.pdf\ndocx2pdf --backend word contract.docx contract.pdf        # macOS only\n```\n\n### Network retries\n\n```bash\ndocx2pdf --backend gotenberg --retries 3 contract.docx contract.pdf\n```\n\nNon-busy backoff via `Atomics.wait`. Advertised via `supports.retries` in `--capabilities`.\n\n### Font preflight\n\n```bash\ndocx2pdf --check-fonts contract.docx\n```\n\nWarns when fonts referenced by the document aren't installed, so you find out before LibreOffice silently substitutes them.\n\n## Backends\n\nSix backends, auto-selected in this order:\n\n| Backend | Fidelity | Requires |\n|---|---|---|\n| `libreoffice` | high (local) | `soffice` or `lowriter` |\n| `gotenberg` | high (server) | `GOTENBERG_URL` + `curl` |\n| `convertapi` | high (cloud) | `CONVERTAPI_SECRET` + `curl` |\n| `pages` | high (macOS) | Apple Pages + Automation permission |\n| `word` | high (macOS) | Microsoft Word + Automation permission |\n| `textutil-cups` | text-only | `textutil` + `cupsfilter` |\n\n`--strict-fidelity` refuses the text-only fallback. Per-backend setup in [docs/setup/](docs/setup/); decision guidance in [docs/reference/backends.md](docs/reference/backends.md).\n\n## Diagnostics\n\n```bash\ndocx2pdf --doctor                  # full host-readiness JSON; locked by schemas/doctor.schema.json\ndocx2pdf --list-backends           # which backends are usable, in auto-selection order\ndocx2pdf --capabilities            # machine-readable feature contract; locked by schemas/capabilities.schema.json\ndocx2pdf --why input.docx          # print backend selection reasoning, then convert\ndocx2pdf --check-fonts input.docx  # report missing fonts (needs unzip + fc-list)\n```\n\n`--check-fonts` requires `unzip` and `fc-list`. On macOS: `brew install fontconfig`.\n\n## For LLM agents\n\nAgent affordances are first-class. The full contract is in [AGENTS.md](AGENTS.md); the schemas are in [`schemas/`](schemas/).\n\n### Capability discovery\n\n```bash\ndocx2pdf --capabilities\n```\n\nReturns a stable machine-readable contract (locked by [`schemas/capabilities.schema.json`](schemas/capabilities.schema.json)) — `capabilitySpecVersion`, tool version, backend fidelity map, supported flags, exit-code semantics, retry support. Validate against the schema rather than parsing prose.\n\n### Recommended defaults\n\n```bash\ndocx2pdf --strict-fidelity --json --out-dir ./pdfs *.docx\n```\n\nCanonical defaults manifest: [`examples/agent-defaults.json`](examples/agent-defaults.json).\n\n### Fallback policy\n\nDon't silently remove `--strict-fidelity` after a backend error — that can produce a text-only PDF and lose layout. Run `--doctor`, read the `recommendation` field, surface its `command` to the user with consent, then retry. Full failure → recovery table in [AGENTS.md](AGENTS.md#failure--recovery).\n\n## How it compares\n\n|                                 | docx2pdf-cli       | [libreoffice-convert](https://www.npmjs.com/package/libreoffice-convert) | [AlJohri/docx2pdf](https://github.com/AlJohri/docx2pdf) | [Gotenberg](https://gotenberg.dev) | [dxpdf](https://lib.rs/crates/dxpdf) |\n|---------------------------------|--------------------|--------------------------------------------------------------------------|--------------------------------------------------------|------------------------------------|--------------------------------------|\n| Backend approach                | hybrid (6)         | LibreOffice                                                              | MS Word automation                                     | LibreOffice (server)               | native Skia renderer                 |\n| Concurrency-safe LO             | ✅ per-call profile | ❌ shared profile collision                                              | n/a                                                    | ✅                                  | n/a                                  |\n| Batch CLI + NDJSON              | ✅                  | ❌ (library API only)                                                    | ❌                                                      | n/a (HTTP server)                  | ❌                                    |\n| Backend transparency (`--why`)  | ✅                  | ❌                                                                        | ❌                                                      | ❌                                  | ❌                                    |\n| Font preflight                  | ✅                  | ❌                                                                        | ❌                                                      | ❌                                  | ❌                                    |\n| Linux + macOS + Windows         | ✅                  | ✅                                                                        | macOS + Windows only                                   | ✅ (Docker)                         | ✅                                    |\n| Install                         | `npm i -g`         | `npm i`                                                                  | `pip install`                                          | Docker                             | `cargo install` / `pip`              |\n\nHonest notes: `libreoffice-convert` is a leaner Node *library API* (we're a CLI). Gotenberg also handles HTML→PDF and scales as a server. `dxpdf` ships a custom renderer that avoids LibreOffice entirely (~100ms per doc) but is still feature-incomplete.\n\n## All flags\n\n```\n--backend \u003cauto|libreoffice|gotenberg|convertapi|pages|word|textutil-cups\u003e\n--strict-fidelity         refuse to fall back to text-only backend\n--out-dir \u003cdir\u003e           write outputs to \u003cdir\u003e/\u003cbasename\u003e.pdf (enables batch mode)\n--concurrency \u003cn\u003e         run up to N conversions in parallel in batch mode (default: 1)\n--retries \u003cn\u003e             retry failed network backends n times (default: 0)\n--timeout-seconds \u003cn\u003e     conversion timeout (default: 120)\n--overwrite, --force      replace existing output file\n--quiet, -q               suppress success output\n--json                    emit machine-readable JSON (NDJSON in batch mode)\n--why                     print backend selection reasoning to stderr\n--check-fonts             report which fonts in the .docx are missing\n--list-backends           show available backends and exit\n--doctor                  print full diagnostics as JSON and exit\n--capabilities            print machine-readable feature contract and exit\n-h, --help\n-v, --version\n```\n\n## Exit codes\n\n| Code | Meaning |\n|---|---|\n| `0` | Success |\n| `2` | Invalid input (missing arg, bad flag) |\n| `3` | No acceptable backend available (`error.kind: \"NO_BACKEND\"`) |\n| `4` | Conversion failed |\n\nFull envelope and stable error `kind` table in [docs/reference/exit-codes.md](docs/reference/exit-codes.md).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## See also\n\n- [AGENTS.md](AGENTS.md) — the agent quickstart (output contract, exit codes, discovery, failure recovery).\n- [docs/setup/](docs/setup/) — per-backend install + configuration.\n- [docs/reference/](docs/reference/) — backends, doctor JSON shape, exit codes, JSON/NDJSON output.\n- [llms.txt](llms.txt) — compressed agent briefing.\n- [schemas/](schemas/) — formal contracts for `--capabilities` and `--doctor` output.\n- [examples/agent-defaults.json](examples/agent-defaults.json) — recommended defaults manifest.\n- [CHANGELOG.md](CHANGELOG.md) — what landed and when.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrbaher%2Fdocx2pdf-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrbaher%2Fdocx2pdf-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrbaher%2Fdocx2pdf-cli/lists"}