invoice.
An invoice is one Markdown file you own. Write it in the browser, drive it from the terminal, or let an agent edit it — every surface runs the same ttyinv/v2 contract.
AGPL-3.0your draft stays in your browserno account to try it
Four entry points. One file. One document.
Every path below writes the same invoice.md, checked by the same Rust engine against the same generated command contract.
cli
Open-source Rust binary. Offline, scriptable, non-zero exit on a bad document.
$ ttyinv validate invoice.md $ echo $? 0 $ ttyinv edit set-gap \ invoice.md --section 2 \ --gap roomy
writes invoice.md in place
webmcp
Generated browser commands over the open editor. Every call shows up in the page, and undo reverses edits.
set_invoice_value { "path": "metadata.number", "value": "INV-0043" }
changes the open document
api
REST and MCP for an agent with no browser. Bearer token, nothing stored.
POST /api/v1/invoices Authorization: Bearer $TTYINV_AGENT_TOKEN 200 { source, document, summary, warnings }
returns canonical invoice.md
markdown
Your editor, your repository. Diff it, review it, keep it for years.
--- schema: ttyinv/v2 format: code-comma-dot --- # Interface design sprint
is invoice.md
| Description | Days | Rate | Amount (EUR) |
|---|---|---|---|
| Product strategy | 1 | 1,200.00 | 1,200.00 |
| UI design | 3 | 800.00 | 2,400.00 |
| TOTAL DUE | EUR 3,600.00 | ||
invoice.pdf — made by the shared rendererThe same Rust renderer runs in your browser, in the CLI, and behind the API, so one document and one set of options give one file. Nothing is uploaded when you export from the editor.
Where your invoice actually is.
One row per surface. No qualifiers.
| SURFACE | WHERE THE DOCUMENT LIVES | WHAT LEAVES YOUR MACHINE |
|---|---|---|
| browser editor | in this browser, while the tab is open | nothing, until you export or send the file yourself |
| cli | on your disk | nothing; the binary makes no network call |
| webmcp | in the open page | nothing; the agent presses the buttons you press |
| rest + mcp | in the request your agent sends | the document you post; processed transiently, not stored |
Open source, and specific about what ships.
SHIPPED
- Browser editor: create, inspect, edit, validate, convert, render
ttyinvCLI: create, validate, inspect, convert, edit, prepare, render, registry- REST: create, inspect, convert, edit, validate, render
- MCP and WebMCP: the generated command registry across every supported adapter
- One Rust renderer: HTML, PDF, PNG
NOT SHIPPED
- No tagged release; the commit history is the record
- No stored invoice, no customer record, no exchange-rate lookup
Every line on the left is in the public repository and runs from a clean checkout. Nothing here claims a version, because there is no tagged release yet.