@diy-accounting-uk/diya-gl

中文文档
1.2.79发布于 2026/11/12Apache-2.0ES Module构建来源已验证近 30 天下载 1.4万

Recalculate, read and write DIYA-GL books from the command line

原始使用文档
文档目录11 节
  1. Install
  2. Use
  3. API
  4. deriveVatReturn(book, lines, { periodEnd, periodStart?, per…
  5. deriveItsaQuarterlyUpdate(book, lines, { periodEndDate?, qu…
  6. deriveItsaAnnualSubmission(book, lines, { taxYear? })
  7. deriveUkPropertyPeriod(book, lines, { periodStartDate, peri…
  8. deriveUkPropertyAnnual(book, lines, { taxYear? })
  9. The format
  10. Provenance
  11. Licence

@diy-accounting-uk/diya-gl

Run a UK sole trader's or company's accounts from the command line. A DIYA-GL™ book is a book.toml and a lines.jsonl file, usually a few kilobytes, that hold a year of transactions and the chart of accounts they post to. This package recalculates one, reads one out of an Excel workbook, writes one back into a workbook, and serves one over MCP, all through the same engine the DIY Accounting Spreadsheets™ site reconciles in CI.

Four products: Basic Sole Trader, Taxi Driver, Self Employed, Limited Company.

Install

npm install -g @diy-accounting-uk/diya-gl

With Homebrew:

brew tap diy-accounting-uk/diya-gl
brew install diy-accounting-uk/diya-gl/diya-gl

Or run the image straight from GHCR, no install:

docker run --rm -v "$PWD":/data ghcr.io/diy-accounting-uk/diya-gl:latest \
  recalc --package bst --data /data/my-book --years se-2025-2026 --output-dir /data/out

Use

diya-gl recalc --package bst --data my-book --years se-2025-2026 --output-dir out
diya-gl read-workbook --file my-workbook.xlsx --output-dir out
diya-gl write-workbook --data my-book --output-dir out
diya-gl link my-book
diya-gl new-book --product se --name "Lark Lane" --year-end 2027-04-05 --output-dir lark-lane
diya-gl roll-forward --data my-book --output-dir next-year
diya-gl view my-book
diya-gl mcp

Each subcommand is also its own command, if you only want one on your PATH: diya-gl-recalc, diya-gl-read-workbook, diya-gl-write-workbook, diya-gl-link, diya-gl-new-book, diya-gl-roll-forward, diya-gl-view, diya-gl-mcp.

  • recalc takes a diya-gl book (--data) or a populated workbook (--source-dir, --mode saved|recalculate) and writes report.json: every figure, report section and compliance check the engine computes.
  • read-workbook takes an .xlsx, a package zip, or a diya-gl zip or JSON file (--file), and writes book.toml, lines.jsonl, report.json and bookchecks.json.
  • write-workbook takes a diya-gl book (--data or --file) and writes the Excel package its product composes onto its template — the same client-side path the DIYA-GL pages use, so it never needs LibreOffice. Add --zip for the package as one zip.
  • link takes a book (a directory with book.toml and lines.jsonl, a diya-gl zip or a diya-gl JSON file) and prints the https://diya-gl.co.uk/<product>.html#book=<data> link that opens it, the whole book carried in the fragment so nothing is uploaded. --base <url> replaces the origin. The fragment length goes to stderr, with a warning past 64 KB (about 2,000 lines), where chat, email and QR codes start to cut links off.
  • new-book starts an empty book for a new business: --product (bst, se, taxi or ltd), --name and --year-end (YYYY-MM-DD), plus --vat for a VAT-registered Self Employed or Company book. It writes book.toml (the product's starting chart of accounts, the twelve months to the year end and that tax year's rates), an empty lines.jsonl, report.json and bookchecks.json into --output-dir, the current directory by default. It answers: how do I start books for a new business, what accounts does a new sole trader or company book start with, and which tax rates apply to the first year?
  • roll-forward takes a book (--data, the same sources as link) and writes the next year's into --output-dir: the year end a year on with that year's tax rates, the closing balances as opening ones, and lines holding only the opening entries (a Company's opening journal and one brought-forward line per bank account; a Self Employed book's bank lines). Beside book.toml, lines.jsonl, report.json and bookchecks.json it writes rollchecks.json, each opening figure the new year prints against the closing figure the old year printed, and exits 1 when one disagrees. It answers: how do I start next year's books, what do I bring forward from last year, and does my opening balance sheet agree with last year's closing one?
  • view takes the same book sources as link, serves the full diya-gl pages on 127.0.0.1 (--port <number>, default a free port) and opens the book in your default browser (--no-open prints the address only). The pages are not in this package: the local server fetches each file from https://diya-gl.co.uk on first use and caches it under the system temporary directory, one directory per package version, so the first run needs the network and later runs of the same version reuse the cache. --origin <url> fetches from another site. The book stays in the browser (the part of the address after # is never sent anywhere). The server stays up until Ctrl-C. The workbook templates come from spreadsheets.diyaccounting.co.uk the first time a page action needs one.
  • mcp runs a stdio MCP server with ten tools: extract_book, new_book (the empty book new-book writes), roll_forward (the next year roll-forward writes), report, edit_lines, save_workbook, and four that read every detail of the loaded book: lines (filter and group every transaction, e.g. best customer or spend on fuel in June), chart (the accounts and the report rows each feeds), book (the business, period, tax settings and registers) and checks (every book check with the entryNumbers behind it). Point an MCP client at diya-gl-mcp (or diya-gl mcp) with no arguments.

API

The package root exports five functions that turn a book into the figures HMRC's MTD APIs take. Each takes the parsed book, its lines and a parameters object. The VAT and self-employment functions return a promise; the two UK property functions return their answer directly. Nothing is sent anywhere: the answer is the request body to send, plus what fed it.

Load a book first:

import { readFileSync } from "node:fs";
import { parse } from "smol-toml";

function loadBook(dir) {
  const book = parse(readFileSync(`${dir}/book.toml`, "utf8"));
  const lines = readFileSync(`${dir}/lines.jsonl`, "utf8")
    .split("\n")
    .filter(Boolean)
    .map((line) => JSON.parse(line));
  return { book, lines };
}

deriveVatReturn(book, lines, { periodEnd, periodStart?, periodKey? })

The nine VAT return boxes for the three-month period ending periodEnd (YYYY-MM-DD), from a Limited Company book that declares diya-gl:vatRegistered = true. periodStart, when given, must open that quarter; periodKey is echoed back. The answer carries boxes (box1 to box9), hmrc (the same figures under HMRC's field names, boxes 1 to 5 to the penny and 6 to 9 in whole pounds), months, dueDate, scheme, and lines: the journal lines behind boxes 1, 4, 6 and 7, each with what it contributes. A book whose lines do not reconcile with its VAT interface is refused.

import { deriveVatReturn } from "@diy-accounting-uk/diya-gl";

const { book, lines } = loadBook("my-company-book");
const answer = await deriveVatReturn(book, lines, { periodStart: "2025-07-01", periodEnd: "2025-09-30" });
console.log(answer.hmrc); // { vatDueSales, vatDueAcquisitions, totalVatDue, ..., totalAcquisitionsExVAT }

deriveItsaQuarterlyUpdate(book, lines, { periodEndDate?, quarterlyPeriodType?, taxYear? })

One period of HMRC's Self Employment Business API from a Self Employed book. In 2023-24 and 2024-25 each period carries its own figures; from 2025-26 each carries the running total from 6 April. periodEndDate picks the period among the year's four; without it every period is answered. quarterlyPeriodType is standard (6 April quarters, the default) or calendar. taxYear (as 2025-26) overrides the year the book's dates imply. Each period lists the fields the book cannot source under omitted; those are left out of the body, never sent as zero.

import { deriveItsaQuarterlyUpdate } from "@diy-accounting-uk/diya-gl";

const { book, lines } = loadBook("my-self-employed-book");
const answer = await deriveItsaQuarterlyUpdate(book, lines, { periodEndDate: "2025-10-05" });
const [period] = answer.periods; // { periodDates, periodIncome, periodExpenses, ..., omitted, covers }

deriveItsaAnnualSubmission(book, lines, { taxYear? })

The year's allowances and adjustments for the same API's annual submission, from a Self Employed book, restricted to the fields HMRC accepts for that tax year. taxYear (as 2025-26) overrides the year the book's dates imply. The answer carries allowances, adjustments, omitted and warnings.

import { deriveItsaAnnualSubmission } from "@diy-accounting-uk/diya-gl";

const { book, lines } = loadBook("my-self-employed-book");
const answer = await deriveItsaAnnualSubmission(book, lines, { taxYear: "2025-26" });
console.log(answer.allowances.annualInvestmentAllowance);

deriveUkPropertyPeriod(book, lines, { periodStartDate, periodEndDate })

One period of HMRC's Property Business API (UK property) from a sole trader book. The book's chart names the HMRC field each account feeds with diya-gl:ukPropertyField on the account (for example "income.periodAmount" on the rent account, "expenses.repairsAndMaintenance" on the repairs account). The function sums the sales and purchases postings on those accounts between the two dates inclusive, net of VAT, with a credit note taking from its field. The answer carries income, expenses, omitted (the fields no posting fed; they are left out of the body, never sent as zero), lines and warnings. A book that names expenses.consolidatedExpenses and an itemised expense in the same period is refused, because HMRC takes one or the other.

import { deriveUkPropertyPeriod } from "@diy-accounting-uk/diya-gl";

const { book, lines } = loadBook("my-landlord-book");
const answer = deriveUkPropertyPeriod(book, lines, { periodStartDate: "2025-04-06", periodEndDate: "2025-07-05" });
console.log(answer.income.periodAmount, answer.expenses.repairsAndMaintenance);

deriveUkPropertyAnnual(book, lines, { taxYear? })

The year's adjustments (balancingCharge, privateUseAdjustment, businessPremisesRenovationAllowanceBalancingCharges) and allowances (annualInvestmentAllowance, businessPremisesRenovationAllowance, otherCapitalAllowance, costOfReplacingDomesticItems, zeroEmissionsCarAllowance) from the postings on the accounts the chart names, for the tax year taxYear (as 2025-26; the default is the year the book's period end falls in). The property income allowance, nonResidentLandlord and rentARoom.jointlyLet are choices and facts about the landlord, not ledger figures; the answer lists them under leftToPage.

The format

A diya-gl book's fields are drawn from the XBRL Global Ledger Taxonomy Framework 2015 and map onto HMRC's SA103S boxes. The two schemas that validate a book are published at /schema/diya-gl-book-v2.schema.json and /schema/diya-gl-lines-v2.schema.json. The full field mapping, the check catalogue and the reconciliation evidence behind them are on the format spec page.

Provenance

Every book this package writes carries five stamps: the format version, this package's own version and commit, a hash over the tax-year data applied, and each product's template hash and reconciliation scorecard. Recalculating an old book either reproduces its report.json byte for byte or names the stamp that differs. Every published release is cut from a commit whose reconciliation checks passed; the scorecards are on the reconciled releases page.

Licence

This package is licensed under the Apache License 2.0. Embed it, ship it, change it. See LICENSE and NOTICE.

The diya-gl format itself is an open specification. The two JSON Schemas are Apache-2.0 and the format text is CC BY 4.0, so you can implement the format in anything with attribution.

The workbook templates are not part of this package. write-workbook and the MCP save_workbook tool fetch the template they need from spreadsheets.diyaccounting.co.uk the first time they run, print the terms, and cache it for later runs of the same version. The templates are the company's own work, under the PolyForm Internal Use License 1.0.0 with an additional grant: use them for your own accounts, or for your clients' accounts if you are an accountant or a bookkeeper, and do not redistribute them.

This repository does not accept contributions.

Copyright (C) 2006-2026 DIY Accounting Limited.

版本与发布记录

@diy-accounting-uk/diya-gl 共发布 89 个版本,首次发布于 2026/09/08;过去 12 个月发布了 89 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.2.79latest2026/11/12今天
1.2.782026/11/111 天前
1.2.772026/11/066 天前
1.2.762026/11/048 天前
1.2.752026/11/039 天前
1.2.742026/11/0210 天前

关于 @diy-accounting-uk/diya-gl 的常见问题

@diy-accounting-uk/diya-gl 是什么?

Recalculate, read and write DIYA-GL books from the command line

如何安装 @diy-accounting-uk/diya-gl?

在项目目录运行 npm install @diy-accounting-uk/diya-gl,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 diya-gl、diya-gl-mcp、diya-gl-link、diya-gl-view、diya-gl-recalc、diya-gl-new-book、diya-gl-roll-forward、diya-gl-read-workbook、diya-gl-write-workbook,可以用 npx diya-gl 直接运行。

@diy-accounting-uk/diya-gl 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/diy-accounting-uk__diya-gl 是否存在。

@diy-accounting-uk/diya-gl 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@diy-accounting-uk/diya-gl 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@diy-accounting-uk/diya-gl 可以商用吗?

@diy-accounting-uk/diya-gl 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@diy-accounting-uk/diya-gl 的下载量有多少?

根据 npm 官方下载统计,@diy-accounting-uk/diya-gl 在 2026/10/13 – 2026/11/11 这 30 天内被下载 13,841 次,日均约 461 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@diy-accounting-uk/diya-gl 还在维护吗?

最新版本 1.2.79 发布于 2026/11/12(今天);至今共发布 89 个版本,其中过去 12 个月发布了 89 个;首次发布于 2026/09/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。