| name | invoice |
| description | Use when the user wants to create, edit, style, or export an invoice PDF — opens a local split-pane editor (style/data controls + HTML/CSS escape hatch, live preview) and exports PDFs via headless Chromium. Claude fills invoice data by editing workspace JSON files. |
Invoice skill
Create, edit, and export styled invoice PDFs through a split-pane browser editor. Claude drives the workflow by writing workspace JSON files; the editor hot-reloads the preview. Headless PDF export runs without opening a browser.
1. Setup
Install dependencies and the Chromium browser used for PDF export:
npm install
npx playwright install chromium
Scaffold the workspace directory (creates sample profile, invoice, and template):
tsx skills/invoice/scripts/launch.ts
This prints:
Workspace ready at ./workspace.
Run "npm run editor" and open http://localhost:4317 to edit and preview.
Export headlessly with: npm run export -- <invoice-name>
To use a custom workspace path, set INVOICE_WORKSPACE:
INVOICE_WORKSPACE=/path/to/ws tsx skills/invoice/scripts/launch.ts
2. Launch the editor
npm run editor
Open http://localhost:4317 in a browser. The UI has two panes:
- Left — tabbed controls: Data (invoice fields), Style (colours, fonts, page size), Code (raw HTML/CSS template editor).
- Right — live preview that hot-reloads whenever workspace files change.
Clicking Export PDF in the editor exports the current invoice and saves it to workspace/output/<invoice-name>.pdf.
3. Workspace file contract
workspace/
profiles/
<name>.json # sender profile (company, address, logo)
invoices/
<name>.json # invoice data (client, items, dates)
templates/
<name>/
template.html # Handlebars HTML template
template.css # template stylesheet
style.json # style variables (colours, fonts, page size)
output/
<name>.pdf # generated PDFs (written by export)
The classic template is seeded by scaffoldWorkspace. Add more templates by creating additional subdirectories under templates/.
4. JSON schemas
All files are validated against these schemas at load time. Unknown fields are ignored; all fields listed here are required unless marked optional.
workspace/invoices/<name>.json — InvoiceSchema
| Field | Type | Notes |
|---|
profile | string | Name of the profile file (without .json) |
template | string | Name of the template directory |
number | string | Invoice number, e.g. "INV-001" |
client | object | See sub-fields below |
client.name | string | Client company or person name |
client.address | string | Client postal address |
client.email | string | Client email address |
items | array | Line items — see LineItemSchema below |
items[].description | string | Description of the service or product |
items[].quantity | number | Non-negative quantity |
items[].rate | number | Non-negative unit price |
issueDate | string | ISO date string, e.g. "2026-06-29" |
dueDate | string | ISO date string |
notes | string | Free-text footer notes (can be empty) |
taxRate | number | Tax rate as a decimal fraction, non-negative (e.g. 0.2 for 20%) |
workspace/profiles/<name>.json — ProfileSchema
| Field | Type | Notes |
|---|
name | string | Sender name or company |
address | string | Sender postal address |
email | string | Sender email address |
logoPath | string | (optional) Path to logo image file |
taxId | string | (optional) VAT / tax registration number |
currency | string | ISO 4217 currency code, e.g. "EUR" or "USD" |
workspace/templates/<name>/style.json — StyleSchema
| Field | Type | Notes |
|---|
accentColor | string | CSS colour value, e.g. "#2563eb" |
fontFamily | string | CSS font-family string |
fontSize | number | Base font size in px (positive) |
pageSize | "A4" | "Letter" | PDF page size |
margin | number | Page margin in px (non-negative) |
logoPosition | "left" | "right" | "center" | Logo alignment in header |
5. Filling invoice data as Claude
When the user asks to create or update an invoice (e.g. "invoice Beta Corp for 10 h design at €90"):
- Choose an existing profile from
workspace/profiles/ (or create one if none exists).
- Choose a template from
workspace/templates/ (default: classic).
- Write or update
workspace/invoices/<name>.json following InvoiceSchema exactly.
Example invoice file workspace/invoices/beta-design.json:
{
"profile": "acme",
"template": "classic",
"number": "INV-001",
"client": {
"name": "Beta Corp",
"address": "123 Client St, London",
"email": "accounts@beta.example"
},
"items": [
{ "description": "Design work", "quantity": 10, "rate": 90 }
],
"issueDate": "2026-06-29",
"dueDate": "2026-07-29",
"notes": "",
"taxRate": 0
}
If the editor is running at http://localhost:4317, it hot-reloads the preview automatically when the file is saved. Tell the user to refresh the browser tab if the preview does not update immediately.
To create a new sender profile, write workspace/profiles/<name>.json following ProfileSchema.
6. Export to PDF
Export headlessly without opening a browser:
npm run export -- <invoice-name>
For example:
npm run export -- beta-design
The command prints the output path when done, e.g.:
Exported workspace/output/beta-design.pdf
The PDF is saved to workspace/output/<invoice-name>.pdf.