@fuzzle/opencode-accountant 0.3.0-next.1 → 0.4.0-next.1

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 CHANGED
@@ -122,12 +122,21 @@ providers:
122
122
  currencyField: Currency
123
123
  skipRows: 9
124
124
  delimiter: ';'
125
- renamePattern: 'transactions-ubs-{account-number}.csv'
125
+ renamePattern: 'ubs-{account-number}-transactions-{from-date}-to-{until-date}.csv'
126
126
  metadata:
127
127
  - field: account-number
128
128
  row: 0
129
129
  column: 1
130
130
  normalize: spaces-to-dashes
131
+ - field: from-date
132
+ row: 2
133
+ column: 1
134
+ - field: until-date
135
+ row: 3
136
+ column: 1
137
+ - field: closing-balance
138
+ row: 5
139
+ column: 1
131
140
  currencies:
132
141
  CHF: chf
133
142
  EUR: eur
@@ -226,7 +235,14 @@ The `import-pipeline` tool is the single entry point for importing bank statemen
226
235
 
227
236
  #### Rules File Matching
228
237
 
229
- The tool matches CSV files to their rules files by parsing the `source` directive in each `.rules` file. For example, if `ubs-account.rules` contains:
238
+ The tool matches CSV files to their rules files using multiple methods:
239
+
240
+ 1. **Source directive matching** (primary): Parses the `source` directive in each `.rules` file and supports glob patterns
241
+ 2. **Filename matching** (fallback): If path matching fails, matches based on the rules filename prefix
242
+
243
+ **Example using source directive:**
244
+
245
+ If `ubs-account.rules` contains:
230
246
 
231
247
  ```
232
248
  source ../../import/pending/ubs/chf/transactions.csv
@@ -234,7 +250,13 @@ source ../../import/pending/ubs/chf/transactions.csv
234
250
 
235
251
  The tool will use that rules file when processing `transactions.csv`.
236
252
 
237
- **Note:** The `source` path should match your configured `{paths.pending}` directory structure.
253
+ **Example using filename matching:**
254
+
255
+ If you have a rules file named `ubs-1234-567890.rules` and a CSV file named `ubs-1234-567890-transactions-2026-01-05-to-2026-01-31.csv`, the tool will automatically match them based on the common prefix `ubs-1234-567890`.
256
+
257
+ This is particularly useful when CSV files move between directories (e.g., from `pending/` to `done/`) or when maintaining exact source paths is impractical.
258
+
259
+ **Note:** Name your rules files to match the prefix of your CSV files for automatic matching.
238
260
 
239
261
  See the hledger documentation for details on rules file format and syntax.
240
262
 
@@ -265,13 +287,13 @@ Configure metadata extraction in `providers.yaml`:
265
287
 
266
288
  ```yaml
267
289
  metadata:
268
- - field: closing_balance
290
+ - field: closing-balance
269
291
  row: 5
270
292
  column: 1
271
- - field: from_date
293
+ - field: from-date
272
294
  row: 2
273
295
  column: 1
274
- - field: until_date
296
+ - field: until-date
275
297
  row: 3
276
298
  column: 1
277
299
  ```
@@ -105,7 +105,9 @@ The `import-pipeline` tool provides an **atomic, safe workflow** using git workt
105
105
  ### Rules Files
106
106
 
107
107
  - The location of the rules files is configured in `config/import/providers.yaml`
108
- - Match CSV to rules file via the `source` directive in each `.rules` file
108
+ - Match CSV to rules file via the `source` directive in each `.rules` file, with automatic fallback to filename-based matching
109
+ - **Filename matching example:** If the rules file is named `ubs-1234-567890.rules`, it will automatically match CSV files like `ubs-1234-567890-transactions-2026-01.csv` based on the common prefix. This works even when CSV files move between directories.
110
+ - When account detection fails, recommend users either fix their `source` directive or rename their rules file to match the CSV filename prefix
109
111
  - Use field names from the `fields` directive for matching
110
112
  - Unknown account pattern: `income:unknown` (positive amounts) / `expenses:unknown` (negative amounts)
111
113
 
package/dist/index.js CHANGED
@@ -23458,6 +23458,18 @@ function findRulesForCsv(csvPath, mapping) {
23458
23458
  return rulesFile;
23459
23459
  }
23460
23460
  }
23461
+ const csvBasename = path9.basename(csvPath);
23462
+ const matches = [];
23463
+ for (const rulesFile of Object.values(mapping)) {
23464
+ const rulesBasename = path9.basename(rulesFile, ".rules");
23465
+ if (csvBasename.startsWith(rulesBasename)) {
23466
+ matches.push({ rulesFile, prefixLength: rulesBasename.length });
23467
+ }
23468
+ }
23469
+ if (matches.length > 0) {
23470
+ matches.sort((a, b) => b.prefixLength - a.prefixLength);
23471
+ return matches[0].rulesFile;
23472
+ }
23461
23473
  return null;
23462
23474
  }
23463
23475
 
@@ -24240,10 +24252,11 @@ function determineClosingBalance(csvFile, config2, options, relativeCsvPath, rul
24240
24252
  metadata = undefined;
24241
24253
  }
24242
24254
  let closingBalance = options.closingBalance;
24243
- if (!closingBalance && metadata?.closing_balance) {
24244
- const { closing_balance, currency } = metadata;
24245
- closingBalance = closing_balance;
24246
- if (currency && !closingBalance.includes(currency)) {
24255
+ if (!closingBalance && metadata?.["closing-balance"]) {
24256
+ const closingBalanceValue = metadata["closing-balance"];
24257
+ const currency = metadata.currency;
24258
+ closingBalance = closingBalanceValue;
24259
+ if (currency && closingBalance && !closingBalance.includes(currency)) {
24247
24260
  closingBalance = `${currency} ${closingBalance}`;
24248
24261
  }
24249
24262
  }
@@ -24324,7 +24337,7 @@ function tryExtractClosingBalanceFromCSV(csvFile, rulesDir) {
24324
24337
  "balance",
24325
24338
  "Balance",
24326
24339
  "BALANCE",
24327
- "closing_balance",
24340
+ "closing-balance",
24328
24341
  "Closing Balance",
24329
24342
  "account_balance",
24330
24343
  "Account Balance",
@@ -24875,8 +24888,8 @@ async function executeMergeStep(context, worktree) {
24875
24888
  throw new Error("Import or reconcile step not completed before merge");
24876
24889
  }
24877
24890
  const commitInfo = {
24878
- fromDate: reconcileDetails.metadata?.from_date,
24879
- untilDate: reconcileDetails.metadata?.until_date
24891
+ fromDate: reconcileDetails.metadata?.["from-date"],
24892
+ untilDate: reconcileDetails.metadata?.["until-date"]
24880
24893
  };
24881
24894
  const transactionCount = importDetails.summary?.totalTransactions || 0;
24882
24895
  const commitMessage = buildCommitMessage(context.options.provider, context.options.currency, commitInfo.fromDate, commitInfo.untilDate, transactionCount);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzzle/opencode-accountant",
3
- "version": "0.3.0-next.1",
3
+ "version": "0.4.0-next.1",
4
4
  "description": "An OpenCode accounting agent, specialized in double-entry-bookkepping with hledger",
5
5
  "author": {
6
6
  "name": "ali bengali",