Skip to content

Releases: erikvankempen/bukio-cli

v0.17.0 — Cost Centers

Choose a tag to compare

@erikvankempen erikvankempen released this 01 Sep 20:29

[0.17.0] — 2026-09-01

Added

  • Cost centers — an optional analytical dimension for management reporting.
    Define cost centers (bukio cost-center add/list/show/deactivate/reactivate),
    tag expense/revenue postings at booking time (4700:-100.00@SALES), and run
    bukio report cost-center to see revenue, costs and result per center for any
    period (year, quarter, month, or date range). Cost centers are purely analytical
    — they never block a posting and are invisible to statutory reporting.
    Schema migration 026; nullable cost_center_id on postings; entry-level @CC
    suffix in posting specs; cost center carried through reversals; period filtering
    via --period YYYY-Qn|YYYY-MM, --from/--to, --year; single-center drill-down
    with --cost-center CODE.
  • Authz gate for cost centerscost-center add/deactivate/reactivate mapped
    to admin.chart (owner + bookkeeper); cost-center list/show and
    report cost-center mapped to report.read. Cost-center commands now
    participate in the Tier 0.5 RBAC system like every other command.
  • Flexible period filtering on cost-center reports--period 2026-Q2 or
    --period 2026-08 (quarter/month), --from/--to (arbitrary date range),
    --year (full fiscal year).

Changed

  • Code cleanup — ponytail audit cut deprecated CLI aliases, empty PLANNED
    sections, and duplicated CSV parsers.
  • README/AGENTS.md — cost-center commands added to command quick reference;
    posting spec documentation updated with @CC suffix; token usage snapshot
    refreshed ($22.05 total, 149 sessions, 37.25 KLOC).

Internal

  • Migration 026: cost_centers table + nullable cost_center_id column on
    postings with index.
  • 12 new cost-center tests; 941/944 tests passing (3 pre-existing).

v0.16.3 — Code-simplification pass

Choose a tag to compare

@erikvankempen erikvankempen released this 21 Aug 18:06

v0.16.3 — Code-simplification pass

Pure refactoring release: net −851 lines of source (+2,200/−3,051 across 191 files) with zero capability changes. The full CLI surface, MCP schemas, document outputs, and error-code contract are unchanged. Suite: 946/946 green. Two consecutive independent review passes, both clean.

Changed

  • New shared core modules: src/core/dates.js (date validation, today, month math) and src/core/errors.js (makeError) replace per-module copies across ~15 modules
  • CLI: command registry loop; withDb action-shell wrapper (67 handlers converted); cliError typed-error factory (46 throw sites); stale program description fixed
  • Compliance: quarterDeadlineOnOffset collapses nine quarterly deadline rules to one-liners; FYE deadline helpers delegate to monthsAfterFyEnd; byte-identical isBooksClosed clone removed
  • Invoice: NL/EU/LU party-field validators share one validateVereistenCore with per-locale config; UBL VAT-category logic unified in exported vatCategory(code); invoice create single engine call for dry-run and real paths (JSON shapes unchanged)
  • Reports: duplicated date-validation and todayIso copies replaced by the core dates module
  • i18n: parity-guard FULL list derived from the table registry; UNITS built from UNIT_CODES
  • Housekeeping: ~180 stale license-header jurisdiction counts corrected to thirty-one; XK profile shape anomalies fixed; dead code deleted

Full changelog: https://github.com/erikvankempen/bukio-cli/blob/main/CHANGELOG.md

v0.16.2 — 31 markets, 28 i18n tables

Choose a tag to compare

@erikvankempen erikvankempen released this 16 Aug 18:41

Added

  • **Phase E: BG Bulgaria + HR Croatia + SI Slovenia + EE Estonia + LV Latvia

    • LT Lithuania + MT Malta + CY Cyprus** — eight more EUR-market profiles
      (twenty-four live): research briefs at
      docs-research/{bg,hr,si,ee,lv,lt,mt,cy}-profile.md (EAS codes verified
      against the official OpenPEPPOL codelist release 8 Dec 2025 — BG 9926,
      HR 9934, SI 9949, EE 9931, LV 9939, LT 9937, MT 9943, CY 9928);
      monthly VAT returns (BG 14th, HR/SI/EE/LV 20th, LT 25th; MT/CY
      quarterly 15th/10th of the second month), annual-accounts + CIT
      deadlines per market (BG 30 Jun, HR 30 Apr, SI 31 Aug/31 Mar, EE 30 Jun
      (CIT on distributions), LV 31 Jul (CIT on distributions), LT 30 Apr/1
      Oct, MT 10/9 months, CY 10 months/31 Jan+2y). New markets keep
      English-document defaults (no i18n tables yet — same treatment as
      GB/IE/US) and inherit the art. 226 EU baseline + cross-border Peppol
      BIS; domestic e-invoicing mandates (e-Sąskaita LT, PVN LV 2025
      framework) and return layouts stay documented B-milestones.
  • **Phase F: CZ Czechia + SK Slovakia + GR Greece + PL Poland + HU Hungary

    • RO Romania** — the final six EU members (thirty live markets; 27/27 EU
    • GB/NO/US): research briefs at
      docs-research/{cz,sk,gr,pl,hu,ro}-profile.md (EAS codes verified
      against the official OpenPEPPOL codelist release 8 Dec 2025 — CZ 9929,
      SK 9950, GR 9933, PL 9945, HU 9910, RO 9947); monthly VAT returns
      (CZ/SK/PL/RO 25th, GR 26th, HU 20th), annual-accounts + CIT deadlines
      per market (CZ 6mo/31 Mar, SK 6mo/31 Mar, GR 10mo/30 Jun, PL 6mo/31
      Mar, HU 31 May/31 May, RO ~150d/25 Jun); CZK/PLN/HUF/RON base
      currencies via per-profile baseCurrency; GR uses the EL VIES prefix;
      RO is the only non-Peppol market (e-Factura national, cross-border UBL
      only); domestic mandates (KSeF PL — live 2026, RTIR HU, myDATA GR,
      e-Factura RO, SK 2027) stay documented B-milestones. English-document
      defaults; art. 226 EU baseline + cross-border Peppol BIS inherited.
  • i18n refactor: per-language table modulessrc/i18n/index.js's
    single TABLES literal split into src/i18n/locales/<lang>.js (one
    module per language: en/nl/nl-be/de/fr/fr-lu/da/fi/nb/sv/it/es/pt);
    index.js keeps the machinery (t/label/unitLabel/resolveLocale,
    LABELS/UNITS backwards-compat exports) and re-assembles TABLES from
    imports. Public API unchanged; keys/values byte-identical; the parity
    guard still pins 89 keys across all 11 full tables. Behavior-neutral —
    944/944 green.

  • i18n: 14 national-language PDF tables — full 89-key tables for
    pl/cs/hu/ro/sk/sl/hr/bg/el/et/lv/lt/mt/cy under src/i18n/locales/
    (25 full tables + 2 regional overrides; parity guard extended). The
    Phase E/F profiles now render documents in their national language by
    default (PL pl, CZ cs, SK sk, GR el, HU hu, RO ro, BG bg,
    HR hr, SI sl, EE et, LV lv, LT lt, MT mt, CY cy) — the
    invoice PDF/email pipeline is fully localized for all 30 markets;
    --language accepts any of the 27 table codes. meta.locale aligned
    to ISO language codes (si->sl, ee->et, cz->cs, gr->el).

  • Phase G: Kosovo (XK) — 31st market. Non-EU EUR jurisdiction
    (unilateral euro adoption), SKRFI convention chart in Albanian, VAT
    18%/8% (monthly returns by the 20th), CIT + annual accounts by 31 March
    (10% flat CIT), Sh.p.k./Sh.a./O.P./K.P./B.I. legal forms, NBR
    (8-digit) + K-prefixed VAT identifiers. Not a Peppol participant —
    cross-border EN 16931 UBL emission only. Full Albanian (sq) i18n table
    (26 full + 2 regional overrides); documents render in Albanian by default.


Full changelog: CHANGELOG.md

v0.16.1

Choose a tag to compare

@erikvankempen erikvankempen released this 16 Aug 06:03

[0.16.1] — 2026-08-16

Added

  • Phase C: AT Austria + IE Ireland — two more jurisdiction profiles
    (thirteen live):
    • AT — Einheitskontenrahmen (EKR) chart (BMF SAF-T verified, 3-digit
      codes zero-padded), USt 20/13/10, Kleinunternehmer ≤ €55K, UID
      (ATU + 8 digits) / Peppol 9914, UVA quarterly (15th of the second
      following month; monthly above €100K) + annual USt-Erklärung 30 Jun.
    • IE — UK-style chart (no statutory chart), VAT 23/13.5/9/4.8/0,
      registration thresholds €85K goods / €42.5K services, CRO + IE-format
      VAT number / Peppol 9935, VAT3 bi-monthly returns (23rd of the month
      after the period; the YYYY-Pn shape) + annual accounts/CT1 in 9 months.
    • Research briefs at docs-research/{at,ie}-profile.md; strict dispatch
      keeps the B-milestones loud (UVA/VAT3 return engines, UGB/CA 2014
      accounts, SAF-T AT (OECD-style ≠ Auditfile), § 11 UStG / s. 108B VATCA
      invoice rule sets).
  • PLANNED now holds Phase D (IT, ES, PT) — init --country
    answers COUNTRY_NOT_SUPPORTED for them (CH remains parked).
  • Profile-aware init output — the vat: module enabled line shows the
    profile's clearing accounts (NL 1500/2500, AT 2500/3500, IE 2110/2100, …)
    instead of a hardcoded NL pair.
  • Clearer B-milestone errorsFORMAT_NOT_SUPPORTED now names the
    country and the milestone ("no invoice compliance rule set for AT yet…",
    "no VAT-return layout for IE yet…") instead of 'undefined'.
  • Phase D: IT Italy + ES Spain + PT Portugal — three more jurisdiction
    profiles (sixteen live):
    • IT — commercialisti convention chart (no statutory chart; standard
      Italian account names), IVA 22/10/5/4, regime forfettario ≤ €85K,
      Partita IVA (IT + 11 digits) / Peppol 0211, liquidazione IVA quarterly
      (16th of the second month after the quarter) + Dichiarazione IVA 30 Apr
      • bilancio ~5 months.
    • ES — official PGC chart (R.D. 1514/2007), IVA 21/10/4, recargo de
      equivalencia, NIF / Peppol 9920, Modelo 303 quarterly (20th; Q4 30 Jan)
      • 390 (30 Jan) + 200 (25 Jul) + cuentas anuales (7 months).
    • PT — official SNC chart (DL 158/2009; 2-digit bases zero-padded),
      IVA 23/13/6, isenção art. 53 CIVA, NIPC / Peppol 9946, Declaração
      Periódica quarterly (20th of the second month) + IRC (31 May) + IES
      (15 Jul).
    • Research briefs at docs-research/{it,es,pt}-profile.md; strict
      dispatch keeps the B-milestones loud (liquidazione/303/DP return
      engines, bilancio/cuentas/demonstrações financeiras, SAF-T PT,
      FatturaPA/SdI (IT), Verifactu (ES), ATCUD (PT) — domestic
      e-invoicing formats; Peppol BIS registered for cross-border).
  • Fully localised invoice PDFs — the rendered invoice is now localised
    in every market language. New full i18n tables it/es/pt (88 keys each,
    key-identical to the pivot — parity guard now covers 11 full tables);
    the document language follows the company profile (de-AT → de, it
    it, nl-be → nl, …) with --language accepting any i18n table;
    migration 025 rebuilds invoices to drop the stale CHECK (language IN ('nl','en')) that rejected de/it at INSERT.
  • EU invoice-compliance baseline — the harmonized art. 226 VAT Directive
    party requirements ('eu-invoice-vereisten') are registered for the twelve
    EU markets without a national rule set (AT/BE/DE/DK/ES/FI/FR/IE/IT/NO/PT/
    SE), so invoice finalization — and thus the localised PDF — works for
    every EU market; NL/LU keep their national rule sets; GB/US stay
    B-milestone (no EU baseline).

v0.16.0 — Eleven jurisdictions, localization, English-first sweep

Choose a tag to compare

@erikvankempen erikvankempen released this 15 Aug 19:58

[0.16.0] — 2026-08-15

Added

  • Eleven jurisdictionsbukio init --country <cc> now seeds the country
    profile's chart convention, VAT codes/rates (2026), identifiers, Peppol
    scheme and compliance calendar for NL, LU, GB, FR, US, BE, DE, DK, FI, NO
    and SE (Phase B; profiles at src/jurisdictions/, roadmap rows 14–15):
    • NL: 29-account RGS-mapped chart (unchanged baseline, byte-identical),
      KvK/btw-id, Peppol 9944.
    • LU: PCN 2020 chart, RCS, Peppol 0195; LU e-invoicing rules.
    • GB: QuickBooks/Xero-style chart, Companies House number, Peppol 0208,
      MTD-compatible stance, 03-31 fiscal year.
    • FR: PCG chart, SIREN, Peppol 0002, franchise small-business scheme.
    • US: no-federal-VAT tracking model (track + export).
    • BE: PCN-BE AR 12-09-1983 chart, KBO, Peppol 0208, BTW readout.
    • DE/DK/FI/NO/SE: SKR 03 / standard charts, USt-IdNr. / CVR / Y-tunnus /
      Org.nr., Peppol 9930 / 0184 / 0037 / 0192 / 0007, per-market VAT bands
      (incl. DK 25 % only, NO no-reduced band, DE 0 % solar, FI 25.5 %).
    • Strict dispatch: unregistered formats fail loudly (PROFILE_NOT_FOUND),
      never a silent NL fallback — NL is one of eleven equal citizens.
  • Localization (i18n) — optional, opt-in --locale <code> (global flag)
    or BUKIO_LOCALE env switches human-facing output; English stays the
    default
    and the JSON contract, error codes and MCP tool names never
    localize:
    • Locale tables for en, nl, nl-be, de, fr, fr-lu, da, fi, nb, sv
      (8 full tables × 88 keys, parity-guarded by tests; nl-be/fr-lu as
      regional overrides).
    • Wired: invoice PDF labels/units, invoice + reminder emails, CLI tables
      and renders (invoice list/reminders, balance sheet, P&L, month-end,
      year-end, company show), VAT file/settle descriptions. --desc still
      wins over localized defaults.
    • Invoice document language follows the company profile (Dutch for NL/BE
      companies, English for every other market; --language nl|en overrides)
      — no market is the de facto base.
  • English-first terminology sweep — generic all-market runtime strings
    (labels, plans, help, MCP descriptions) are English by default; statutory
    artifacts keep their legal language per market (OB readout labels,
    'Winst en verlies' statutory XLSX sheet, RGS group names, command aliases,
    import CSV header aliases).
  • financial-statements command (year-end close) with the deprecated
    jaarrekening alias; init --kvk/--btw-id deprecated in favour of
    --registration-id/--tax-id.

Changed

  • Positioning — repository, README and CLI description now state the
    eleven-jurisdiction scope (the "Dutch SMEs" tagline is gone); the invoice
    document-language default is documented as profile-derived (Dutch for NL/BE
    companies, English otherwise). The README presents the Netherlands as one of
    eleven equal citizens: init/company/account/contact options use the
    profile-neutral names (--country, --registration-id, --tax-id,
    --taxonomy-code), chart and report examples are marked as the NL profile's,
    and the OB readout is framed as the NL statutory VAT-return shape. The
    command reference was re-verified against the live CLI (init/company/
    account/contact option names, invoice create + bank import + fx set options,
    per-profile VAT codes and statutory models).

  • Migrations 021–024: company gains country, base_currency, locale,
    profile_version; legal_form CHECK removed; taxonomy backfill for RGS;
    vat_returns/filings type CHECK widened — lossless, verified.

  • Code comments remain Dutch where they explain statutory/fiscal mechanics;
    the public surface is English.

Fixed

  • invoice show no longer throws ReferenceError on invoices with payments
    or outstanding amounts in human mode (locale was undeclared in the render
    path; JSON mode had masked it).
  • i18n table parity repair (the 14 balance-sheet/company keys now exist in
    all 8 full tables; a parity-guard test prevents silent regressions).
  • Residual Dutch literals on generic paths (assets list/schemes, fx, item
    list, ICP readout, import/export summaries, MCP tool descriptions).

Verified

  • 891/891 tests green (was 876 at Phase B start; +15 market/i18n
    coverage). Two consecutive clean full-review passes (rounds 8+9) plus the
    round-10 fresh pass and the i18n 3-review chain — all fail-closed,
    static-only subagent reviews with file:line verdicts.

v0.15.1 — Remote access

Choose a tag to compare

@erikvankempen erikvankempen released this 12 Aug 05:25

Remote access — drive the books from any device

Host the books on one machine (an in-house server, a VPS) and drive them from a phone, a laptop, or an agent on another VPS — while the private signing keys stay on the devices that own them.

What's new

  • bukio server start — serve ONE company DB over HTTP(S). Clients POST signed command envelopes; the server verifies each against the company registry (Ed25519 signature, ±5 min window, nonce replay refusal, authz) and executes it. Output is byte-identical to local mode; audit rows carry the real signature (audit verify works server-side).
  • bukio server token <actor> — mint a one-time enrolment token (single-use, TTL, actor-bound, stored sha256-hashed at rest).
  • bukio actor register --server <url> --token <t> — remote enrolment: the client's public key is enrolled; the private key never leaves the client.
  • Global --server <url> / BUKIO_SERVER — run ANY command remotely, e.g. bukio --server https://bukio.intranet vat book ....
  • Transport guidance — SSH tunnel (recommended for humans, zero new listening ports), Tailscale/WireGuard for agents & always-on clients, native TLS for direct exposure. Plain HTTP on a public interface is discouraged.
  • Same-device mode--server http://127.0.0.1:PORT on the same host works too.

Security model

The private key never leaves the client; the server verifies signatures against enrolled public keys only. Enrolment is capability-gated (one-time, short-lived tokens). Every command is tamper- and replay-proof (canonical digest + nonce + time window); the authz gate and actor enforce on apply server-side. Full rationale in issue #2.

Also in this release

  • SSH/Tailscale transport options documented (README + AGENTS.md)
  • README screenshot regenerated (v0.15.1) showing the remote-access flow
  • Fix: test suite no longer leaks bukio-* temp dirs into /tmp (RAM-starved SQLite on tmpfs hosts)
  • Cost-section refresh: 28.25 KLOC, token spend $13.59, owner time ≈8.8 h / €396

Stats

  • 773/773 tests passing (20 new e2e tests for remote access)
  • 3 new files: src/cli/server.js, src/cli/remote.js, test/remote.test.js
  • Resolves #2 — issue auto-closed by this release

Built with an AI agent (Hermes) and reviewed by a human owner who is not a professional developer. All code Apache-2.0.

bukio-cli v0.15.0 — Verifiable actor attribution

Choose a tag to compare

@erikvankempen erikvankempen released this 11 Aug 06:27

Verifiable actor attribution — resolves #1

The audit trail now records proofs, not claims. Every command is cryptographically signed by its declared actor (Ed25519) and verified against the per-company key registry before dispatch; audit verify re-checks the whole trail and detects tampering, replay, and revoked keys.

Added — actor identity (Tier 0)

  • bukio actor CLI: keygen (Ed25519; human keys passphrase-encrypted), register, list, revoke, enforce --on|--off, unlock/lock (12 h sessions), verify
  • Sign-and-verify gate: every CLI command is auto-signed (canonical digest + ±5 min window + 24 h nonce cache; replay refused in every mode)
  • bukio audit verify: per-row ok | unsigned | revoked | tampered | invalid-signature | unknown-key, exit 1 on anomalies; a copied DB file verifies standalone
  • MCP signed execution: every mutating tool call signed with the same gate, same guarantees across CLI + MCP
  • Migration 018/019: per-company actor_keys registry + audit signature columns (legacy rows read back unsigned — backwards compatible)

Added — per-actor authorizations (Tier 0.5)

  • bukio actor authz --on|--off: deny-by-default capability model (20 families, 6 roles) with segregation-of-duties warnings
  • bukio actor roles / roles grant / roles revoke (owner-only; LAST owner never revoked)

Fixed

  • Aging report: creditors leg now honours --as-of
  • Invoice finalize: sequential number allocated inside the transaction with a UNIQUE-collision retry
  • markPaid: payment insert + status transition commit atomically
  • Recurring createTemplate: object postings kept in VAT-tagged lists
  • MCP server: params: null answered cleanly (-32602, not -32603)
  • audit verify: negative --limit rejected with INVALID_LIMIT

753/753 tests green. Full details in CHANGELOG.md.

bukio-cli v0.14.1: Initial Release

Choose a tag to compare

@erikvankempen erikvankempen released this 09 Aug 09:33

bukio-cli v0.14.1: Initial Release

We are excited to announce the initial release of bukio-cli (v0.14.1), an open-source, local-first double-entry bookkeeping engine designed specifically for Dutch SMEs and AI agents.

While built for human operators, bukio-cli is architected from the ground up to be safely driven by AI agents via the Model Context Protocol (MCP). Everything runs natively on your machine or VPS against a single SQLite database file—giving you complete ownership of your financial data without vendor lock-in.


Key Features

  • Agent-Native Architecture:

    • Native MCP server integration over stdio.
    • Deterministic --json machine outputs for every command.
    • Forced --dry-run (plan mode) support for safe agent execution.
    • Append-only audit logging with required actor identity attribution (--actor human:erik or agent:bartholomeus).
  • Built for the Dutch Business Ecosystem:

    • Bidirectional E-Invoicing (Peppol BIS 3.0): Complete outgoing pipeline (finalize → compliant PDF → UBL → Peppol send) and inbound UBL import (import invoice) directly into the payables register.
    • Tax Compliance: Optional VAT module with Dutch OB-aangifte readout (fields 1a–5d), vat file balance reclassification, vat settle payment booking, KOR support, and ICP listing.
    • Statutory Reporting: Generate Jaarrekening reports (micro/klein models for Title 9 Book 2 BW) and KVK deposit packages.
    • Auditfile Compatibility: Full import and export for XML Auditfile Financieel 4.0 (XAF).
  • Core Bookkeeping & Cash Management:

    • Immutable Ledger: Double-entry engine backstopped by SQLite database triggers. Reversals create linked contra-entries; posted entries are never altered or deleted.
    • Reconciliation & Payments: CAMT.053 / CSV bank statement imports, auto-matching, payables management, and SEPA payment exports (pain.001 credit transfers and pain.008 direct debits with mandate tracking).
    • In-Database Attachments (attach): Store source PDFs or scans directly in the SQLite file as BLOBs (up to 25 MB per file, SHA-256 deduplicated).
    • Encrypted Backups: AES-256-GCM database backup encryption (backup --encrypt) with automated rotation (--keep N).
    • Fixed Assets & FX: Asset register with mid-life adoption support, lineair/degressief schemes, and live European Central Bank (ECB) rate integration for foreign currency transactions.
    • Items Catalog & Multi-Language: Product/service catalog with fractional quantities, total and line-item discounts, custom logo support, and Dutch/English invoice rendering.

Quick Start

Ensure you have Node.js >= 20 installed:

# Install globally or clone
git clone https://github.com/erikvankempen/bukio-cli.git
cd bukio-cli && npm install && npm link

# Initialize a new company database
bukio init --name "Demo BV" --kvk 12345678 --legal-form bv --vat on

# Post an initial capital entry
bukio entry add --date 2026-08-04 --desc "Startkapitaal" \
  --postings "1100:10000.00,3000:-10000.00" --post

# Check trial balance
bukio report trial-balance

Running as an MCP Server for AI Agents

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"trial_balance","arguments":{}}}' \
| bukio mcp

Documentation & Agent Guide

  • Check out AGENTS.md in the repository root for the agent integration manual, command syntax, and strict execution guardrails.
  • View the full README.md for comprehensive command references, database schema details, and cron scheduling recipes.

Feedback & Contributions

Ran into a question, bug, or anything else you need to know? Ask your agent first — it has the full agent manual (AGENTS.md) and this README in context. If your agent is unable to help, or if you want to contribute, shoot me a message at erik@posthumanresources.nl and I'll try to answer it when I'm able.

License: Apache-2.0