# brewdoc

> Fast, deterministic document-to-Markdown conversion for agent systems. Easy to install. No model weights, OCR or external services.

Local conversion after installation is offline and downloads no runtime components.
Supported formats and readable-file constraints are defined in FORMATS.md.
Version 0.4.1 adds [selected ZIP/XML reader budgets](https://github.com/kochetkov-ma/brewdoc/blob/v0.4.1/FORMATS.md#zipxml-reader-limits)
for DOCX/PPTX and workbook metadata/artifacts, with refusal before output writes.
Native workbook values and total process memory are outside those bounds.

- [Installation](https://github.com/kochetkov-ma/brewdoc/blob/v0.4.1/INSTALL.md): pip, uv/uvx, pipx, native downloads, PATH, update and removal.
- [CLI/API and receipts](https://github.com/kochetkov-ma/brewdoc/blob/v0.4.1/README.md): deterministic Markdown and machine-readable results, including article mode introduced in 0.4.0.
- [Format limits](https://github.com/kochetkov-ma/brewdoc/blob/v0.4.1/FORMATS.md): supported/refused inputs, omissions, resource budgets and package compatibility evidence.
- [Latest release](https://github.com/kochetkov-ma/brewdoc/releases/latest): concise features, actual assets and channel availability.
- Installation examples select 0.4.1; use a channel listed as available in [that release](https://github.com/kochetkov-ma/brewdoc/releases/tag/v0.4.1). npm targets Linux x64/glibc and macOS ARM64; Windows uses GitHub native or Python.

## CLI and API

```sh
brewdoc file.pdf --out file.md
brewdoc book.xlsx --sheet Calc --sheet Inputs --out book.md
brewdoc --self-check
```

Conversion prints a JSON receipt first; without --out, Markdown follows on stdout.
Paths resolve against the caller's directory; --out creates parents. --sheet and
--artifact are repeatable and workbook-only. Markdown is brewdoc.markdown/2;
local receipts are brewdoc.receipt/1, URL receipts brewdoc.receipt/2.
Exit 0 means conversion, 1 refusal and 2 invalid usage. Success does not prove fidelity.

```python
import brewdoc
code, receipt, markdown = brewdoc.run("book.epub", out="book.md")
markdown, tally = brewdoc.render_html("page.html")
```

Local run/render APIs and self-check never acquire URLs.

## Deliberate HTTP acquisition

```sh
brewdoc --url https://example.com --render-js --timeout 30 --out page.md
```

--url deliberately fetches a public HTTP(S) page. DNS, destinations, redirects,
TLS, requests and byte budgets are validated. The default waiting budget is 30
seconds. JS uses installed/bundled components and may preserve valid partial
content on timing-only expiry; hard failures refuse. Ordinary requests use GET;
only the narrow credential-free HN Algolia XHR POST exception is admitted.
See the format limits for supported JS runtimes and prerequisite refusals.

## Article mode

Introduced in 0.4.0; use a channel listed as available in the release. Python JS capture
needs `brewdoc[render-js]==0.4.1`; supported standalone bundles include its prerequisites.

```sh
brewdoc page.html --article --out article.md
brewdoc --url https://example.com/article --article --out article.md
brewdoc --url https://example.com/article --render-js --article --out article.md
```

Python: `run(path, article=True)` or `render_html(path, article=True)`. Local APIs stay offline.
Only literal main/article elements select roots; role=main/article and class names do not.
Existing role=button controls exclude candidates and fallback prose. Hidden ancestors and navigation/form contexts
exclude candidates; peer articles and multiple mains refuse. Main fallback needs one nonempty
h1, prose outside navigation/tables/controls and no visible form. Empty output refuses; an
explicit image/table-only article is valid. Nested articles stay inside their outer article.
No text scoring, full-page fallback, title replacement or inferred author/date metadata.
Use single articles or marked documentation. Peer-article feeds refuse. Visible forms
disqualify main fallback; forms inside an eligible explicit article remain rendered content.
Receipt `not_carried` and successful Markdown Known omissions include
`body content outside the selected article or main subtree; complete page coverage is not claimed`.
See [the article contract](https://github.com/kochetkov-ma/brewdoc/blob/v0.4.1/FORMATS.md#article-selection).

[Source-package CI](https://github.com/kochetkov-ma/brewdoc/actions/runs/38431645006) passed on
Ubuntu 22.04 x64/glibc with CPython 3.13.15, macOS 15 ARM64 and Windows Server 2025 x64
with CPython 3.14.7. Each passed four independent wheel/sdist base/optional installs;
optional JS executed on Unix and refused before requests on Windows. These are selected
tested patches. CPython 3.12.14 retains local macOS full-suite and existing CI smoke evidence.
Source-package checks are separate from standalone binaries; other OS/minor combinations,
free-threaded CPython and other architectures remain untested here.
See [package compatibility](https://github.com/kochetkov-ma/brewdoc/blob/v0.4.1/FORMATS.md#python-package-compatibility).

## Related projects

- [BrewPage](https://brewpage.app): free hosting for HTML, Markdown, JSON and files; each upload returns a shareable HTTPS link.
- [BrewPage MCP server](https://github.com/kochetkov-ma/brewpage-openapi/tree/main/mcp-server): npm package brewpage-mcp for publishing to BrewPage from MCP clients.
- [claude-brewcode](https://github.com/kochetkov-ma/claude-brewcode): plugin suite for Claude Code. Its brewdoc plugin is a different tool from this brewdoc CLI.
- [claude-brewcode documentation](https://doc-claude.brewcode.app): installation and skill reference for that suite.
- [brewcode.app](https://brewcode.app): home site of the Brew projects.

This is a readable entry point, without a promise of automatic client discovery.
