@fuzzle/opencode-accountant 0.0.9 → 0.0.10-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 +51 -9
- package/agent/accountant.md +31 -23
- package/dist/index.js +1198 -6
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -97,6 +97,7 @@ paths:
|
|
|
97
97
|
pending: doc/agent/todo/import
|
|
98
98
|
done: doc/agent/done/import
|
|
99
99
|
unrecognized: statements/import/unrecognized
|
|
100
|
+
rules: ledger/rules
|
|
100
101
|
|
|
101
102
|
providers:
|
|
102
103
|
revolut:
|
|
@@ -115,13 +116,15 @@ providers:
|
|
|
115
116
|
|
|
116
117
|
ubs:
|
|
117
118
|
detect:
|
|
118
|
-
|
|
119
|
+
# Note: UBS exports have a trailing semicolon in the header row, which creates
|
|
120
|
+
# an empty field when parsed. The header must include a trailing comma to match.
|
|
121
|
+
- header: 'Trade date,Trade time,Booking date,Value date,Currency,Debit,Credit,Individual amount,Balance,Transaction no.,Description1,Description2,Description3,Footnotes,'
|
|
119
122
|
currencyField: Currency
|
|
120
123
|
skipRows: 9
|
|
121
124
|
delimiter: ';'
|
|
122
|
-
renamePattern: 'transactions-ubs-{
|
|
125
|
+
renamePattern: 'transactions-ubs-{account-number}.csv'
|
|
123
126
|
metadata:
|
|
124
|
-
- field:
|
|
127
|
+
- field: account-number
|
|
125
128
|
row: 0
|
|
126
129
|
column: 1
|
|
127
130
|
normalize: spaces-to-dashes
|
|
@@ -141,13 +144,14 @@ providers:
|
|
|
141
144
|
| `pending` | Base path for classified files awaiting import |
|
|
142
145
|
| `done` | Base path for archived files after import |
|
|
143
146
|
| `unrecognized` | Directory for files that couldn't be classified |
|
|
147
|
+
| `rules` | Directory containing hledger `.rules` files |
|
|
144
148
|
|
|
145
149
|
**Provider Detection Rules:**
|
|
146
150
|
|
|
147
151
|
| Field | Required | Description |
|
|
148
152
|
| ----------------- | -------- | ---------------------------------------------------------- |
|
|
149
153
|
| `filenamePattern` | No | Regex pattern to match against filename |
|
|
150
|
-
| `header` | Yes | Expected CSV header row (exact match)
|
|
154
|
+
| `header` | Yes | Expected CSV header row (comma-separated, exact match)\* |
|
|
151
155
|
| `currencyField` | Yes | Column name containing the currency/symbol |
|
|
152
156
|
| `skipRows` | No | Number of rows to skip before header (default: 0) |
|
|
153
157
|
| `delimiter` | No | CSV delimiter character (default: `,`) |
|
|
@@ -155,6 +159,8 @@ providers:
|
|
|
155
159
|
| `metadata` | No | Array of metadata extraction rules (see below) |
|
|
156
160
|
| `currencies` | Yes | Map of raw currency values to normalized folder names |
|
|
157
161
|
|
|
162
|
+
\* **Note on trailing delimiters:** If the CSV header row ends with a trailing delimiter (e.g., `Field1;Field2;`), this creates an empty field when parsed. The `header` config must include a trailing comma to account for this (e.g., `Field1,Field2,`).
|
|
163
|
+
|
|
158
164
|
**Metadata Extraction Rules:**
|
|
159
165
|
|
|
160
166
|
| Field | Required | Description |
|
|
@@ -171,15 +177,18 @@ your-project/
|
|
|
171
177
|
├── config/
|
|
172
178
|
│ └── import/
|
|
173
179
|
│ └── providers.yaml
|
|
180
|
+
├── ledger/
|
|
181
|
+
│ └── rules/ # hledger rules files
|
|
182
|
+
│ └── <provider>-{account-number}.rules # {account-number} from metadata extraction
|
|
174
183
|
├── statements/
|
|
175
|
-
│ └── import/
|
|
176
|
-
│ └── unrecognized/
|
|
184
|
+
│ └── import/ # Drop CSV files here
|
|
185
|
+
│ └── unrecognized/ # Unclassified files moved here
|
|
177
186
|
└── doc/
|
|
178
187
|
└── agent/
|
|
179
188
|
├── todo/
|
|
180
189
|
│ └── import/
|
|
181
|
-
│ └── <provider>/
|
|
182
|
-
│ └── <currency>/
|
|
190
|
+
│ └── <provider>/ # e.g. revolut
|
|
191
|
+
│ └── <currency>/ # e.g. chf, eur, usd, btc
|
|
183
192
|
└── done/
|
|
184
193
|
└── import/
|
|
185
194
|
└── <provider>/
|
|
@@ -192,7 +201,40 @@ your-project/
|
|
|
192
201
|
2. Run `classify-statements` tool
|
|
193
202
|
3. Files are moved to `doc/agent/todo/import/<provider>/<currency>/`
|
|
194
203
|
4. Unrecognized files are moved to `statements/import/unrecognized/`
|
|
195
|
-
5.
|
|
204
|
+
5. Run `import-statements` with `checkOnly: true` to validate transactions
|
|
205
|
+
6. If unknown postings found: Add rules to the `.rules` file, repeat step 5
|
|
206
|
+
7. Once all transactions match: Run `import-statements` with `checkOnly: false`
|
|
207
|
+
8. Transactions are imported to journal, CSV files moved to `doc/agent/done/import/`
|
|
208
|
+
|
|
209
|
+
### Statement Import
|
|
210
|
+
|
|
211
|
+
The `import-statements` tool imports classified CSV statements into hledger using rules files. It validates transactions before import and identifies any that cannot be categorized.
|
|
212
|
+
|
|
213
|
+
#### Tool Arguments
|
|
214
|
+
|
|
215
|
+
| Argument | Type | Default | Description |
|
|
216
|
+
| ----------- | ------- | ------- | ------------------------------------------- |
|
|
217
|
+
| `provider` | string | - | Filter by provider (e.g., `revolut`, `ubs`) |
|
|
218
|
+
| `currency` | string | - | Filter by currency (e.g., `chf`, `eur`) |
|
|
219
|
+
| `checkOnly` | boolean | `true` | If true, only validate without importing |
|
|
220
|
+
|
|
221
|
+
#### Rules File Matching
|
|
222
|
+
|
|
223
|
+
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:
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
source ../../doc/agent/todo/import/ubs/chf/transactions.csv
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The tool will use that rules file when processing `transactions.csv`.
|
|
230
|
+
|
|
231
|
+
See the hledger documentation for details on rules file format and syntax.
|
|
232
|
+
|
|
233
|
+
#### Unknown Postings
|
|
234
|
+
|
|
235
|
+
When a transaction doesn't match any `if` pattern in the rules file, hledger assigns it to `income:unknown` or `expenses:unknown` depending on the transaction direction. The tool reports these so you can add appropriate rules.
|
|
236
|
+
|
|
237
|
+
For detailed output format examples, see [`docs/tools/import-statements.md`](docs/tools/import-statements.md).
|
|
196
238
|
|
|
197
239
|
## Development
|
|
198
240
|
|
package/agent/accountant.md
CHANGED
|
@@ -3,13 +3,13 @@ description: Specialized agent for hledger accounting tasks and transaction mana
|
|
|
3
3
|
prompt: You are an accounting specialist with expertise in hledger and double-entry bookkeeping. Your role is to help maintain accurate financial records following the user's conventions.
|
|
4
4
|
mode: subagent
|
|
5
5
|
temperature: 0.1
|
|
6
|
-
steps:
|
|
6
|
+
steps: 8
|
|
7
7
|
tools:
|
|
8
|
-
bash:
|
|
8
|
+
bash: true
|
|
9
9
|
edit: true
|
|
10
10
|
write: true
|
|
11
11
|
permission:
|
|
12
|
-
bash:
|
|
12
|
+
bash: allow
|
|
13
13
|
edit: allow
|
|
14
14
|
glob: allow
|
|
15
15
|
grep: allow
|
|
@@ -19,30 +19,24 @@ permission:
|
|
|
19
19
|
todoread: allow
|
|
20
20
|
todowrite: allow
|
|
21
21
|
webfetch: deny
|
|
22
|
-
write: allow
|
|
22
|
+
write: allow
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
## Repository Structure
|
|
26
26
|
|
|
27
|
-
- `.hledger.journal` - Global hledger journal file
|
|
27
|
+
- `.hledger.journal` - Global hledger journal file
|
|
28
28
|
- `ledger/` - All ledger related files are stored here
|
|
29
29
|
- `ledger/currencies/` - Currency exchange rate files
|
|
30
30
|
- `ledger/YYYY.journal` - Annual hledger journal files
|
|
31
|
+
- `ledger/rules` - hledger rules files
|
|
31
32
|
- `statements/` - Bank and broker account statements
|
|
32
33
|
- `statements/import` - Upload folder for new statements to process
|
|
33
|
-
- `statements/provider/YYYY` -
|
|
34
|
-
- `doc/agent/todo/` -
|
|
34
|
+
- `statements/{provider}/YYYY` - Processed statements organized by source and year
|
|
35
|
+
- `doc/agent/todo/` - Agent's task work directory
|
|
35
36
|
- `doc/agent/done/` - Tasks completed by the agent
|
|
36
37
|
- `config/conventions/` - Accounting conventions
|
|
37
38
|
- `config/rules/` - import rules files
|
|
38
39
|
|
|
39
|
-
## System Environment
|
|
40
|
-
|
|
41
|
-
**Required for accounting tasks:**
|
|
42
|
-
|
|
43
|
-
- `pricehist` - Price data fetching
|
|
44
|
-
- `hledger`, `hledger-fmt` - Accounting operations
|
|
45
|
-
|
|
46
40
|
## Conventions & Workflow
|
|
47
41
|
|
|
48
42
|
All account conventions, conversion patterns (currency, crypto, equity postings), transaction status management, import
|
|
@@ -59,15 +53,29 @@ When working with accounting tasks:
|
|
|
59
53
|
1. **File organization** - Keep transactions in appropriate year journals
|
|
60
54
|
1. **Duplicate checking** - Take extra care to avoid duplicate transactions
|
|
61
55
|
1. **Unintended edits** - If a balance is off, check the journal for unintended edits
|
|
62
|
-
1. **Statement tracking** - Move processed statements to `statements/provider/YYYY`
|
|
56
|
+
1. **Statement tracking** - Move processed statements to `statements/{provider}/YYYY`
|
|
57
|
+
1. **Consistency** - Maintain consistent formatting and naming conventions across all files
|
|
58
|
+
|
|
59
|
+
## Statement Import Workflow
|
|
60
|
+
|
|
61
|
+
Use the `import-statements` tool to import bank statements. The workflow:
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
1. **Prepare**: Drop CSV files into `statements/import/`
|
|
64
|
+
2. **Classify**: Run `classify-statements` tool to move files to `doc/agent/todo/import/<provider>/<currency>/`
|
|
65
|
+
3. **Validate (check mode)**: Run `import-statements(checkOnly: true)` to validate transactions
|
|
66
|
+
- Tool runs `hledger print` dry run to check for unknown postings
|
|
67
|
+
- Unknown postings appear as `income:unknown` or `expenses:unknown`
|
|
68
|
+
4. **Handle unknowns**: If unknown postings found:
|
|
69
|
+
- Tool returns full CSV row data for each unknown posting
|
|
70
|
+
- Analyze the CSV row data to understand the transaction
|
|
71
|
+
- Create or update rules file with `if` directives to match the transaction
|
|
72
|
+
- Repeat step 3 until all postings are matched
|
|
73
|
+
5. **Import**: Once all transactions have matching rules, run `import-statements(checkOnly: false)`
|
|
74
|
+
6. **Complete**: Transactions imported to journal, CSVs moved to `doc/agent/done/import/`
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
- Processing crypto purchases and transfers
|
|
68
|
-
- Currency conversions between CHF/EUR/USD
|
|
69
|
-
- Validating journal integrity
|
|
70
|
-
- Generating balance reports
|
|
71
|
-
- Correcting malformed transactions
|
|
76
|
+
### Rules Files
|
|
72
77
|
|
|
73
|
-
|
|
78
|
+
- Rules files are in `config/rules/` directory
|
|
79
|
+
- Match CSV to rules file via the `source` directive in each `.rules` file
|
|
80
|
+
- Use field names from the `fields` directive for matching
|
|
81
|
+
- Unknown account pattern: `income:unknown` (positive amounts) / `expenses:unknown` (negative amounts)
|