Change log · every entry posted to main

The release ledger

An accounting app's changelog should keep books like one. Every release below is a posted entry: dated, referenced, signed, and reconciled against the regression suite, a balance that only goes up.

BALANCE C/F v2.20.1 · 3,581 tests Windows + macOS signed full detail on GitHub →

A quieter start

  • FIXEDThe release notes show once per version. The start-up splash opened on every load; the terms recorded their acknowledgement, the what's-new panel never did. Now it opens only while something on it is new, and About still shows it any time. Reported and diagnosed by @stevenmirabito (#220).✓
  • FIXEDThe sign-in and setup screens no longer link to each other. Each link only led somewhere that bounced straight back. From @stevenmirabito (#219).✓

Tidy lists, classes in detail

  • ADDEDInactive records out of the way. Customers, Vendors, Items, Employees and Jobs show active records, with Inactive and All a click away and Make Inactive / Make Active on every row. A customer or vendor with an open balance, or an employee, asks first. Asked for by Ryan of Cimarron Site Services (#210).✓
  • ADDEDP&L by Class in detail. Every account down the side with a column per class. Click an amount for the transactions behind it, or a class for its own Profit & Loss. The General Ledger CSV ends with a Class column (#213).✓
  • FIXED"Expense or COGS". The vendor's and item's account fields say so, and every purchase account list puts Cost of Goods Sold first (#214).✓

Type to find it

  • ADDEDThe pickers search as you type. A customer, vendor, item, account, employee, job or class picker, or any long list, narrows to what you type: "harb" finds Harbor Light Bakery, "6500" finds Rent or Lease, the match in bold. Enter, Tab or a click takes it (#207).✓
  • ADDED"+ New Customer" knows the name. Chosen after typing a name that isn't there, the quick add opens with that name filled in.✓
  • ADDEDHeard, not just seen. A screen reader hears the picker's name, how many names match, and the one highlighted; checked with VoiceOver and Narrator's events.✓
  • CHANGEDWindows builds pin pythonnet 3.2.0, the library the app's window runs on, so every build gets the version the gate ran (#208).✓

Every field says its name

  • FIXEDA screen reader says what each field is. Each form field is read with its label, like "Customer" or "Date", and a required field as required instead of "star". A budget cell reads "Jan, 6500 Rent or Lease", a row's checkbox says what ticking it does, and a search box takes its placeholder as its name, on the Mac too. In 2.18.1, about 1,100 fields had no name at all (#198).✓
  • ADDEDClick a label to reach its field. Clicking a field's label puts the cursor in it. Where the same label appears twice on a screen, as with billing and shipping addresses, the heading above each one is read with it.✓
  • FIXEDAn import that hit errors says so. QuickBooks Interop showed a green "Imported 0 records" even when the only result was an error; now it's red, with the count (#197).✓
  • CHANGEDClaude and Grok come first in the AI provider list, and a company that hasn't chosen one starts on Claude, now on Sonnet 5.5, with Opus 5.5 and Haiku 4.5 beside it. A model you saved is kept (#200).✓

Names from QuickBooks come across clean

  • FIXEDQuotes around a name come off. QuickBooks quotes a name that holds a comma, and the IIF import kept the quote marks. From @TheLocalW (#195).✓
  • ADDEDALL-CAPS names in normal capitalization, if you ask. Validate shows a few of your own names as they would import, beside a box that is off unless you tick it; item names stay as typed. From @TheLocalW (#195).✓
  • FIXEDNames match in any case, and sub-account lines import. A second spelling no longer makes a second customer, vendor or account, and a line posted to a sub-account is no longer refused as not found.✓
  • FIXEDA second import says what it skipped, and a payment for a customer who isn't in your books is reported instead of dropped.✓
  • FIXEDThe permit form's note stays off its boxes. Reported by @cnbarry1 (#194).✓

Around the ledger

  • FIXEDA day of real bookkeeping's findings. Two QA agents each ran a new company for a day and checked every figure by hand: the ledger held, and all sixty-eight things they found around it are fixed. Pay Sales Tax works, supplier tax is part of a purchase's cost, Schedule C keeps expenses in expenses, balances show what is owed, and every aging report equals its control account.✓
  • ADDEDEach company keeps its own files. Logos, attachments and employee documents live in the company file, so a backup carries them; companies on one desktop no longer share a folder.✓
  • SECURITYNothing a company uploaded is served without a sign-in, employee documents open only for an administrator, a backup downloads only for one, portal links are no longer kept as issued, and a sign-in opens only the company it was made in.✓
  • CHANGEDRoles are offered only what they can do. A read-only sign-in sees no writes, and a bookkeeper none of the administrator's settings, AI settings and QuickBooks Online connection included.✓
  • ADDEDQuickBooks Online journals and posted ledger activity import, watched in a live log, and changes flow both ways. With @Sciumo (#192).✓
  • ADDEDTax rates to four decimal places (8.875%); the payment screens see every open invoice and bill (#191); SimpleFIN feeds fetch older history (#181).✓
  • FIXEDDocker: backups work, and saved passwords survive an upgrade. The release notes say what to copy out of a 2.17 container first.✓
  • CHANGEDWCAG AA contrast everywhere, in both themes; chart lines and keys meet 3:1.✓

Payments land on the right account

  • FIXEDPay Bills makes one payment per vendor. Paying bills from two vendors at once recorded a single payment to the first vendor that also paid the other's bill.✓
  • FIXEDA payment, credit memo or batch payment can no longer land on another customer's invoice, nor a bill payment on another vendor's bill. Found with @Bit-Sage.✓

Editing an invoice keeps its job costing

  • FIXEDSaving an invoice from the edit screen no longer strips each line's job and cost code, so its revenue stays on the job's cost codes in Job Cost Detail. Found and fixed with @Bit-Sage.✓
  • FIXEDAn edited invoice posts the way a new one does: foreign-currency invoices at their rate, a changed date moves the ledger entry, and a total cannot drop below what has been paid.✓

OpenAI works again

  • FIXEDAI analysis with OpenAI works on its current models, including the default gpt-5.4-mini, which refused the old request settings. Contributed by @Sciumo.✓
  • CHANGEDReasoning models get room to think before answering, and a reply cut off at the limit says so.✓

Your ledger, in a spreadsheet

  • ADDEDTrial Balance and General Ledger save as a spreadsheet and a printable file; Profit & Loss and Balance Sheet gain the spreadsheet. Amounts are plain numbers, ready to sum, and the files hold the figures on the screen. Asked for by @cnbarry1.✓
  • ADDEDThe General Ledger carries a balance brought forward, a running balance and a period total that ties to the Trial Balance, each account in its natural sign — a payable you owe reads positive.✓
  • CHANGEDBank feeds from any SimpleFIN provider, not only bridge.simplefin.org.✓

The Docker image starts again

  • FIXEDA freshly built server or Docker image starts. A database library update this week changed its default driver and every fresh image failed to start; the library is pinned to the tested version. Desktop apps were not affected.✓
  • FIXEDThe What's New box on the splash reads in the dark theme.✓

Tax-exempt customers, wider amounts, and two forms put right

  • FIXEDReseller and exempt customers are not charged sales tax — on new invoices, estimates, sales receipts, conversions, duplicates and recurring runs. Open invoices saved earlier keep their tax until you edit and save them.✓
  • ADDEDAmounts up to 9,999,999,999,999.99, for currencies with large everyday amounts. Contributed by 6lb.✓
  • FIXEDThe estimate and job-cost forms line up: cells under their headings, nothing cut off, and the estimate shows the tax it will charge. Reported by cnbarry1.✓

Wave's full export imports its journals

  • FIXEDMigrating from Wave brings the journals in. Wave's full export labels its money columns in a way the importer did not recognise, so the dry run passed and the import wrote nothing. Reported by a user mid-migration with 14,372 journals.✓
  • FIXEDA ledger that reads all zero is refused, for every migration source, with the file's own header row in the message. Zero balances against zero; that is how the dry run was fooled.✓
  • FIXEDA second click on Import does not double the books. What an earlier import already brought in is skipped, and the dry run says how many.✓

The year at a glance

  • ADDEDTwo opt-in overview cards. P&L year to date with cumulative net by month, and a balance sheet trend over the last twelve month-ends that balances at every point and equals the report to the cent. Contributed by jarvis4openclaw.✓
  • ADDEDA CSV template in the chart import dialog, served by the app so an offline install has it.✓
  • FIXEDCharts follow a theme toggle. A chart on screen kept the old theme's axis colours, near-invisible, until the next visit; the Analytics page had done the same since it shipped. Found by the Windows lane.✓

Your chart, from your file

  • ADDEDImport a chart of accounts. Chart of Accounts → Import… reads a CSV in the export's columns, any spreadsheet with Number / Name / Type, or hledger's account list — tested against files hledger itself wrote. A dry run shows every row's fate first; nothing is written until you say so.✓
  • ADDEDYour names replace ours. Accounts you already have take the file's names, including the control accounts the software posts to by number — renamed in place, never duplicated, so every document still finds its account. Replace mode hides the seeded accounts you never used.✓
  • FIXEDThe licence block reads in the dark theme too. The terms and the I understand button were near-invisible on the dark splash; found by the macOS lane.✓

In and out of a company, and the terms once

  • ADDEDOpening the app lands in your last company. Its sign-in screen, or the app itself if you were still signed in. The picker is one click away, and appears on its own when there is no last company.✓
  • FIXEDSign out returns to the company picker. It used to reload the same company's password prompt; switching companies meant closing the program. Sign out, the new Switch company button and Choose a different company all go back to the picker.✓
  • ADDEDUsers listed at sign-in. On a multi-user install, pick your name and type only your own password. Names only, before sign-in only.✓
  • ADDEDThe terms, once. The first launch shows the short form of the license with an I understand button; the Windows installer shows the full license with an accept step. First release under LICENSE 2.0.✓

The words the server sends

  • FIXEDEvery message the server sends now uses your company's words. A nonprofit's Pledge screen used to say "Invoice not found" under it — 42 such sentences. Found by walking a running server in both company types, an instrument that now ships with the source.✓
  • FIXEDWhat you post is written in the document's own words. A pledge posts as Pledge, a program-fee invoice stays Invoice, and the ledger, the email and the printed document agree. Existing entries keep the words they were posted with. Payment providers key on ids, never on those words.✓
  • FIXEDConnecting QuickBooks Online works again. Intuit's sign-in handoff was being refused before it could finish, on every install. Contributed by CimarronSiteServices.✓

Bank of America, in a file the bank produced

  • ADDEDImport Bank of America detail CSV exports into the bank-feed review queue. Contributed by Lazyjimpressions, and held back a day for one reason: no file a bank had produced. He opened two real exports and committed a fixture derived from them, byte shape pinned, so every unknown is answered by the bank rather than reasoned out.✓
  • FIXEDThe bank-import dialog says it is working, and names Bank of America. The preview pane stayed empty for the whole round trip and the button stayed live, so a second click put a second parse in flight. It shows that it is reading the file, takes the button away until the answer is back, and does so on every browser engine — the first cut only worked on one.✓
  • FIXEDOnly a sentence written for the user leaves the program. Four code-scanning alerts on the import routes, open since August, closed by making that a property the scanner can see rather than a convention. A missing control account now tells the operator which account to restore instead of "unexpected error".✓
  • FIXEDA Windows machine without the WebView2 runtime is told what it can do — and offered the app in its web browser instead. The old message told the installed application to run a Python command it has no way to run.✓

See an email template before you save it

  • ADDEDPreview a template edit against a real invoice. Editing the invoice email used to mean saving over a working template and mailing a customer to find out what it looked like. The preview also names anything that came out blank — and tells apart a name no template can use from one that is available and simply not set for this invoice. Contributed by mdornich.✓
  • FIXEDThe message for an out-of-date company file now names something you can actually run. The repair tool was not in the installed application, and once it was, nothing on the machine could run it. A repair that cannot finish also no longer starts — it used to clear its way first and then discover it was stuck, leaving the file no better and a second attempt offering advice that also could not work.✓
  • CHANGEDRepairing a file no longer gets slower the more tables are involved. Each attempt restarted the whole upgrade, so the work doubled with every table in the way. Everything blocking is cleared in one pass now.✓

Your chart, your templates, your clipboard

  • FIXEDYou can remove accounts you do not use. A new company arrives with 57 accounts and not one of them could be deleted or hidden — so anyone whose business does not look like ours was stuck with a chart they did not choose. Deactivate, Reactivate and Delete are on the page now. Fifteen accounts still cannot be removed, because the software finds them by number when it posts; those you can rename.✓
  • FIXEDThe email template you save is the email that gets sent. Editing it saved correctly and changed nothing at all. There is a preview in the Email Invoice dialog now, produced by the same code that sends. And sending an invoice failed on every install, because the dialog sent a Message field the server refused.✓
  • SECURITYAn email template could read stored passwords. A template asking for the mail password got the live value, and one asking for the whole settings object got every credential at once — in an email addressed by whoever sent it. Reported privately. Credentials are removed before any template can see them.✓
  • FIXEDCopy buttons tell you the truth. Copying silently did nothing for anyone opening SlowBooks from another machine on the network. All four explain themselves now and leave the text selected. The app also refuses to start against a company file older than itself, instead of quietly making it impossible to upgrade.✓

Wave imports work, and you can copy an API token

  • FIXEDImporting from Wave brought in nothing and reported success. The importer looked for columns Wave does not use, so every row read as an empty account with zero on both sides — and the check that follows called the file balanced, because zero equals zero. Found against a real six-year, two-thousand-transaction export, which now imports with the books balancing to the cent.✓
  • FIXEDWave's own filename defeated the importer. Files are identified by name, and “account” was checked before “transaction” — so Account Transactions.csv was always mistaken for a chart of accounts. Several other exports were being misfiled the same way.✓
  • ADDEDA Copy button for a new API token. The token is shown exactly once and had to be selected by hand, which went wrong often enough that one person recovered theirs from a screenshot. A secret in a camera roll is a security problem, not an inconvenience.✓

Record a credit from a supplier

  • ADDEDVendor Credits. When a supplier credits you — materials returned, a short shipment, a line they overcharged — there was nowhere correct to put it. A negative bill is refused, a negative expense is refused, and both told you to use a credit memo, which only accepts a customer. Enter it as its own document now. It reduces what you owe that vendor straight away, and you choose which bill it settles — or leave it on their account until there is one.✓
  • FIXEDBoth aging reports were hiding credits you are holding. A credit memo reduces what a customer owes the moment you issue it, but the report added up invoices only. A customer with a 1,000 invoice and an unused 300 credit showed 700 in the books and 1,000 on the report. It has overstated what customers owe by every unused credit since credit memos were introduced. Both reports now count them, on their own line.✓
  • ADDEDReturning stock takes it off the shelf. Goods received on a bill go into Inventory rather than an expense, so a credit for goods going back takes them out of Inventory and drops the quantity on hand — instead of leaving an asset on your balance sheet for things that are no longer in the building.✓
  • CHANGEDCredit memo status labels are styled. They have rendered as bare text since credit memos shipped. They match every other status badge now, in both themes.✓

You can see when there is a new version

  • CHANGEDThe update notice is at the top of the sidebar. It used to sit below every menu item, so you found it only by scrolling the whole list — and people stayed on old versions without knowing. It is under the edition line now, visible the moment the app opens. Still a quiet banner and not a dialog, and it takes up no room at all when you are already current. The version you are running is shown beside the edition too.✓
  • FIXEDAn attachment added on Windows can be opened on a Mac or Linux. The file path was stored with the separator of whichever computer uploaded it, so the other two could not find the file. Company files move between machines — that is the point of a file you own. Files an existing Windows install already recorded keep working.✓
  • FIXEDClicking an attachment gives you the file. The download address was being claimed by another page address declared before it, so it answered with nothing. Found in testing by the two people who clicked the link. Every address in the program is now checked for the same problem.✓
  • FIXEDThe search results panel closes, and Quick Entry can be read in dark mode. The panel stayed open until you reloaded, and at rest left a two-pixel grey line under the toolbar — the edge visible along the top of our own screenshots for four releases. The Quick Entry log was white on white, which is the one thing Quick Entry exists to show you.✓

You can edit your chart of accounts again

  • FIXEDEvery account has an Edit button. The page showed one only for accounts you had added yourself — and in a new company the software has added all of them, so the Actions column was empty on every row. The previous release had just told people renaming was allowed. It is, and now you can do it.✓
  • ADDEDThe accounts your books post to are marked and explained. A CONTROL badge on the row, and an edit form that names the account, says what it is used for, and shows the number and type greyed out rather than hiding them — so the reason sits where the restriction is. The name stays yours to change.✓
  • CHANGEDTesting reaches the machines it needs to. The test suite could not even start on a computer without the PDF rendering libraries, which is why a Windows-only fault reached an earlier release with nothing able to catch it. Nearly all of it now runs anywhere.✓

A document is never accepted without its journal entry

  • FIXEDAn invoice that looked saved could miss the books entirely. A reader found that renumbering Accounts Receivable — an ordinary request when matching an accountant's chart — stopped every later invoice, payment and credit memo from reaching the general ledger, while still showing them in the aging report. Same on the payables side. Renumbering an account the software posts to is now refused, and you are told which account and why; renaming it is still yours to do.✓
  • FIXEDA posting that cannot find the account it needs now stops and says so, instead of saving the document and quietly skipping the entry. Opening a company file also tells you once if its chart is missing something the books depend on.✓
  • CHANGEDThe thing that let this through. The books balanced the whole time — debits equalled credits to the cent, because the ledger never contradicted itself; it was simply missing an entry. Our release testing had compared those totals on three machines every release and would have passed this every time. It now ties each control account to its own sub-ledger, and that check is proven against the broken build.✓

The bank register is the ledger

  • CHANGEDA register entry now moves the general ledger. A user coming from QuickBooks asked why a payment typed into the checking register left the checking account untouched. It was a fair question: the register kept its own rows and its own balance, imports never posted, and the documents that did post never appeared in it. From this release there is one ledger. A bank or credit-card account is flagged on the chart, the register is that account's ledger lines with a running balance, and every "paid from" and "deposit to" list shows exactly those accounts.✓
  • ADDEDStatement lines wait in To review. A line imported from a bank feed or a file looks for the entry you already made — same amount, same side, within five days — and matches it. Anything left sits in a queue where you add it with a category, match it by hand, or exclude it. Nothing posts silently. Transfers are a document now, so paying a credit card is a transfer, and reconciliation ticks ledger lines and locks what it closed.✓
  • FIXEDPDF receipts scan on Windows and macOS with nothing to install. Scanning a photo has used the operating system's own text engine since 2.9, but a PDF had to be turned into an image first and only a separate tool could do it, so a PDF receipt answered with an install instruction. Windows and macOS now render the page themselves. Linux still uses poppler-utils, and the message says so only on Linux.✓
  • FIXEDThe cash flow statement follows the cash. It had been adding up the movement of every account, including unpaid bills and opening balances; it now reads only the journals that actually move a bank account. Contributed by a reader of the code.✓
  • CHANGEDUpgrading is not asked to guess. A file from an earlier version keeps its old register balance and shows it once, with the choice to post it as the account's opening balance or dismiss it. The upgrade itself writes nothing to the ledger. Gated on Windows, macOS and Linux over six candidate builds; the last check needed a person, because the dismiss button asks a question no test can answer.✓

The company logo on every document; exception text stays in the server log

  • FIXEDYour logo prints on every document — invoices, estimates, statements, collection letters, donor acknowledgments, giving statements and the financial reports, not only the analytics PDF. Nothing changes for a company without one. Reported in the discussions by a user.✓
  • SECURITYImport failures no longer echo the database's own words. The IIF importer answered a routine QuickBooks export with the whole INSERT statement and every bound value; now every importer and route reports the constraint or a fixed sentence and puts the details in the server log. Closes the five code-scanning alerts. Three gate rounds on three platforms, each one sending a real failing request through the change.✓

SimpleFIN request pinned to the address the guard approved

  • SECURITYOne fix, right behind 2.9.2 — the bank-feed bridge request checked the hostname against a private-address list and then let the HTTP client resolve the name a second time, which a hostile DNS answer could steer at a private service. The request now connects to the address the guard checked, with the hostname kept for the Host header and TLS so the certificate is still verified against it. Flagged by code scanning on the 2.9.2 pull request; the owner ruled it ships now, not later.✓

Security: HR and payroll are admin-only; payment row locks; Server Edition CSP

  • SECURITYFour private security reports, all right, all fixed — the role gate treated everything outside six admin prefixes as daily books, so a bookkeeper could mint any employee's self-service portal token, rewrite direct-deposit accounts and export the NACHA file, and a read-only user could download pay stubs, W-2s and I-9 paperwork. HR and payroll are now admin functions for every method, sessions and API tokens alike; the employee list stays a directory with pay, tax and address blanked for other roles. Batch and bill payments take the row lock single payments already had, so two concurrent requests on PostgreSQL cannot over-apply. Reported by hongshengy and furkan-arslan-sec. If you run Server Edition with more than one role, update.✓
  • FIXEDServer Edition script policy — the desktop window's relaxed policy was also served to LAN browsers; it is now decided per request and only loopback gets it (found by the macOS maintainer). SimpleFIN on PostgreSQL saves its settings (the value column is now text) and bank feeds can target a liability account, both contributed by kycrna.✓

Post-release tidy from the 2.9.0 gate

  • FIXEDNonprofit vocabulary, audited — every screen, form, report modal, email and PDF was walked in nonprofit mode; about sixty leftover business words (toasts, form titles, hints, the analytics aging header, the Contributions by Donor card) and seven labels whose translation key never resolved now speak donor, pledge, fund and grant. Two new guards keep it that way.✓
  • FIXEDA stored AI provider key can be removed (Remove beside the saved mark; the API clears on an explicit empty string, keeps when omitted). Windows releases ship SHA256SUMS.windows beside the installer and zip. The last table only app startup created now has a migration, so the schema comes from migrations alone.✓

Nonprofit mode: funds, net assets, functional expenses, donor documents

  • ADDEDNonprofit mode — one switch in Settings (Company Type → Nonprofit) and every screen speaks the language: Donor Center, Pledges, Donations, Funds, Grants, Statement of Activities, Statement of Financial Position, Net Assets. Nothing in your data changes name; printed documents are literal — a donation prints as a DONATION RECEIPT, a pledge as PLEDGE, a program fee as INVOICE.✓
  • ADDEDFund accounting — a class is a fund with a donor restriction and a default function; net assets are split with / without donor restrictions at report time, releases from restriction are real journal entries, and the two net-asset lines always add up to the balance sheet's equity. Every expense carries program / management / fundraising; allocation rules (percent, square feet, hours on grants) split a shared cost at entry or in one month-end run.✓
  • ADDEDFive statements — Activities, Financial Position, Fund Balances, Functional Expenses in Form 990 Part IX column order, and a Pledge Report, each with PDF and CSV and a compare-to-prior-year column. Donor documents — IRS Publication 1771 language on receipts and acknowledgment letters (an editable template), in-kind gifts described without a value, year-end giving statements one per donor or the whole stack, pledge write-offs to Bad Debt.✓
  • ADDEDFor agents — unknown request fields are a 422 naming the field instead of a silently dropped $0 document; tax_rate is documented as a fraction and a percent-looking value is refused with the unit in the message; PTO enums are in the spec; DELETE on a posted document names the /void route; a fresh company can run depreciation first time.✓
  • ADDEDCustom AI provider — an eighth AI Insights provider: any OpenAI-compatible /v1/chat/completions endpoint you name, HTTPS-only with the same SSRF guard as the Worker gateway (contributed by @jarvis4openclaw). The self-hosted Cloudflare Worker gateway's replies, which were parsed to empty, now come through.✓
  • FIXEDmacOS: the desktop bridge (Save PDF, print preview, Save backup, Show in folder) had been silently dead since v2.1 — the app's security policy blocked it under WebKit; the app is now stapled before the disk image is built and asks for Documents and Downloads access with an explanation. Docker: the documented docker compose up had not started since v2.8 (a missing migration, then the production guards refusing the stack's own configuration, then a first-boot worker race); all three fixed and the Linux gate now runs it on every release. Save PDF says where the file went and offers Show in folder; a company's two names can no longer diverge.✓

Benefits, all-state payroll, and an overview you can arrange

  • ADDEDBenefits engine — a benefit is a code with a rule, and payroll evaluates whatever codes are attached to an employee. Pre-tax codes apply in an explicit order, each changing the taxable base for the next; rates are effective-dated and resolve against the pay-period end; limits are per period, annual and wage-base; the employer side has its own method including tiered 401(k) matching, an expense and liability account per code, and a remittance vendor whose bill the Remittance tab creates. Employee groups are templates an enrollment can override, loan-style codes run down to zero, PTO banks carry dollars and post the accrued liability, and processed runs snapshot the rules they used. Your deduction types and elections migrate onto it.✓
  • ADDEDState withholding for all 50 states and DC — every state resolves to a payroll engine with the 2026 published figures and the source named per state; employees gain the state W-4 inputs (allowances, extra withholding, an elected rate, a local rate for county and city taxes). Actual employer taxes and job-routed benefits can flow to jobs as labor burden by hours.✓
  • ADDEDCustomizable overview — pick, hide and reorder the Company Snapshot's cards, remembered per user, with five new cards; the Snapshot is titled with your company's name. Sales tax per line — untaxed labor and taxed parts on one invoice. Export parity — IIF and CSV export now carry classes, jobs, bills, deposits and sales receipts, and a full export re-imports without duplicates.✓
  • ADDEDAccessibility — real dialogs with focus trapping, table header scopes, contrast that clears AA in both themes, and every PDF generated tagged (PDF/UA-1) with a language and title. The posture is "strives to conform to WCAG 2.1 AA", never a compliance claim.✓
  • FIXEDThe employee portal link opened inside the desktop app instead of the employee's browser; a post-tax deduction larger than a check could post an unbalanced payroll entry (found on the macOS lap); the splash now shows what's new in the version you're running.✓

Jobs, job costing, and receipts that read themselves

  • ADDEDJobs — QuickBooks-style Customer:Job on every invoice, bill, expense, card charge, journal entry, estimate, purchase order and time entry, carried on the posted line rather than the document. A Jobs page shows Budget, Committed, Actual, Projected, Variance and % Used per job; open one and drill from cost type to division to code to the posted lines, each opening the document behind it. QuickBooks Customer:Job names and Online sub-customers import as jobs.✓
  • ADDEDJob costing — nested cost codes with a CSI MasterFormat loader, editable cost types with a burden rate, Job Cost Entries for internal labor, equipment hours, mileage and overhead, approved time posted to jobs at loaded rates, allocations across jobs, budgets seeded from estimates, committed cost from open purchase orders, and a Job Profitability report that totals to the P&L.✓
  • ADDEDReceipt intake — scan a receipt photo or PDF into a Bill, Expense or Sales Receipt using the OCR built into macOS and Windows (Tesseract on Linux), with a box-to-fix canvas for anything it misread and a remembered layout per merchant. Nothing to install.✓
  • FIXEDThe Time Entry form saved every entry with zero hours; the estimate form never showed its Class field. Both found on the hardware laps.✓

Your QuickBooks classes come with you

  • ADDEDClass list import — QuickBooks keeps classes in a list export of their own, separate from your transactions, and that export used to be skipped on the way in. A migrated file arrived with every class stripped, and any transaction that named one refused to post. Export the class list and it now comes across whole: subclasses keep their full Parent:Child name, inactive classes arrive archived, and re-importing the same list changes nothing.✓
  • FIXEDCheck Detail and Deposit Detail reports quietly dropped the block types their parser does not handle. Those are counted and named now, so a full export stops looking like it imported cleanly when only part of it did.✓
  • FIXEDCSV uploads fall back to Windows-1252 when a file is not UTF-8. QuickBooks Desktop's Save as CSV often writes ANSI, and a payee like José used to fail the upload outright.✓

Your QuickBooks reports import themselves

  • ADDEDReport-CSV import — QuickBooks Desktop can't export transactions to IIF, so its report exports now upload directly: Transaction Detail (sales receipts), Deposit Detail, and Check Detail, auto-detected from one upload. Payroll checks work — withholding lines credit their liability accounts and net to the check. Every parser was validated against a real customer's exports.✓
  • FIXEDCreating a customer or vendor with a blank Email box failed with an unexplained error; blank now simply means no email, and validation messages name the field they're about.✓
  • FIXEDThe Server Edition install script now actually copies your desktop books into the server's data home — and a quoting bug that silently prevented the startup task from ever registering from the normal install path is fixed, verified end-to-end on real hardware. Both found by a Server Edition user's field report.✓

The receipt now looks like a receipt

  • FIXEDThe printed sales receipt was rendering as an invoice — titled INVOICE, with Due Date, Terms, and Balance Due rows on a sale paid in full at the counter. It now prints as a SALES RECEIPT: date, Sold To, Total + Paid, saved as SalesReceipt_<n>.pdf. Caught on macOS hardware by @ContractorKeith during the release pass.✓
  • FIXEDThe PDF's address block always prints the customer's name now — previously the direct download printed a bare header for customers with no address on file.✓
  • CHANGEDThe macOS checksum file now covers the stable-named DMG, so the README's direct download link is verifiable.✓

Sales receipts, rung up on one screen

  • ADDEDEnter Sales Receipts - for point-of-sale style sales where the customer pays on the spot: one form records the sale and its payment together, deposited to the account you choose, with both journal entries posted atomically. Requested by a user moving decades of counter sales over from QuickBooks.✓
  • ADDEDQuickBooks sales receipt import, both flavors: CASH SALE blocks in Desktop IIF files (counter sales with no customer land on an auto-created “Walk-In Customer”) and the SalesReceipt entity over the QuickBooks Online connection. Re-imports dedup; nothing counts twice.✓
  • ADDEDA migrate-from-QuickBooks guide covering both paths, including the clean report recipe for getting sales history out of Desktop without the messy summary exports.✓
  • CHANGEDSales receipts list on their own page; the Invoices page shows only invoices. The API is unchanged unless you ask it to filter.✓

API hardening, and the Mac signs itself

  • FIXEDBalance sheet and P&L lines now display signed amounts, so a contra-balance account (like A/R after an unapplied customer prepayment) always agrees with its total. Reported by @markhalonen, released same day.✓
  • FIXEDIIF imports no longer auto-create unnamed customers from blank NAME rows, and imported names respect field limits.✓
  • FIXED--help on the installed Windows app could hang invisibly when its output was piped; command output is now total.✓
  • CHANGEDMachine-written audit rows are attributed to an explicit system principal; a blank actor is now always a bug, never a state.✓
  • ADDEDmacOS releases sign, notarize, and staple in CI on every tag. Publisher: Trenton Von Holten.✓

Everything secret is sealed

  • SECURITYEvery stored credential (SMTP, Stripe, PayPal, Square, QuickBooks Online, SimpleFIN, the closing-date password) is now encrypted at rest. Existing plaintext values upgrade themselves on first boot.✓
  • FIXEDQuitting the macOS app no longer leaves its server running in the background. Reported by @ContractorKeith.✓

Scoped API tokens

  • ADDEDRole-bound bearer tokens for agents and integrations, shown once, hashed at rest, audited as token:<label>. A token can hold read-only, bookkeeper, or admin scope, but can never manage users or mint more tokens. The AI setup guide now leads with them.✓

Server Edition, and a native Mac

  • ADDEDServer Edition - the same signed install, serving your whole office over the LAN: users and roles (admin / bookkeeper / read-only), per-user attribution on the tamper-evident audit trail, and a one-command Windows service install. Free, like everything else.✓
  • ADDEDNative macOS app for Apple Silicon - drag-to-Applications DMG, macOS 14+. Build pipeline by @ContractorKeith.✓

Updates look updated

  • FIXEDThe Windows desktop could keep showing the previous version's interface after an update (a stale embedded-browser cache). Caches are now purged on version change and pages revalidate.✓

The software drops the bit

  • CHANGEDThe fictional "decompiled from QuickBooks" flavor text is gone from the app itself - splash, About, PDF footers. The origin story lives in the README, where it belongs. Your invoices are yours, not our joke.✓

Bank feeds, on your terms

  • ADDEDSimpleFIN bank feeds - connect your bank with a credential you hold, with no aggregator account in our name. Synced transactions flow through the same dedup and bank-rules engine as OFX imports.✓

Migration onramps

  • ADDEDOne Migrate Data page that brings full accounting history in from six systems (MYOB, GnuCash, Wave, Zoho Books, Xero, and QuickBooks Online), all behind the same dry-run gate: nothing is written until every reconstructed journal balances.✓

The fork-integration release

  • ADDEDClass tracking, multi-currency with Bank of Canada FX rates, CSV bank import, fixed assets with depreciation, and a redesigned report PDF pack, the best work from community forks, brought upstream with credit to @LayoverLogic, @moshgrossman, @amazon1148, and @joelmacklow.✓

First-field-machine fixes

  • FIXEDLessons from the first Windows machine that wasn't a dev box: print and PDF windows stay signed in, and the installer bootstraps the WebView2 runtime on machines that lack it.✓

Opening entry: the signed Windows installer

  • ADDEDA code-signed native Windows installer - Windows shows a verified publisher instead of a warning. One file per company, desktop mode, and the in-app update badge that brought you here.✓

† An adjusting entry: v2.4.1 retired one test along with the flavor text it guarded. Ledgers are allowed those, when they're disclosed.

Balance carried forward. Next entry: when it's ready.