Skip to content
ttyinv

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

invoice.mdttyinv/v2 · one contract · one engine
ttyinv renderone Rust renderer · html · pdf · png

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.

Data boundary by surface
SURFACEWHERE THE DOCUMENT LIVESWHAT LEAVES YOUR MACHINE
browser editorin this browser, while the tab is opennothing, until you export or send the file yourself
clion your disknothing; the binary makes no network call
webmcpin the open pagenothing; the agent presses the buttons you press
rest + mcpin the request your agent sendsthe document you post; processed transiently, not stored

Open source, and specific about what ships.

SHIPPED

  • Browser editor: create, inspect, edit, validate, convert, render
  • ttyinv CLI: 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.

Start with an empty invoice, or paste Markdown you already have.