bkper 4.12.30 → 4.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/lib/auth/local-auth-service.d.ts.map +1 -1
- package/lib/auth/local-auth-service.js +83 -66
- package/lib/auth/local-auth-service.js.map +1 -1
- package/lib/cli.js +2 -0
- package/lib/cli.js.map +1 -1
- package/lib/commands/cli-helpers.d.ts +4 -0
- package/lib/commands/cli-helpers.d.ts.map +1 -1
- package/lib/commands/cli-helpers.js +8 -2
- package/lib/commands/cli-helpers.js.map +1 -1
- package/lib/commands/files/get.d.ts +14 -0
- package/lib/commands/files/get.d.ts.map +1 -0
- package/lib/commands/files/get.js +34 -0
- package/lib/commands/files/get.js.map +1 -0
- package/lib/commands/files/index.d.ts +3 -0
- package/lib/commands/files/index.d.ts.map +1 -0
- package/lib/commands/files/index.js +3 -0
- package/lib/commands/files/index.js.map +1 -0
- package/lib/commands/files/register.d.ts +3 -0
- package/lib/commands/files/register.d.ts.map +1 -0
- package/lib/commands/files/register.js +42 -0
- package/lib/commands/files/register.js.map +1 -0
- package/lib/commands/files/upload.d.ts +18 -0
- package/lib/commands/files/upload.d.ts.map +1 -0
- package/lib/commands/files/upload.js +94 -0
- package/lib/commands/files/upload.js.map +1 -0
- package/lib/commands/transactions/create.d.ts +9 -0
- package/lib/commands/transactions/create.d.ts.map +1 -1
- package/lib/commands/transactions/create.js +30 -1
- package/lib/commands/transactions/create.js.map +1 -1
- package/lib/commands/transactions/index.d.ts +1 -1
- package/lib/commands/transactions/index.d.ts.map +1 -1
- package/lib/commands/transactions/index.js +1 -1
- package/lib/commands/transactions/index.js.map +1 -1
- package/lib/commands/transactions/register.d.ts.map +1 -1
- package/lib/commands/transactions/register.js +5 -2
- package/lib/commands/transactions/register.js.map +1 -1
- package/lib/docs/cli-reference.md +4 -1
- package/lib/docs/data-management.md +45 -1
- package/lib/docs/index.md +3 -2
- package/lib/docs/taxes.md +264 -0
- package/lib/utils/local-file.d.ts +11 -0
- package/lib/utils/local-file.d.ts.map +1 -0
- package/lib/utils/local-file.js +55 -0
- package/lib/utils/local-file.js.map +1 -0
- package/package.json +2 -1
|
@@ -7,10 +7,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import { File as BkperFile, Transaction } from 'bkper-js';
|
|
10
11
|
import { getBkperInstance } from '../../bkper-factory.js';
|
|
11
|
-
import {
|
|
12
|
+
import { readLocalFilePayload } from '../../utils/local-file.js';
|
|
12
13
|
import { parsePropertyFlag } from '../../utils/properties.js';
|
|
13
14
|
import { throwIfErrors } from '../../utils/validation.js';
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the single supported --file value for transaction create.
|
|
17
|
+
*
|
|
18
|
+
* @param filePaths - Parsed --file option values
|
|
19
|
+
* @param hasStdinInput - Whether stdin JSON input was provided
|
|
20
|
+
* @returns The single file path, if any
|
|
21
|
+
*/
|
|
22
|
+
export function resolveCreateTransactionFilePath(filePaths, hasStdinInput) {
|
|
23
|
+
const errors = [];
|
|
24
|
+
if (filePaths && filePaths.length > 1) {
|
|
25
|
+
errors.push('Option --file may only be provided once');
|
|
26
|
+
}
|
|
27
|
+
if (hasStdinInput && filePaths && filePaths.length > 0) {
|
|
28
|
+
errors.push('Option --file is only supported for single transaction create and cannot be used with stdin input');
|
|
29
|
+
}
|
|
30
|
+
throwIfErrors(errors);
|
|
31
|
+
return filePaths === null || filePaths === void 0 ? void 0 : filePaths[0];
|
|
32
|
+
}
|
|
14
33
|
/**
|
|
15
34
|
* Creates a new transaction in the specified book.
|
|
16
35
|
*
|
|
@@ -74,6 +93,16 @@ export function createTransaction(bookId, options) {
|
|
|
74
93
|
}
|
|
75
94
|
}
|
|
76
95
|
}
|
|
96
|
+
if (options.file) {
|
|
97
|
+
try {
|
|
98
|
+
const payload = yield readLocalFilePayload(options.file);
|
|
99
|
+
const file = new BkperFile(book, payload);
|
|
100
|
+
tx.addFile(file);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
errors.push(err.message);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
77
106
|
throwIfErrors(errors);
|
|
78
107
|
return tx.create();
|
|
79
108
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/transactions/create.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/commands/transactions/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { listTransactions, listTransactionsFormatted, ListTransactionsOptions, ListTransactionsResult, } from './list.js';
|
|
2
|
-
export { createTransaction, CreateTransactionOptions } from './create.js';
|
|
2
|
+
export { createTransaction, CreateTransactionOptions, resolveCreateTransactionFilePath, } from './create.js';
|
|
3
3
|
export { updateTransaction, UpdateTransactionOptions } from './update.js';
|
|
4
4
|
export { postTransaction } from './post.js';
|
|
5
5
|
export { checkTransaction } from './check.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/transactions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,GACzB,MAAM,WAAW,CAAC;AACnB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/transactions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,GACzB,MAAM,WAAW,CAAC;AACnB,OAAO,EACH,iBAAiB,EACjB,wBAAwB,EACxB,gCAAgC,GACnC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { listTransactions, listTransactionsFormatted, } from './list.js';
|
|
2
|
-
export { createTransaction } from './create.js';
|
|
2
|
+
export { createTransaction, resolveCreateTransactionFilePath, } from './create.js';
|
|
3
3
|
export { updateTransaction } from './update.js';
|
|
4
4
|
export { postTransaction } from './post.js';
|
|
5
5
|
export { checkTransaction } from './check.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/transactions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,yBAAyB,GAG5B,MAAM,WAAW,CAAC;AACnB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/transactions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,yBAAyB,GAG5B,MAAM,WAAW,CAAC;AACnB,OAAO,EACH,iBAAiB,EAEjB,gCAAgC,GACnC,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAA4B,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAe,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/commands/transactions/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/commands/transactions/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBzC,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuMlE"}
|
|
@@ -8,11 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { withAction } from '../action.js';
|
|
11
|
-
import { collectProperty } from '../cli-helpers.js';
|
|
11
|
+
import { collectProperty, collectRepeatable } from '../cli-helpers.js';
|
|
12
12
|
import { renderListResult, renderItem } from '../../render/index.js';
|
|
13
13
|
import { validateRequiredOptions, throwIfErrors } from '../../utils/validation.js';
|
|
14
14
|
import { parseStdinItems } from '../../input/index.js';
|
|
15
|
-
import { listTransactionsFormatted, createTransaction, updateTransaction, postTransaction, checkTransaction, trashTransaction, mergeTransactions, batchCreateTransactions, batchUpdateTransactions, } from './index.js';
|
|
15
|
+
import { listTransactionsFormatted, createTransaction, updateTransaction, postTransaction, checkTransaction, trashTransaction, mergeTransactions, batchCreateTransactions, batchUpdateTransactions, resolveCreateTransactionFilePath, } from './index.js';
|
|
16
16
|
export function registerTransactionCommands(program) {
|
|
17
17
|
const transactionCommand = program.command('transaction').description('Manage Transactions');
|
|
18
18
|
transactionCommand
|
|
@@ -43,9 +43,11 @@ export function registerTransactionCommands(program) {
|
|
|
43
43
|
.option('--to <to>', 'Debit account (destination)')
|
|
44
44
|
.option('--url <url>', 'URL (repeatable)', collectProperty)
|
|
45
45
|
.option('--remote-id <remoteId>', 'Remote ID (repeatable)', collectProperty)
|
|
46
|
+
.option('--file <path>', 'Attach a local file (single-create only)', collectRepeatable)
|
|
46
47
|
.option('-p, --property <key=value>', 'Set a property (repeatable, empty value deletes)', collectProperty)
|
|
47
48
|
.action(options => withAction('creating transaction', (format) => __awaiter(this, void 0, void 0, function* () {
|
|
48
49
|
const stdinData = !process.stdin.isTTY ? yield parseStdinItems() : null;
|
|
50
|
+
const filePath = resolveCreateTransactionFilePath(options.file, stdinData !== null);
|
|
49
51
|
if (stdinData && stdinData.items.length > 0) {
|
|
50
52
|
throwIfErrors(validateRequiredOptions(options, [{ name: 'book', flag: '--book' }]));
|
|
51
53
|
yield batchCreateTransactions(options.book, stdinData.items, options.property);
|
|
@@ -64,6 +66,7 @@ export function registerTransactionCommands(program) {
|
|
|
64
66
|
url: options.url,
|
|
65
67
|
remoteId: options.remoteId,
|
|
66
68
|
property: options.property,
|
|
69
|
+
file: filePath,
|
|
67
70
|
});
|
|
68
71
|
renderItem(transaction.json(), format);
|
|
69
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/commands/transactions/register.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/commands/transactions/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -137,10 +137,13 @@ Pi-specific extensions are loaded from Pi extension folders (for example `.pi/ex
|
|
|
137
137
|
|
|
138
138
|
## Data Management
|
|
139
139
|
|
|
140
|
-
Manage books, accounts, transactions, and balances.
|
|
140
|
+
Manage books, files, accounts, transactions, and balances.
|
|
141
141
|
|
|
142
142
|
```bash
|
|
143
143
|
bkper book list
|
|
144
|
+
bkper file upload ./receipt.pdf -b <bookId>
|
|
145
|
+
bkper file get <fileId> -b <bookId>
|
|
146
|
+
bkper transaction create -b <bookId> --description "Team lunch" --file ./receipt.pdf
|
|
144
147
|
bkper account list -b <bookId>
|
|
145
148
|
bkper transaction list -b <bookId> -q 'on:2025' --format csv
|
|
146
149
|
bkper balance list -b <bookId> -q 'on:2025-12-31' --format csv
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Data Management
|
|
2
2
|
|
|
3
|
-
Interact with books, accounts, transactions, and balances using the `bkper` CLI.
|
|
3
|
+
Interact with books, files, accounts, transactions, and balances using the `bkper` CLI.
|
|
4
4
|
|
|
5
5
|
All commands that operate within a book use `-b, --book <bookId>` to specify the book context.
|
|
6
6
|
|
|
@@ -155,6 +155,39 @@ Avoid using the same name for a Group and an Account in the same Book.
|
|
|
155
155
|
|
|
156
156
|
---
|
|
157
157
|
|
|
158
|
+
## Files
|
|
159
|
+
|
|
160
|
+
Upload local files to a book and optionally route them with properties.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Upload a file to a book
|
|
164
|
+
bkper file upload ./receipt.jpg -b abc123
|
|
165
|
+
|
|
166
|
+
# Get a file by id
|
|
167
|
+
bkper file get file_123 -b abc123
|
|
168
|
+
|
|
169
|
+
# Upload and resolve an account to canonical account_id
|
|
170
|
+
bkper file upload ./statement.pdf -b abc123 --account "Credit Card"
|
|
171
|
+
|
|
172
|
+
# Upload with workflow properties
|
|
173
|
+
bkper file upload ./statement.pdf -b abc123 \
|
|
174
|
+
-p statement_period=2025-01 -p group_id=grp_123
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Use `-p group_id=...` for group-based routing. The CLI infers `contentType` from the local filename when possible, so PDFs are uploaded as `application/pdf` instead of a generic binary type. It rejects `--account` together with raw `-p account_id=...` and forbids `-p upload_method=...` because that property is reserved for transaction attachments.
|
|
178
|
+
|
|
179
|
+
<details>
|
|
180
|
+
<summary>Command reference</summary>
|
|
181
|
+
|
|
182
|
+
- `file get <fileId> -b <bookId>` - Get a file by ID
|
|
183
|
+
- `file upload <path> -b <bookId>` - Upload a local file to a book
|
|
184
|
+
- `--account <accountIdOrName>` - Resolve an account by name or id and persist canonical `account_id=<resolvedAccountId>`
|
|
185
|
+
- `-p, --property <key=value>` - Set a property (repeatable, empty value deletes)
|
|
186
|
+
|
|
187
|
+
</details>
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
158
191
|
## Transactions
|
|
159
192
|
|
|
160
193
|
Record, query, and manage financial transactions.
|
|
@@ -167,6 +200,13 @@ bkper transaction create -b abc123 --description "Office supplies"
|
|
|
167
200
|
bkper transaction create -b abc123 --date 2025-01-15 --amount 100.50 \
|
|
168
201
|
--from "Bank Account" --to "Office Supplies" --description "Printer paper"
|
|
169
202
|
|
|
203
|
+
# Create a transaction with one local attachment
|
|
204
|
+
bkper transaction create -b abc123 --date 2025-01-15 --amount 23.90 \
|
|
205
|
+
--from "Cash" --to "Meals" --description "Team lunch" --file ./receipt.pdf
|
|
206
|
+
|
|
207
|
+
# Create a file-only draft for receipt capture
|
|
208
|
+
bkper transaction create -b abc123 --file ./invoice.pdf
|
|
209
|
+
|
|
170
210
|
# List transactions for a full year (on:YYYY)
|
|
171
211
|
bkper transaction list -b abc123 -q 'on:2025'
|
|
172
212
|
|
|
@@ -205,6 +245,7 @@ bkper transaction merge tx_123 tx_456 -b abc123
|
|
|
205
245
|
- `--to <to>` - Debit account (destination)
|
|
206
246
|
- `--url <url>` - URL (repeatable)
|
|
207
247
|
- `--remote-id <remoteId>` - Remote ID (repeatable)
|
|
248
|
+
- `--file <path>` - Attach one local file during single-create mode only
|
|
208
249
|
- `-p, --property <key=value>` - Set a property (repeatable, empty value deletes)
|
|
209
250
|
- `transaction update [transactionId] -b <bookId>` - Update a transaction (or batch update via stdin)
|
|
210
251
|
- `--date <date>` - Transaction date
|
|
@@ -222,6 +263,7 @@ bkper transaction merge tx_123 tx_456 -b abc123
|
|
|
222
263
|
|
|
223
264
|
</details>
|
|
224
265
|
|
|
266
|
+
|
|
225
267
|
---
|
|
226
268
|
|
|
227
269
|
## Balances
|
|
@@ -367,6 +409,8 @@ CSV is significantly more token-efficient than JSON for tabular data, and for wi
|
|
|
367
409
|
|
|
368
410
|
Write commands (`account create`, `transaction create`) accept JSON data piped via stdin for batch operations. The `transaction update` command also accepts stdin for batch updates. The input format follows the [Bkper API Types](https://raw.githubusercontent.com/bkper/bkper-api-types/refs/heads/master/index.d.ts) exactly -- a single JSON object or an array of objects.
|
|
369
411
|
|
|
412
|
+
`transaction create --file` is not available in stdin batch mode. Use single-create commands when attaching a local file.
|
|
413
|
+
|
|
370
414
|
```bash
|
|
371
415
|
# Create transactions
|
|
372
416
|
echo '[{
|
package/lib/docs/index.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Reference docs for Bkper tasks. Load only the specific doc(s) relevant to the task — do not load all of them. All docs are in the same directory as this index.
|
|
4
4
|
|
|
5
|
-
- **data-management.md** — CLI reference for managing financial data: books, accounts, groups, transactions, per-account balance queries, query operators (on:, after:, before:, account:, group:), output formats (table/json/csv), batch operations via stdin/piping, collections.
|
|
5
|
+
- **data-management.md** — CLI reference for managing financial data and files: books, accounts, groups, files, transactions, per-account balance queries, query operators (on:, after:, before:, account:, group:), output formats (table/json/csv), batch operations via stdin/piping, collections.
|
|
6
6
|
- **app-management.md** — CLI reference for building and deploying Bkper apps: dev/build/deploy workflow, app install/uninstall, secrets management, app logs, bkper.yaml configuration reference (identity, branding, events, menu integration, deployment).
|
|
7
7
|
- **app-building.md** — Full app-building reference: architecture (packages, client/server/events), development loop, event handlers, deployment patterns, the Bkper Platform, and self-hosted alternatives. Includes authentication patterns for web clients (`@bkper/web-auth`), event handlers (`bkper-oauth-token` headers), and local development. Load this for scaffolding apps, understanding app structure, or debugging the dev/build/deploy lifecycle.
|
|
8
8
|
- **financial-statements.md** — Step-by-step workflow for aggregate financial reports (balance sheet, P&L): root group discovery, query patterns, date semantics (before: vs after:+before:), common mistakes to avoid.
|
|
9
|
+
- **taxes.md** — Deterministic workflow for tax position and filing summaries: discovering tax-relevant groups, period-based balance queries, persisting a local tax runner. Jurisdiction-agnostic — outputs raw period balances, leaving rate/application to the user.
|
|
9
10
|
- **bkper-js.md** — bkper-js Node.js/browser SDK: Bkper, Book, Account, Transaction, Group, Balance classes, all methods, getBalancesReport, OAuth configuration, library setup.
|
|
10
|
-
- **bkper-api-types.md** — Bkper REST API TypeScript interfaces: Book, Account, Transaction, Group, Balance, Collection — field names and types used by the API and bkper-js.
|
|
11
|
+
- **bkper-api-types.md** — Bkper REST API TypeScript interfaces: Book, Account, Transaction, Group, Balance, Collection, File — field names and types used by the API and bkper-js.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Taxes — Deterministic Workflow
|
|
2
|
+
|
|
3
|
+
Use this guide when a user asks to "do my taxes", compute a tax position, generate a tax filing summary, or derive any period-based tax report from a Bkper book.
|
|
4
|
+
|
|
5
|
+
## Deterministic first
|
|
6
|
+
|
|
7
|
+
Tax reporting is a **deterministic accounting task**.
|
|
8
|
+
|
|
9
|
+
For the same book snapshot, tax period, and set of tax-relevant groups, the agent should be able to run the same local code/config and obtain the same tax position every time. Use non-deterministic reasoning only for interpretive tasks — such as flagging unusual transactions, commenting on trends, or explaining variances — not for deciding how the tax position itself is computed.
|
|
10
|
+
|
|
11
|
+
Treat the tax route as something that should be **persisted locally** and reused.
|
|
12
|
+
|
|
13
|
+
Jurisdiction-specific tax rules (rates, deductions, allowances, filing formats) vary widely and change over time. This workflow intentionally stays **agnostic about those rules**. It provides the deterministic scaffold: discovering tax-relevant account groupings, querying period data, producing a repeatable tax position through a local runner, and persisting that route. The user applies their local tax knowledge to interpret the output.
|
|
14
|
+
|
|
15
|
+
The agent does **not** compute tax owed directly. It builds or reuses a **local tax generation engine** (a script, config, or small program) that queries the book deterministically and outputs raw period data. The engine is the canonical source of truth; the agent merely orchestrates, validates, and persists it.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Step 0 — Reuse an existing local tax runner
|
|
20
|
+
|
|
21
|
+
Before running ad-hoc queries, inspect the local project for a canonical deterministic tax runner.
|
|
22
|
+
|
|
23
|
+
Look for artifacts such as:
|
|
24
|
+
|
|
25
|
+
- `reports/`
|
|
26
|
+
- `scripts/`
|
|
27
|
+
- `package.json` scripts
|
|
28
|
+
- local config/spec files
|
|
29
|
+
- `AGENTS.md`
|
|
30
|
+
|
|
31
|
+
If a local tax runner already exists:
|
|
32
|
+
|
|
33
|
+
- Use it as the default route
|
|
34
|
+
- Pass explicit parameters for book, period, and any tax-relevant overrides
|
|
35
|
+
- Return the result produced by that runner
|
|
36
|
+
- Do **not** rediscover groups or rebuild fresh queries unless the user explicitly asks to update or rebuild the tax logic
|
|
37
|
+
|
|
38
|
+
Once a deterministic route exists, prefer it over live ad-hoc querying.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Step 1 — If none exists, bootstrap one
|
|
43
|
+
|
|
44
|
+
If no deterministic runner exists yet, do **not** treat a live one-off query as the canonical solution.
|
|
45
|
+
|
|
46
|
+
Instead:
|
|
47
|
+
|
|
48
|
+
1. Explain briefly that tax positions should be generated by a repeatable local engine
|
|
49
|
+
2. Offer to create that tax runner for the project
|
|
50
|
+
3. Ask approval before writing files
|
|
51
|
+
4. Use live Bkper queries only as **bootstrap/discovery steps** to build the deterministic route correctly
|
|
52
|
+
|
|
53
|
+
If the request is ambiguous (for example, "do my taxes"), clarify what the user wants:
|
|
54
|
+
|
|
55
|
+
- Tax position for a specific period (e.g., quarterly VAT, annual income tax)
|
|
56
|
+
- Tax filing summary / worksheet for their jurisdiction
|
|
57
|
+
- Reconciliation of tax-related balances
|
|
58
|
+
|
|
59
|
+
During bootstrap, it is acceptable to create either:
|
|
60
|
+
|
|
61
|
+
- a small shell script that runs fixed CLI queries and formats the output, or
|
|
62
|
+
- a `bkper-js` script that resolves dates, loads groups, and renders the tax position in a stable format
|
|
63
|
+
|
|
64
|
+
Prefer the smallest boring solution that is easy to rerun and inspect.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Step 2 — Discover the tax-relevant groups
|
|
69
|
+
|
|
70
|
+
Tax positions are usually derived from **period activity** — revenue, deductible expenses, and tax liability accounts. The specific groups that matter depend on the user's jurisdiction and how they have structured their book.
|
|
71
|
+
|
|
72
|
+
The deterministic engine can work from **aggregated balances** or from **individual transactions**, depending on what the user needs:
|
|
73
|
+
|
|
74
|
+
- **Balance-level** — faster, gives period totals per group/account. Good for computing a tax position or filing summary.
|
|
75
|
+
- **Transaction-level** — slower, gives itemized detail. Good for audit trails, per-transaction deductions, or reconciling tax-account movements.
|
|
76
|
+
|
|
77
|
+
During bootstrap, ask the user which level they need, or default to balance-level and note that transaction-level detail can be added later.
|
|
78
|
+
|
|
79
|
+
Use these commands during bootstrap to identify candidate tax-relevant roots:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
bkper group list -b <bookId> --format csv
|
|
83
|
+
bkper account list -b <bookId> --format csv
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Inspect the output and look for groups or accounts that the user already treats as tax-related. Common patterns include:
|
|
87
|
+
|
|
88
|
+
- A root group or account for **revenue / income** (often INCOMING type)
|
|
89
|
+
- A root group or account for **deductible expenses** (often OUTGOING type)
|
|
90
|
+
- Accounts or groups that track **tax liabilities** or **tax credits** (often LIABILITY or ASSET type)
|
|
91
|
+
|
|
92
|
+
Do **not** assume standard names. Root group names vary by book — examples: `Revenue`, `Income`, `Sales`, `Deductible Expenses`, `Operating Costs`, `Taxes`, `VAT`, `Income Tax`.
|
|
93
|
+
|
|
94
|
+
Ask the user which groups represent their **tax-relevant activity** for the period in question. If they are unsure, propose the smallest set of top-level groups that cover:
|
|
95
|
+
|
|
96
|
+
1. **Gross revenue or income** for the period
|
|
97
|
+
2. **Deductible costs or expenses** for the period
|
|
98
|
+
3. Any **tax liability or credit accounts** already in use
|
|
99
|
+
|
|
100
|
+
When you discover the correct groups, persist them for future runs.
|
|
101
|
+
|
|
102
|
+
Prefer storing the **group IDs** in the local tax config/script. If the execution route also needs group names for query strings, persist the names as well.
|
|
103
|
+
|
|
104
|
+
### If the book has no usable tax-relevant grouping
|
|
105
|
+
|
|
106
|
+
If Step 2 does not reveal clear tax-relevant roots, treat that as a modeling gap, not as permission to improvise one silently.
|
|
107
|
+
|
|
108
|
+
In that case:
|
|
109
|
+
|
|
110
|
+
- explain that the book is **not yet tax-ready** for deterministic reporting
|
|
111
|
+
- do **not** invent arbitrary tax categories from subgroup names or partial account matches
|
|
112
|
+
- inspect the existing account names, language, and reporting style already present in the book
|
|
113
|
+
- propose the **smallest** grouping that fits the user's actual use case and local standards
|
|
114
|
+
- ask approval before creating groups, moving accounts, or persisting the proposed roots
|
|
115
|
+
- once approved, validate the grouping with live queries and then persist it in the local runner/config
|
|
116
|
+
|
|
117
|
+
If the user only wants a quick answer for now, you may still provide an **exploratory / provisional** result, but state clearly that the book still needs an approved tax-relevant hierarchy for future deterministic tax runs.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Step 3 — Fetch data to validate and implement the runner
|
|
122
|
+
|
|
123
|
+
Use these commands during bootstrap to validate the accounting logic and to implement the deterministic runner.
|
|
124
|
+
|
|
125
|
+
Tax positions are period-based — query **activity within a period**, not cumulative position.
|
|
126
|
+
|
|
127
|
+
### Balance-level bootstrap (aggregated)
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Revenue / income activity for the period
|
|
131
|
+
bkper balance list -b <bookId> \
|
|
132
|
+
-q "group:'<revenueRoot>' after:<start> before:<end>" \
|
|
133
|
+
--format csv --expanded 2
|
|
134
|
+
|
|
135
|
+
# Deductible expense activity for the period
|
|
136
|
+
bkper balance list -b <bookId> \
|
|
137
|
+
-q "group:'<expenseRoot>' after:<start> before:<end>" \
|
|
138
|
+
--format csv --expanded 2
|
|
139
|
+
|
|
140
|
+
# Tax liability or credit balance at period end (optional)
|
|
141
|
+
bkper balance list -b <bookId> \
|
|
142
|
+
-q "account:'<taxLiabilityAccount>' before:<end>" \
|
|
143
|
+
--format csv --expanded 2
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Transaction-level bootstrap (itemized)
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Revenue / income transactions for the period
|
|
150
|
+
bkper transaction list -b <bookId> \
|
|
151
|
+
-q "group:'<revenueRoot>' after:<start> before:<end>" \
|
|
152
|
+
--format csv
|
|
153
|
+
|
|
154
|
+
# Deductible expense transactions for the period
|
|
155
|
+
bkper transaction list -b <bookId> \
|
|
156
|
+
-q "group:'<expenseRoot>' after:<start> before:<end>" \
|
|
157
|
+
--format csv
|
|
158
|
+
|
|
159
|
+
# Tax-account movements for the period (optional)
|
|
160
|
+
bkper transaction list -b <bookId> \
|
|
161
|
+
-q "account:'<taxLiabilityAccount>' after:<start> before:<end>" \
|
|
162
|
+
--format csv
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
> **Bootstrap-only flags:** `--format csv` and `--expanded <level>` are conveniences for the discovery phase. CSV is compact for loading into an LLM context to inspect hierarchy structure; `--expanded <level>` reveals sub-totals so you can confirm the group tree is correct. The canonical runner you persist should output whatever format the user actually needs — structured JSON, Markdown tables, plain CSV, or rendered CLI tables — not necessarily the raw CLI dump.
|
|
166
|
+
|
|
167
|
+
Use the output to confirm the correct groups, period totals, and hierarchy before persisting the script/spec.
|
|
168
|
+
|
|
169
|
+
**Do not compute tax owed in the agent's reasoning.** The deterministic runner should output raw period data. The user (or a jurisdiction-specific layer they add later) applies rates, deductions, and rules.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Step 4 — Persist the deterministic route locally
|
|
174
|
+
|
|
175
|
+
After discovery and validation, create or update local artifacts so future requests reuse the same route.
|
|
176
|
+
|
|
177
|
+
Typical artifacts:
|
|
178
|
+
|
|
179
|
+
- `reports/tax-position.sh`
|
|
180
|
+
- `scripts/taxes.ts`
|
|
181
|
+
- `reports/taxes.json`
|
|
182
|
+
- `package.json` scripts such as `report:taxes`
|
|
183
|
+
|
|
184
|
+
Persist the decisions that make the tax run repeatable:
|
|
185
|
+
|
|
186
|
+
- `bookId`
|
|
187
|
+
- tax-relevant group IDs and names
|
|
188
|
+
- query level (balance or transaction)
|
|
189
|
+
- period semantics (e.g., calendar quarter, fiscal year)
|
|
190
|
+
- timezone, if relevant to date boundaries
|
|
191
|
+
- expanded depth for balance queries, if used
|
|
192
|
+
- output format
|
|
193
|
+
|
|
194
|
+
The canonical runner should produce a stable output shape using programmatic formatting — structured JSON, Markdown, rendered tables, or CSV — with clear sections, period labels, and raw totals. Build the report in code (via `bkper-js`, table builders, or the CLI's own render utilities) rather than passing through raw CLI query output. Keep the output **pre-calculation** — expose revenue, expenses, and any tax-account balances so the user can apply their local rules.
|
|
195
|
+
|
|
196
|
+
If helpful, also create or update a local `AGENTS.md` note telling future agent sessions to use the canonical tax script. `AGENTS.md` is **optional persistence**, not a prerequisite for the first request.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Step 5 — Use the script for future requests
|
|
201
|
+
|
|
202
|
+
Once the local tax runner exists:
|
|
203
|
+
|
|
204
|
+
- Use it as the default route for tax position and filing summary requests
|
|
205
|
+
- Resolve relative periods like "last quarter" or "last year" into explicit date boundaries in code/config
|
|
206
|
+
- Keep deterministic tax generation separate from optional AI commentary or filing advice
|
|
207
|
+
- If the tax logic must change (new groups, different period boundaries), update the script/config instead of improvising a fresh one-off route
|
|
208
|
+
|
|
209
|
+
Do not re-decide which groups are tax-relevant on every request.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## One-off exploratory fallback
|
|
214
|
+
|
|
215
|
+
If the user explicitly does **not** want to create the script now and only wants a quick one-off answer, you may run live queries directly.
|
|
216
|
+
|
|
217
|
+
In that case:
|
|
218
|
+
|
|
219
|
+
- Clearly label the result as **exploratory / provisional**
|
|
220
|
+
- State that it is **not yet** the canonical deterministic tax route for the project
|
|
221
|
+
- Recommend persisting a local script/config if the user wants repeatable tax output in future requests
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Date patterns
|
|
226
|
+
|
|
227
|
+
Use these patterns when validating or implementing the deterministic runner.
|
|
228
|
+
|
|
229
|
+
| Request | Period activity query |
|
|
230
|
+
| -------------- | ---------------------------------------------- |
|
|
231
|
+
| Current month | `after:$m-1 before:$m` |
|
|
232
|
+
| Current year | `after:$y-1 before:$y` |
|
|
233
|
+
| Full year 2024 | `after:2024-01-01 before:2025-01-01` |
|
|
234
|
+
| Last quarter | Resolve to explicit `after:<start> before:<end>` in script |
|
|
235
|
+
|
|
236
|
+
- `after:` is **inclusive**, `before:` is **exclusive**
|
|
237
|
+
- `$d` = today, `$m` = current month-end, `$y` = current year-end
|
|
238
|
+
- In shell, wrap queries containing `$` variables in **single quotes** to prevent shell expansion
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Key rules
|
|
243
|
+
|
|
244
|
+
- **The agent orchestrates the engine; the engine produces the output** — the canonical runner is what generates the tax report, not the agent's direct reasoning
|
|
245
|
+
- **Tax positions are period-based** — use `after:` + `before:` for revenue and expense activity, not `before:` alone
|
|
246
|
+
- **Always query by group or account** — never run unfiltered queries across the whole book
|
|
247
|
+
- **Output raw data, not computed tax owed** — the deterministic runner exposes totals; jurisdiction-specific calculation is a user concern
|
|
248
|
+
- **Bootstrap queries** may use `--format csv` and `--expanded <level>` to inspect hierarchy structure efficiently; the canonical runner should use programmatic formatting suited to the end user
|
|
249
|
+
- Once a canonical local tax route exists, **reuse it instead of rediscovering the logic**
|
|
250
|
+
- Prefer persisting tax-relevant group decisions in code/config rather than relying on session memory
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Common mistakes
|
|
255
|
+
|
|
256
|
+
| Wrong | Right |
|
|
257
|
+
| --- | --- |
|
|
258
|
+
| The agent computing tax owed directly from queried data using guessed rates or rules | The agent building or reusing a local runner that outputs raw data; the user applies jurisdiction-specific rules |
|
|
259
|
+
| Immediately running ad-hoc queries as the default response to a first tax request | First look for a local runner; if none exists, propose creating one and use queries only for bootstrap |
|
|
260
|
+
| Assuming `AGENTS.md` must already exist | `AGENTS.md` can be created or updated during bootstrap to route future requests |
|
|
261
|
+
| Using `before:` only for tax-relevant queries | Use `after:` + `before:` for period-based activity (revenue, expenses) |
|
|
262
|
+
| Inventing a new tax hierarchy silently because no roots were found | Explain that the book is not yet tax-ready, propose a minimal grouping aligned with the user's language and local standards, and ask approval before changing structure |
|
|
263
|
+
| Re-interpreting "last quarter" differently each time | Resolve relative periods into explicit dates inside the canonical script/config |
|
|
264
|
+
| Mixing tax-bot specifics into the generic tax workflow | Keep this workflow independent of any bot or automation; it works from plain balances and transactions |
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a local file from disk and returns a Bkper File payload.
|
|
3
|
+
*
|
|
4
|
+
* The payload preserves the local basename as the file name and encodes the
|
|
5
|
+
* content as base64, ready to be passed to `new File(book, payload)`.
|
|
6
|
+
*
|
|
7
|
+
* @param localPath - Local filesystem path
|
|
8
|
+
* @returns File payload suitable for Bkper uploads
|
|
9
|
+
*/
|
|
10
|
+
export declare function readLocalFilePayload(localPath: string): Promise<bkper.File>;
|
|
11
|
+
//# sourceMappingURL=local-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-file.d.ts","sourceRoot":"","sources":["../../src/utils/local-file.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAgCjF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
11
|
+
import mime from 'mime';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
/**
|
|
14
|
+
* Reads a local file from disk and returns a Bkper File payload.
|
|
15
|
+
*
|
|
16
|
+
* The payload preserves the local basename as the file name and encodes the
|
|
17
|
+
* content as base64, ready to be passed to `new File(book, payload)`.
|
|
18
|
+
*
|
|
19
|
+
* @param localPath - Local filesystem path
|
|
20
|
+
* @returns File payload suitable for Bkper uploads
|
|
21
|
+
*/
|
|
22
|
+
export function readLocalFilePayload(localPath) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
let fileStats;
|
|
25
|
+
try {
|
|
26
|
+
fileStats = yield stat(localPath);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
const error = err;
|
|
30
|
+
if (error.code === 'ENOENT') {
|
|
31
|
+
throw new Error(`Local file not found: ${localPath}`);
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Local file is not readable: ${localPath}`);
|
|
34
|
+
}
|
|
35
|
+
if (!fileStats.isFile()) {
|
|
36
|
+
throw new Error(`Local path is not a regular file: ${localPath}`);
|
|
37
|
+
}
|
|
38
|
+
let content;
|
|
39
|
+
try {
|
|
40
|
+
content = yield readFile(localPath);
|
|
41
|
+
}
|
|
42
|
+
catch (_a) {
|
|
43
|
+
throw new Error(`Local file is not readable: ${localPath}`);
|
|
44
|
+
}
|
|
45
|
+
const contentType = mime.getType(localPath);
|
|
46
|
+
return {
|
|
47
|
+
createdAt: `${Date.now()}`,
|
|
48
|
+
name: path.basename(localPath),
|
|
49
|
+
contentType: contentType || undefined,
|
|
50
|
+
size: fileStats.size,
|
|
51
|
+
content: content.toString('base64'),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=local-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-file.js","sourceRoot":"","sources":["../../src/utils/local-file.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,UAAgB,oBAAoB,CAAC,SAAiB;;QACxD,IAAI,SAAS,CAAC;QACd,IAAI,CAAC;YACD,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,GAA4B,CAAC;YAC3C,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;YAC1D,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,qCAAqC,SAAS,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACD,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;QAAC,WAAM,CAAC;YACL,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE5C,OAAO;YACH,SAAS,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE;YAC1B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC9B,WAAW,EAAE,WAAW,IAAI,SAAS;YACrC,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;SACtC,CAAC;IACN,CAAC;CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bkper",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.13.0",
|
|
4
4
|
"description": "Command line client for Bkper",
|
|
5
5
|
"bin": {
|
|
6
6
|
"bkper": "./lib/cli.js"
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"dotenv": "^8.2.0",
|
|
59
59
|
"esbuild": "^0.27.2",
|
|
60
60
|
"google-auth-library": "^10.5.0",
|
|
61
|
+
"mime": "^4.1.0",
|
|
61
62
|
"open": "^10.1.0",
|
|
62
63
|
"openapi-fetch": "^0.15.0",
|
|
63
64
|
"tar": "^7.0.0",
|