@fuzzle/opencode-accountant 0.4.6 → 0.5.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.
@@ -18,6 +18,8 @@ This tool is **restricted to the accountant agent only**.
18
18
  - `{paths.pending}` = `import/pending`
19
19
  - `{paths.unrecognized}` = `import/unrecognized`
20
20
 
21
+ **Note on Context IDs:** Each classified file receives a unique `contextId` (UUID). This ID references an import context file stored in `.memory/{uuid}.json` that tracks the file's metadata and progress through the import pipeline. The context is used by subsequent tools (`import-statements`, `reconcile-statement`) to locate files and retrieve metadata. See [Import Context Architecture](../architecture/import-context.md) for details.
22
+
21
23
  ### Success - All Files Classified
22
24
 
23
25
  When all CSV files are successfully classified:
@@ -30,13 +32,15 @@ When all CSV files are successfully classified:
30
32
  "filename": "transactions-ubs-2026-02.csv",
31
33
  "provider": "ubs",
32
34
  "currency": "chf",
33
- "targetPath": "{paths.pending}/ubs/chf/transactions-ubs-2026-02.csv"
35
+ "targetPath": "{paths.pending}/ubs/chf/transactions-ubs-2026-02.csv",
36
+ "contextId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
34
37
  },
35
38
  {
36
39
  "filename": "account-statement_2026-02.csv",
37
40
  "provider": "revolut",
38
41
  "currency": "eur",
39
- "targetPath": "{paths.pending}/revolut/eur/account-statement_2026-02.csv"
42
+ "targetPath": "{paths.pending}/revolut/eur/account-statement_2026-02.csv",
43
+ "contextId": "8b3e9c21-1a4f-4d89-b123-9f8e7d6c5b4a"
40
44
  }
41
45
  ],
42
46
  "unrecognized": [],
@@ -61,7 +65,8 @@ When provider config includes `renamePattern` with metadata extraction:
61
65
  "originalFilename": "export.csv",
62
66
  "provider": "ubs",
63
67
  "currency": "chf",
64
- "targetPath": "{paths.pending}/ubs/chf/transactions-ubs-0235-90250546.csv"
68
+ "targetPath": "{paths.pending}/ubs/chf/transactions-ubs-0235-90250546.csv",
69
+ "contextId": "a1b2c3d4-5e6f-7g8h-9i0j-k1l2m3n4o5p6"
65
70
  }
66
71
  ],
67
72
  "unrecognized": [],
@@ -87,7 +92,8 @@ When some files cannot be classified:
87
92
  "filename": "transactions-ubs-2026-02.csv",
88
93
  "provider": "ubs",
89
94
  "currency": "chf",
90
- "targetPath": "{paths.pending}/ubs/chf/transactions-ubs-2026-02.csv"
95
+ "targetPath": "{paths.pending}/ubs/chf/transactions-ubs-2026-02.csv",
96
+ "contextId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
91
97
  }
92
98
  ],
93
99
  "unrecognized": [
@@ -207,13 +213,74 @@ ubs:
207
213
 
208
214
  This extracts metadata from the CSV (e.g., account number from row 0, column 1) and uses it in the output filename.
209
215
 
216
+ ## Import Context
217
+
218
+ Each classified file gets an **import context** - a JSON file stored in `.memory/{contextId}.json` that tracks the file's metadata and progress through the import pipeline.
219
+
220
+ ### What Gets Stored in the Context
221
+
222
+ When a CSV is classified, the context is created with:
223
+
224
+ - **File tracking**: filename, file path, original filename (if renamed)
225
+ - **Provider detection**: provider, currency, account number
226
+ - **CSV metadata**: transaction date range (from-date, until-date), opening/closing balances
227
+ - **Timestamps**: creation and last update times
228
+
229
+ ### Example Context File
230
+
231
+ `.memory/f47ac10b-58cc-4372-a567-0e02b2c3d479.json`:
232
+
233
+ ```json
234
+ {
235
+ "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
236
+ "createdAt": "2026-02-28T10:30:00.000Z",
237
+ "updatedAt": "2026-02-28T10:30:00.000Z",
238
+
239
+ "filename": "ubs-0235-90250546.1-transactions-2026-02-22-to-2026-02-24.csv",
240
+ "filePath": "import/pending/ubs/chf/ubs-0235-90250546.1-transactions-2026-02-22-to-2026-02-24.csv",
241
+ "originalFilename": "transactions-0235-90250546.1-2026-02.csv",
242
+
243
+ "provider": "ubs",
244
+ "currency": "chf",
245
+ "accountNumber": "0235-90250546.1",
246
+
247
+ "fromDate": "2026-02-22",
248
+ "untilDate": "2026-02-24",
249
+ "openingBalance": "4001.55",
250
+ "closingBalance": "9001.55"
251
+ }
252
+ ```
253
+
254
+ ### Context Lifecycle
255
+
256
+ 1. **Created by classify-statements**: Initial context with provider/currency/metadata
257
+ 2. **Updated by import-statements**: Adds rules file, year journal, transaction count
258
+ 3. **Updated by reconcile-statement**: Adds reconciliation results
259
+ 4. **Persisted**: Remains in `.memory/` for audit/debugging
260
+
261
+ ### Why Context IDs Matter
262
+
263
+ Context IDs solve the **multi-account problem**: when you have multiple accounts from the same provider/currency (e.g., UBS checking `.0` and savings `.1`), the context ID ensures each file is tracked independently and reconciled against the correct account.
264
+
265
+ **Without contexts**: Tools would select CSVs by timestamp → wrong account reconciled ❌
266
+
267
+ **With contexts**: Each CSV has an `accountNumber` in its context → correct account reconciled ✓
268
+
269
+ See [Import Context Architecture](../architecture/import-context.md) for complete technical details.
270
+
210
271
  ## Directory Structure
211
272
 
212
273
  ```
213
274
  your-project/
275
+ ├── .memory/ # Import context files (created by classify-statements)
276
+ │ ├── f47ac10b-58cc-4372-a567-0e02b2c3d479.json # Context for UBS checking
277
+ │ ├── 8b3e9c21-1a4f-4d89-b123-9f8e7d6c5b4a.json # Context for UBS savings
278
+ │ └── a1b2c3d4-5e6f-7g8h-9i0j-k1l2m3n4o5p6.json # Context for Revolut EUR
279
+
214
280
  ├── config/
215
281
  │ └── import/
216
282
  │ └── providers.yaml # Defines all paths and detection rules
283
+
217
284
  ├── {paths.import}/ # Drop CSV files here (default: import/incoming)
218
285
  │ ├── bank1.csv
219
286
  │ └── bank2.csv
@@ -224,7 +291,8 @@ your-project/
224
291
  │ │ └── classified.csv
225
292
  │ ├── ubs/
226
293
  │ │ └── chf/
227
- │ │ └── transactions-ubs-0235-90250546.csv
294
+ │ │ ├── ubs-0235-90250546.0-transactions-2026-02.csv # Checking
295
+ │ │ └── ubs-0235-90250546.1-transactions-2026-02.csv # Savings
228
296
  │ └── revolut/
229
297
  │ └── eur/
230
298
  │ └── account-statement_2026-02.csv
@@ -233,6 +301,13 @@ your-project/
233
301
  └── mystery-bank.csv
234
302
  ```
235
303
 
304
+ **Note on `.memory/` directory:**
305
+
306
+ - Contains import context JSON files (one per classified CSV)
307
+ - Each context tracks metadata and progress through the pipeline
308
+ - Files persist for audit/debugging (not auto-deleted)
309
+ - Directory is gitignored (contexts are local/temporary)
310
+
236
311
  ## Typical Workflow
237
312
 
238
313
  ### Scenario 1: Successful Classification
@@ -240,8 +315,10 @@ your-project/
240
315
  1. Drop CSV files into `{paths.import}/` (e.g., `import/incoming/`)
241
316
  2. Run `classify-statements` tool (no arguments)
242
317
  3. Check output - all files classified successfully
243
- 4. Files organized in `{paths.pending}/<provider>/<currency>/`
244
- 5. Proceed to `import-statements` tool
318
+ 4. **Each file gets a unique contextId** stored in `.memory/{uuid}.json`
319
+ 5. Files organized in `{paths.pending}/<provider>/<currency>/`
320
+ 6. **Context IDs are passed automatically to subsequent steps** when using `import-pipeline`
321
+ 7. Proceed to `import-statements` or `import-pipeline` tool
245
322
 
246
323
  ### Scenario 2: Handling Unrecognized Files
247
324