@dizzlkheinz/ynab-mcpb 0.17.0 → 0.18.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/.env.example +33 -33
- package/.github/workflows/ci-tests.yml +45 -45
- package/.github/workflows/claude-code-review.yml +57 -57
- package/.github/workflows/claude.yml +50 -50
- package/.github/workflows/full-integration.yml +22 -22
- package/.github/workflows/publish.yml +12 -3
- package/.github/workflows/release.yml +2 -2
- package/CHANGELOG.md +10 -1
- package/CLAUDE.md +16 -12
- package/README.md +6 -1
- package/dist/bundle/index.cjs +49 -49
- package/dist/server/YNABMCPServer.d.ts +125 -54
- package/dist/server/YNABMCPServer.js +42 -11
- package/dist/server/cacheManager.js +6 -5
- package/dist/server/completions.d.ts +25 -0
- package/dist/server/completions.js +160 -0
- package/dist/server/config.d.ts +2 -2
- package/dist/server/errorHandler.js +1 -0
- package/dist/server/rateLimiter.js +3 -1
- package/dist/server/resources.d.ts +1 -0
- package/dist/server/resources.js +33 -16
- package/dist/server/securityMiddleware.d.ts +38 -8
- package/dist/server/securityMiddleware.js +1 -0
- package/dist/server/toolRegistry.d.ts +9 -0
- package/dist/server/toolRegistry.js +11 -0
- package/dist/tools/adapters.d.ts +3 -1
- package/dist/tools/adapters.js +1 -0
- package/dist/tools/reconciliation/executor.d.ts +2 -0
- package/dist/tools/reconciliation/executor.js +26 -1
- package/dist/tools/reconciliation/index.d.ts +3 -2
- package/dist/tools/reconciliation/index.js +4 -3
- package/dist/tools/schemas/outputs/index.d.ts +2 -2
- package/dist/tools/schemas/outputs/index.js +2 -2
- package/dist/tools/schemas/outputs/utilityOutputs.d.ts +0 -15
- package/dist/tools/schemas/outputs/utilityOutputs.js +0 -9
- package/dist/tools/utilityTools.d.ts +0 -7
- package/dist/tools/utilityTools.js +1 -50
- package/docs/maintainers/npm-publishing.md +27 -0
- package/docs/reference/API.md +83 -97
- package/docs/technical/reconciliation-system-architecture.md +2251 -2251
- package/package.json +6 -6
- package/scripts/analyze-bundle.mjs +41 -41
- package/scripts/generate-mcpb.ps1 +95 -95
- package/scripts/watch-and-restart.ps1 +49 -49
- package/src/__tests__/comprehensive.integration.test.ts +4 -32
- package/src/__tests__/performance.test.ts +5 -14
- package/src/__tests__/setup.ts +45 -14
- package/src/__tests__/smoke.e2e.test.ts +70 -0
- package/src/__tests__/testUtils.ts +2 -113
- package/src/server/YNABMCPServer.ts +64 -10
- package/src/server/__tests__/YNABMCPServer.test.ts +0 -1
- package/src/server/__tests__/completions.integration.test.ts +117 -0
- package/src/server/__tests__/completions.test.ts +319 -0
- package/src/server/__tests__/resources.template.test.ts +3 -3
- package/src/server/__tests__/resources.test.ts +3 -3
- package/src/server/__tests__/toolRegistration.test.ts +3 -3
- package/src/server/cacheManager.ts +7 -6
- package/src/server/completions.ts +279 -0
- package/src/server/errorHandler.ts +1 -0
- package/src/server/rateLimiter.ts +4 -1
- package/src/server/resources.ts +49 -13
- package/src/server/securityMiddleware.ts +1 -0
- package/src/server/toolRegistry.ts +42 -0
- package/src/tools/__tests__/transactionTools.integration.test.ts +63 -3
- package/src/tools/__tests__/utilityTools.integration.test.ts +1 -85
- package/src/tools/__tests__/utilityTools.test.ts +1 -123
- package/src/tools/adapters.ts +22 -1
- package/src/tools/reconciliation/__tests__/executor.progress.test.ts +462 -0
- package/src/tools/reconciliation/executor.ts +55 -1
- package/src/tools/reconciliation/index.ts +7 -3
- package/src/tools/schemas/outputs/index.ts +0 -3
- package/src/tools/schemas/outputs/utilityOutputs.ts +2 -43
- package/src/tools/toolCategories.ts +0 -1
- package/src/tools/utilityTools.ts +5 -76
- package/vitest.config.ts +4 -1
- package/.chunkhound.json +0 -11
- package/.code/agents/0098661e-0fa3-4990-beb9-c0cbf3f123aa/status.txt +0 -1
- package/.code/agents/01a13ef4-3f23-4f52-b33b-3585b73cfa60/error.txt +0 -3
- package/.code/agents/084fd32f-e298-4728-9103-a78d7dc39613/error.txt +0 -3
- package/.code/agents/0fed51e1-a943-4b97-a2a8-a6f0f27c844d/status.txt +0 -1
- package/.code/agents/1059b6bd-5ccd-4d83-a12c-7c9d89137399/error.txt +0 -5
- package/.code/agents/110/exec-call_F9BDNG7JfxKkq7Vc8ESAvdft.txt +0 -1569
- package/.code/agents/11ebcef3-b13f-4e44-ad80-d94a866804b7/error.txt +0 -3
- package/.code/agents/1324/exec-call_tIpx9uV1TpARbAMZonRQm8AO.txt +0 -757
- package/.code/agents/1398/exec-call_CjItcWMU1G6JoPshX62QvpaR.txt +0 -2832
- package/.code/agents/1398/exec-call_SUVq2ivmONQ5LMCmd7ngmOqr.txt +0 -2709
- package/.code/agents/1398/exec-call_SdNY4NOffdcC5pRYjVXHjPCK.txt +0 -2832
- package/.code/agents/1398/exec-call_qblJo9et1gsFFB63TtLOiji2.txt +0 -2832
- package/.code/agents/1398/exec-call_zaRrzlGz7GJcNzVfkAmML7Zg.txt +0 -2709
- package/.code/agents/1572/exec-call_GjVFBFOWcY7lE0idc5nWlLNh.txt +0 -781
- package/.code/agents/171834fd-5905-42fc-bbcc-2c755145b0fc/status.txt +0 -1
- package/.code/agents/1724/exec-call_HvHQe0w5CCG3T7Q3ULT6MO3g.txt +0 -5217
- package/.code/agents/1724/exec-call_QwUNESVzfxxk78K1frh1Vahb.txt +0 -2594
- package/.code/agents/1724/exec-call_aJ1Xwz71XmIpD4SBxSHERzLe.txt +0 -2594
- package/.code/agents/1846/exec-call_1YNAVD18RjrMN7JnfkkQhUP3.txt +0 -766
- package/.code/agents/1846/exec-call_lh3lDzE4WJAh1lFiomiiZ73D.txt +0 -766
- package/.code/agents/1d7d7ab7-7473-4b69-8b97-6e914f56056a/result.txt +0 -231
- package/.code/agents/2038/exec-call_DYwOukaYsL8VCONWmV2rUW5u.txt +0 -766
- package/.code/agents/2038/exec-call_c7fOQ7UrpVcTtvdfGBRM146V.txt +0 -652
- package/.code/agents/2038/exec-call_ySNyq9Mm55jWE480s54r5QcA.txt +0 -766
- package/.code/agents/210/exec-call_0tQCsKNJ1WTuIchb8wlcFJpW.txt +0 -2590
- package/.code/agents/210/exec-call_8ZlY9cUc8Ft1twi4ch8UJ6IN.txt +0 -5195
- package/.code/agents/2188/exec-call_5HqayBxIteJtoI8oPTiLWgvJ.txt +0 -286
- package/.code/agents/2188/exec-call_XRbBKBq3adZe6dcppAvQtM7G.txt +0 -218
- package/.code/agents/2188/exec-call_ehA0SjpYtrUi6GJXmibLjp4i.txt +0 -180
- package/.code/agents/21902821-ecaf-4759-bb9d-222b90921af5/error.txt +0 -3
- package/.code/agents/2256/exec-call_AtPcRWPmFPMcmX6qOFm1fCEY.txt +0 -766
- package/.code/agents/232073be-aa0e-46da-b478-5b64dbf03cf5/status.txt +0 -1
- package/.code/agents/234ff534-2336-4771-a8d9-aa04421a63be/result.txt +0 -747
- package/.code/agents/2454/exec-call_aFJpupwjfZeOBm7ixI5Vc8z2.txt +0 -766
- package/.code/agents/2454/exec-call_wogZ4HfXTodTEXvdgXlVUBpv.txt +0 -766
- package/.code/agents/253e2695-dc36-4022-b436-27655e0fc6c7/status.txt +0 -1
- package/.code/agents/2583/exec-call_M59I4eDjpjlBIWBiSxyS0YlJ.txt +0 -2594
- package/.code/agents/2583/exec-call_usLRGh7OhVHtsRBL4iUwRhjq.txt +0 -2594
- package/.code/agents/292aa3ff-dbab-470f-97c9-e7e8fd65e0db/result.txt +0 -144
- package/.code/agents/2e905864-aa07-4314-bcf9-c5b32277e4ac/result.txt +0 -36
- package/.code/agents/3073/exec-call_Peeagc9DxGYLgE6pNdMZhqIE.txt +0 -766
- package/.code/agents/3073/exec-call_d2YSE3hXF08KRSoUM3qd8Z3x.txt +0 -766
- package/.code/agents/3134/exec-call_IgCAMGx19lWfuo8zfYIt5FFC.txt +0 -416
- package/.code/agents/3134/exec-call_IxvLR2Oo7kba2QTsI1gHVko8.txt +0 -2590
- package/.code/agents/3134/exec-call_jYvc8hksZChSiysbzKjl2ZbB.txt +0 -2590
- package/.code/agents/329/exec-call_4QdP3SfSO7HGPCwVcqZIth6s.txt +0 -2590
- package/.code/agents/335aa031-466d-4fb7-925f-3cd864e264d0/result.txt +0 -191
- package/.code/agents/3364/exec-call_NbhIrsM5HhyDZDmJZG5CuCYL.txt +0 -766
- package/.code/agents/3364/exec-call_cKtJg0NrXiwXEFwlsE3uPZRA.txt +0 -766
- package/.code/agents/36d98414-5cde-4d9d-9a67-a240a18c1f07/result.txt +0 -189
- package/.code/agents/4604e866-b7b8-44f5-992f-2f683b0a523b/status.txt +0 -1
- package/.code/agents/472/exec-call_4AxzEEcWwkKhpqRB3bE8Ha4L.txt +0 -790
- package/.code/agents/472/exec-call_CB3LPYQA8QIZRi8I6kj4J17A.txt +0 -766
- package/.code/agents/472/exec-call_YeoUWvaFoktay2nqVUsa9KKX.txt +0 -790
- package/.code/agents/472/exec-call_jPWgKVquBBXTg0T3Lks5ZfkK.txt +0 -2594
- package/.code/agents/472/exec-call_qBkvunpGBDEHph2jPmTwtcsb.txt +0 -1000
- package/.code/agents/472/exec-call_v0ffRV1p0kTckBmJPzzHAEy0.txt +0 -3489
- package/.code/agents/472/exec-call_xAX5FXqWIlk02d9WubHbHWh8.txt +0 -766
- package/.code/agents/5346/exec-call_9q0muXUuLaucwEqI51Pt7idT.txt +0 -2594
- package/.code/agents/5346/exec-call_B2el3B79rVkq9LhWTI2VYlz7.txt +0 -2456
- package/.code/agents/5346/exec-call_BfX08f02qkZI9uJD5dvCvuoj.txt +0 -2594
- package/.code/agents/543328d0-61d6-4fd1-a723-bb168656e2e2/error.txt +0 -18
- package/.code/agents/5580c02c-1383-4d18-9cbd-cc8a06e3408d/result.txt +0 -48
- package/.code/agents/5f8dc01c-47b3-4163-b0b3-aa31be89fcdc/status.txt +0 -1
- package/.code/agents/60ce1a22-5126-44b2-b977-1d5b56142a7b/status.txt +0 -1
- package/.code/agents/6215d9db-7fa9-4429-aeec-3835c3212291/error.txt +0 -1
- package/.code/agents/6743db55-30e5-4b4e-9366-a8214fc7f714/error.txt +0 -1
- package/.code/agents/6bf9591b-b9c9-422c-b0a5-e968c7d8422a/status.txt +0 -1
- package/.code/agents/7/exec-call_HltHpkDox0Zm1vGEjdksUgpE.txt +0 -1120
- package/.code/agents/7/exec-call_LCATrOPPAgbxW9Q1z0XaVi2E.txt +0 -2646
- package/.code/agents/7/exec-call_W8DeRfNG9hvbgVFvf0clBf6R.txt +0 -2646
- package/.code/agents/7/exec-call_eww3GfdEiJZx61sJEQ9wNmt3.txt +0 -1271
- package/.code/agents/70/exec-call_owUtDMYiVgqDf8vsz1i32PFf.txt +0 -1570
- package/.code/agents/8/exec-call_UtrjAcLbhYLatxR4O97fZgnm.txt +0 -2590
- package/.code/agents/82490bc9-f34e-4b1b-8a8e-bccc2e6254f5/error.txt +0 -3
- package/.code/agents/841/exec-call_7nTNhSBCNjTDUIJv7py6CepO.txt +0 -3299
- package/.code/agents/841/exec-call_TLI0yUdUijuUAvI4o3DXEvHO.txt +0 -3299
- package/.code/agents/9/exec-call_XaABQT1hIlRpnKZ2uyBMWsTC.txt +0 -1882
- package/.code/agents/941/exec-call_GuGHRx7NNXWIDAnxUG2NEWPa.txt +0 -2594
- package/.code/agents/94a0ddf3-a304-4ec3-913e-3cceef509948/error.txt +0 -1
- package/.code/agents/95d9fbab-19a2-48af-83f9-c792566a347f/error.txt +0 -1
- package/.code/agents/b0098cb8-cb32-4ada-9bc4-37c587518896/result.txt +0 -170
- package/.code/agents/b4fe59a4-81df-42e2-a112-0153e504faca/error.txt +0 -1
- package/.code/agents/bf4ce152-f623-49d7-aa52-c18631625c3c/error.txt +0 -3
- package/.code/agents/d7d1db75-d7eb-468e-adea-4ef4d916d187/status.txt +0 -1
- package/.code/agents/e2baa9c8-bac3-49e3-a39d-024333e6a990/status.txt +0 -1
- package/.code/agents/e2c752b7-711d-423a-af57-f53c809deb84/result.txt +0 -160
- package/.code/agents/e350b8c3-8483-408c-b2bb-94515f492a11/error.txt +0 -3
- package/.code/agents/e63f9919-719f-4ad0-bccf-01b1a596e1e9/status.txt +0 -1
- package/.code/agents/e6601719-c31f-4a0e-8c71-d70787d0ab71/status.txt +0 -1
- package/.code/agents/e71695a8-3044-478d-8f12-ed13d02884c7/status.txt +0 -1
- package/.code/agents/f250b7ed-5bd5-4036-aa8c-ce63caee7d61/result.txt +0 -20
- package/.code/agents/f95b7464-3e25-4897-b153-c8dfd63fd605/error.txt +0 -5
- package/.code/agents/fa3c5ddf-cdf7-47a2-930a-b806c6363689/status.txt +0 -1
- package/AGENTS.md +0 -1
- package/NUL +0 -0
- package/package.json.tmp +0 -105
- package/src/__tests__/delta.performance.test.ts +0 -80
- package/src/__tests__/workflows.e2e.test.ts +0 -1702
- package/temp-recon.ts +0 -126
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +0 -23
- package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +0 -23
- package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +0 -44
- package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +0 -58
- package/test-exports/ynab_since_2025-10-16_account_53298e13_238items_2025-11-28_13-46-20.json +0 -3662
- package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +0 -115
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
src\types\reconciliation.ts:4: * AMOUNTS ARE IN MILLIUNITS (integers, 1000 = $1.00).
|
|
2
|
-
src\types\reconciliation.ts:12: /** Amount in MILLIUNITS (negative = outflow, positive = inflow) */
|
|
3
|
-
src\types\reconciliation.ts:36: * AMOUNTS ARE IN MILLIUNITS - same as YNAB API native format.
|
|
4
|
-
src\types\reconciliation.ts:42: /** Amount in MILLIUNITS (same as YNAB API) */
|
|
5
|
-
src\__tests__\workflows.e2e.test.ts:825: it('should convert amounts between dollars and milliunits', async () => {
|
|
6
|
-
src\__tests__\workflows.e2e.test.ts:828: // Convert dollars to milliunits
|
|
7
|
-
src\__tests__\workflows.e2e.test.ts:829: const toMilliunitsResult = await executeToolCall(server, 'ynab:convert_amount', {
|
|
8
|
-
src\__tests__\workflows.e2e.test.ts:831: to_milliunits: true,
|
|
9
|
-
src\__tests__\workflows.e2e.test.ts:833: const milliunits = parseToolResult(toMilliunitsResult);
|
|
10
|
-
src\__tests__\workflows.e2e.test.ts:835: expect(milliunits.data?.conversion?.converted_amount).toBe(25500);
|
|
11
|
-
src\__tests__\workflows.e2e.test.ts:836: expect(milliunits.data?.conversion?.description).toContain('25500');
|
|
12
|
-
src\__tests__\workflows.e2e.test.ts:837: expect(milliunits.data?.conversion?.to_milliunits).toBe(true);
|
|
13
|
-
src\__tests__\workflows.e2e.test.ts:839: // Convert milliunits to dollars
|
|
14
|
-
src\__tests__\workflows.e2e.test.ts:842: to_milliunits: false,
|
|
15
|
-
src\__tests__\workflows.e2e.test.ts:848: expect(dollars.data?.conversion?.to_milliunits).toBe(false);
|
|
16
|
-
src\__tests__\workflows.e2e.test.ts:1146: { name: 'ynab:convert_amount', args: { amount: 100, to_milliunits: true } },
|
|
17
|
-
src\__tests__\workflows.e2e.test.ts:1629: to_milliunits: true,
|
|
18
|
-
src\server\prompts.ts:154:4. Create the transaction with the correct amount in milliunits (multiply by 1000)
|
|
19
|
-
src\server\prompts.ts:233:Convert milliunits to dollars for easy reading.`,
|
|
20
|
-
src\__tests__\performance.test.ts:629: to_milliunits: true,
|
|
21
|
-
src\__tests__\performance.test.ts:718: executeToolCall(server, 'ynab:convert_amount', { amount: i * 10, to_milliunits: true }),
|
|
22
|
-
src\__tests__\comprehensive.integration.test.ts:53: convertMilliUnitsToCurrencyAmount: vi.fn(
|
|
23
|
-
src\__tests__\comprehensive.integration.test.ts:54: (milliunits: number, currencyDecimalDigits: number = 2) => {
|
|
24
|
-
src\__tests__\comprehensive.integration.test.ts:55: const amount = milliunits / 1000;
|
|
25
|
-
src\__tests__\comprehensive.integration.test.ts:59: convertCurrencyAmountToMilliUnits: vi.fn((amount: number) => Math.round(amount * 1000)),
|
|
26
|
-
src\__tests__\comprehensive.integration.test.ts:68: 'converts milliunits using SDK rounding rules',
|
|
27
|
-
src\__tests__\comprehensive.integration.test.ts:73: expect(utils.convertMilliUnitsToCurrencyAmount(123456, 2)).toBe(123.46);
|
|
28
|
-
src\__tests__\comprehensive.integration.test.ts:74: expect(utils.convertMilliUnitsToCurrencyAmount(123456, 3)).toBe(123.456);
|
|
29
|
-
src\__tests__\comprehensive.integration.test.ts:75: expect(utils.convertMilliUnitsToCurrencyAmount(-98765, 2)).toBe(-98.77);
|
|
30
|
-
src\__tests__\comprehensive.integration.test.ts:756: // Test dollar to milliunits conversion
|
|
31
|
-
src\__tests__\comprehensive.integration.test.ts:757: const toMilliunitsResult = await executeToolCall(server, 'ynab:convert_amount', {
|
|
32
|
-
src\__tests__\comprehensive.integration.test.ts:759: to_milliunits: true,
|
|
33
|
-
src\__tests__\comprehensive.integration.test.ts:761: validateToolResult(toMilliunitsResult);
|
|
34
|
-
src\__tests__\comprehensive.integration.test.ts:763: const toMilli = parseToolResult(toMilliunitsResult);
|
|
35
|
-
src\__tests__\comprehensive.integration.test.ts:765: expect(toMilli.data.conversion.description).toBe('$25.75 = 25750 milliunits');
|
|
36
|
-
src\__tests__\comprehensive.integration.test.ts:767: // Test milliunits to dollar conversion
|
|
37
|
-
src\__tests__\comprehensive.integration.test.ts:770: to_milliunits: false,
|
|
38
|
-
src\__tests__\comprehensive.integration.test.ts:776: expect(dollars.data.conversion.description).toBe('25750 milliunits = $25.75');
|
|
39
|
-
src\tools\monthTools.ts:6:import { milliunitsToAmount } from '../utils/amountUtils.js';
|
|
40
|
-
src\tools\monthTools.ts:69: income: milliunitsToAmount(month.income),
|
|
41
|
-
src\tools\monthTools.ts:70: budgeted: milliunitsToAmount(month.budgeted),
|
|
42
|
-
src\tools\monthTools.ts:71: activity: milliunitsToAmount(month.activity),
|
|
43
|
-
src\tools\monthTools.ts:72: to_be_budgeted: milliunitsToAmount(month.to_be_budgeted),
|
|
44
|
-
src\tools\monthTools.ts:83: budgeted: milliunitsToAmount(category.budgeted),
|
|
45
|
-
src\tools\monthTools.ts:84: activity: milliunitsToAmount(category.activity),
|
|
46
|
-
src\tools\monthTools.ts:85: balance: milliunitsToAmount(category.balance),
|
|
47
|
-
src\tools\monthTools.ts:151: income: milliunitsToAmount(month.income),
|
|
48
|
-
src\tools\monthTools.ts:152: budgeted: milliunitsToAmount(month.budgeted),
|
|
49
|
-
src\tools\monthTools.ts:153: activity: milliunitsToAmount(month.activity),
|
|
50
|
-
src\tools\monthTools.ts:154: to_be_budgeted: milliunitsToAmount(month.to_be_budgeted),
|
|
51
|
-
src\tools\toolCategories.ts:123: * - convert_amount: Converts between dollars and milliunits
|
|
52
|
-
src\__tests__\testRunner.ts:349:- Milliunits handling
|
|
53
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:18: expect(result.transactions[0].amount).toBe(-45230); // Milliunits!
|
|
54
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:34: expect(result.transactions[0].amount).toBe(-45230); // Debit = negative milliunits
|
|
55
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:35: expect(result.transactions[1].amount).toBe(500000); // Credit = positive milliunits
|
|
56
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:59: expect(result.transactions[0].amount).toBe(1234560); // 1234.56 in milliunits
|
|
57
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:94: // Shell: exact amount match (both -45230 milliunits)
|
|
58
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:98: // Amazon: exact amount match (both -127990 milliunits)
|
|
59
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:108: amount: -45230, // Integer milliunits
|
|
60
|
-
src\__tests__\tools\reconciliation\csvParser.integration.test.ts:117: amount: -45230, // Integer milliunits - direct from YNAB API
|
|
61
|
-
src\tools\accountTools.ts:6:import { milliunitsToAmount } from '../utils/amountUtils.js';
|
|
62
|
-
src\tools\accountTools.ts:108: balance: milliunitsToAmount(account.balance),
|
|
63
|
-
src\tools\accountTools.ts:109: cleared_balance: milliunitsToAmount(account.cleared_balance),
|
|
64
|
-
src\tools\accountTools.ts:110: uncleared_balance: milliunitsToAmount(account.uncleared_balance),
|
|
65
|
-
src\tools\accountTools.ts:172: balance: milliunitsToAmount(account.balance),
|
|
66
|
-
src\tools\accountTools.ts:173: cleared_balance: milliunitsToAmount(account.cleared_balance),
|
|
67
|
-
src\tools\accountTools.ts:174: uncleared_balance: milliunitsToAmount(account.uncleared_balance),
|
|
68
|
-
src\tools\accountTools.ts:242: balance: params.balance ? params.balance * 1000 : 0, // Convert to milliunits
|
|
69
|
-
src\tools\accountTools.ts:273: balance: milliunitsToAmount(account.balance),
|
|
70
|
-
src\tools\accountTools.ts:274: cleared_balance: milliunitsToAmount(account.cleared_balance),
|
|
71
|
-
src\tools\accountTools.ts:275: uncleared_balance: milliunitsToAmount(account.uncleared_balance),
|
|
72
|
-
src\tools\compareTransactions\types.ts:11: /** Transaction amount in milliunits (YNAB format) */
|
|
73
|
-
src\tools\compareTransactions\types.ts:31: /** Transaction amount in milliunits */
|
|
74
|
-
src\__tests__\testUtils.ts:362: * Generate test amounts in milliunits
|
|
75
|
-
src\tools\compareTransactions\parser.ts:47: * Convert dollar amount to milliunits
|
|
76
|
-
src\tools\compareTransactions\parser.ts:49:export function amountToMilliunits(amountStr: string): Milli {
|
|
77
|
-
src\tools\compareTransactions\parser.ts:482: amount = amountToMilliunits(rawAmount);
|
|
78
|
-
src\tools\reconciliation\csvParser.ts:193: * IMPORTANT: Amounts are converted to MILLIUNITS (integers) at this boundary.
|
|
79
|
-
src\tools\reconciliation\csvParser.ts:194: * This is the ONLY place where float-to-milliunit conversion happens.
|
|
80
|
-
src\tools\reconciliation\csvParser.ts:364: let amountMilliunits: number;
|
|
81
|
-
src\tools\reconciliation\csvParser.ts:369: amountMilliunits = dollarStringToMilliunits(rawAmount);
|
|
82
|
-
src\tools\reconciliation\csvParser.ts:375: const debitMilliunits = dollarStringToMilliunits(debit);
|
|
83
|
-
src\tools\reconciliation\csvParser.ts:376: const creditMilliunits = dollarStringToMilliunits(credit);
|
|
84
|
-
src\tools\reconciliation\csvParser.ts:379: if (Math.abs(debitMilliunits) > 0 && Math.abs(creditMilliunits) > 0) {
|
|
85
|
-
src\tools\reconciliation\csvParser.ts:385: if (Math.abs(debitMilliunits) > 0) {
|
|
86
|
-
src\tools\reconciliation\csvParser.ts:386: amountMilliunits = -Math.abs(debitMilliunits); // Debits are outflows (negative)
|
|
87
|
-
src\tools\reconciliation\csvParser.ts:387: } else if (Math.abs(creditMilliunits) > 0) {
|
|
88
|
-
src\tools\reconciliation\csvParser.ts:388: amountMilliunits = Math.abs(creditMilliunits); // Credits are inflows (positive)
|
|
89
|
-
src\tools\reconciliation\csvParser.ts:390: amountMilliunits = 0;
|
|
90
|
-
src\tools\reconciliation\csvParser.ts:394: if (debitMilliunits < 0) {
|
|
91
|
-
src\tools\reconciliation\csvParser.ts:403: if (!Number.isFinite(amountMilliunits)) {
|
|
92
|
-
src\tools\reconciliation\csvParser.ts:415: amountMilliunits *= multiplier;
|
|
93
|
-
src\tools\reconciliation\csvParser.ts:423: amount: amountMilliunits,
|
|
94
|
-
src\tools\reconciliation\csvParser.ts:555:function dollarStringToMilliunits(str: string): number {
|
|
95
|
-
src\tools\reconciliation\csvParser.ts:578: // Convert to milliunits: $1.00 → 1000
|
|
96
|
-
src\tools\categoryTools.ts:6:import { milliunitsToAmount } from '../utils/amountUtils.js';
|
|
97
|
-
src\tools\categoryTools.ts:44: budgeted: z.number().int('Budgeted amount must be an integer in milliunits'),
|
|
98
|
-
src\tools\categoryTools.ts:52: * Convert goal-related monetary fields from milliunits to dollars.
|
|
99
|
-
src\tools\categoryTools.ts:58: category.goal_target != null ? milliunitsToAmount(category.goal_target) : undefined,
|
|
100
|
-
src\tools\categoryTools.ts:61: ? milliunitsToAmount(category.goal_under_funded)
|
|
101
|
-
src\tools\categoryTools.ts:65: ? milliunitsToAmount(category.goal_overall_funded)
|
|
102
|
-
src\tools\categoryTools.ts:69: ? milliunitsToAmount(category.goal_overall_left)
|
|
103
|
-
src\tools\categoryTools.ts:113: budgeted: milliunitsToAmount(category.budgeted),
|
|
104
|
-
src\tools\categoryTools.ts:114: activity: milliunitsToAmount(category.activity),
|
|
105
|
-
src\tools\categoryTools.ts:115: balance: milliunitsToAmount(category.balance),
|
|
106
|
-
src\tools\categoryTools.ts:191: budgeted: milliunitsToAmount(category.budgeted),
|
|
107
|
-
src\tools\categoryTools.ts:192: activity: milliunitsToAmount(category.activity),
|
|
108
|
-
src\tools\categoryTools.ts:193: balance: milliunitsToAmount(category.balance),
|
|
109
|
-
src\tools\categoryTools.ts:253: budgeted: milliunitsToAmount(params.budgeted),
|
|
110
|
-
src\tools\categoryTools.ts:320: budgeted: milliunitsToAmount(category.budgeted),
|
|
111
|
-
src\tools\categoryTools.ts:321: activity: milliunitsToAmount(category.activity),
|
|
112
|
-
src\tools\categoryTools.ts:322: balance: milliunitsToAmount(category.balance),
|
|
113
|
-
src\tools\reconciliation\analyzer.ts:5: * V2 UPDATE: Uses new parser and matcher (milliunits based)
|
|
114
|
-
src\tools\reconciliation\analyzer.ts:48: const amount = txn.amount / 1000; // Convert from milliunits to dollars
|
|
115
|
-
src\tools\reconciliation\index.ts:170: amountToleranceMilliunits: (params.amount_tolerance_cents ?? 1) * 10,
|
|
116
|
-
src\tools\reconcileAdapter.ts:44: bank_statement_balance_milliunits: number;
|
|
117
|
-
src\tools\reconcileAdapter.ts:45: ynab_calculated_balance_milliunits: number;
|
|
118
|
-
src\tools\reconcileAdapter.ts:46: discrepancy_milliunits: number;
|
|
119
|
-
src\tools\reconcileAdapter.ts:54: amount_milliunits: number;
|
|
120
|
-
src\tools\reconcileAdapter.ts:123: const discrepancyMilli = analysis.balance_info.discrepancy.value_milliunits;
|
|
121
|
-
src\tools\reconcileAdapter.ts:148: bank_statement_balance: toMoneyValue(precision.bank_statement_balance_milliunits, currency),
|
|
122
|
-
src\tools\reconcileAdapter.ts:149: ynab_calculated_balance: toMoneyValue(precision.ynab_calculated_balance_milliunits, currency),
|
|
123
|
-
src\tools\reconcileAdapter.ts:150: discrepancy: toMoneyValue(precision.discrepancy_milliunits, currency),
|
|
124
|
-
src\tools\reconcileAdapter.ts:165: amount: toMoneyValue(cause.amount_milliunits, currency),
|
|
125
|
-
src\tools\reconciliation\executor.ts:14: balance: number; // milliunits
|
|
126
|
-
src\tools\reconciliation\executor.ts:15: cleared_balance: number; // milliunits
|
|
127
|
-
src\tools\reconciliation\executor.ts:16: uncleared_balance: number; // milliunits
|
|
128
|
-
src\tools\reconciliation\executor.ts:782: bank_statement_balance_milliunits: bankMilli,
|
|
129
|
-
src\tools\reconciliation\executor.ts:783: ynab_calculated_balance_milliunits: ynabMilli,
|
|
130
|
-
src\tools\reconciliation\executor.ts:784: discrepancy_milliunits: discrepancy,
|
|
131
|
-
src\tools\reconciliation\executor.ts:857: amount_milliunits: number;
|
|
132
|
-
src\tools\reconciliation\executor.ts:868: amount_milliunits: discrepancyMilli,
|
|
133
|
-
src\tools\reconciliation\executor.ts:957: 'value_milliunits' in value &&
|
|
134
|
-
src\tools\reconciliation\executor.ts:958: typeof (value as { value_milliunits: unknown }).value_milliunits === 'number'
|
|
135
|
-
src\tools\reconciliation\executor.ts:960: return (value as { value_milliunits: number }).value_milliunits;
|
|
136
|
-
src\utils\money.ts:4:export type Milli = number; // integer milliunits (no bigint)
|
|
137
|
-
src\utils\money.ts:9: value_milliunits: Milli;
|
|
138
|
-
src\utils\money.ts:45: * Convert milliunits to currency amount using proper decimal digits
|
|
139
|
-
src\utils\money.ts:47: * @param m - Milliunits value
|
|
140
|
-
src\utils\money.ts:51: return ynab.utils.convertMilliUnitsToCurrencyAmount(m, decimalDigits);
|
|
141
|
-
src\utils\money.ts:54:export const assertMilli = (m: number, msg = 'Expected safe integer milliunits') => {
|
|
142
|
-
src\utils\money.ts:60: if (!Number.isSafeInteger(s)) throw new Error('Milliunit sum overflow');
|
|
143
|
-
src\utils\money.ts:84: * Format milliunits as currency string with proper decimal digits
|
|
144
|
-
src\utils\money.ts:85: * @param value - Milliunits value
|
|
145
|
-
src\utils\money.ts:96: * Convert milliunits to MoneyValue with proper currency format
|
|
146
|
-
src\utils\money.ts:97: * @param value - Milliunits value
|
|
147
|
-
src\utils\money.ts:106: value_milliunits: value,
|
|
148
|
-
src\tools\reconciliation\recommendationEngine.ts:182: amount: toMilli(bankTxn.amount), // Convert dollars to milliunits for create_transaction
|
|
149
|
-
src\tools\reconciliation\recommendationEngine.ts:222: // Calculate total amount from candidates for context (convert from milliunits to decimal)
|
|
150
|
-
src\tools\reconciliation\recommendationEngine.ts:428: amount: toMilli(txn.amount), // Convert dollars to milliunits for create_transaction
|
|
151
|
-
src\tools\reconciliation\reportFormatter.ts:93: const discrepancyMilli = balanceInfo.discrepancy.value_milliunits;
|
|
152
|
-
src\tools\reconciliation\reportFormatter.ts:352: const amount = txn.amount / 1000; // Convert milliunits to dollars
|
|
153
|
-
src\tools\reconciliation\types.ts:37: /** Amount in milliunits */
|
|
154
|
-
src\tools\reconciliation\types.ts:175: // Tolerances (in MILLIUNITS for amount)
|
|
155
|
-
src\tools\reconciliation\types.ts:176: amountToleranceMilliunits: number; // Default: 10 (1 cent)
|
|
156
|
-
src\tools\transactionTools.ts:10:import { amountToMilliunits, milliunitsToAmount } from '../utils/amountUtils.js';
|
|
157
|
-
src\tools\transactionTools.ts:173: amount: z.number().int('Amount must be an integer in milliunits'),
|
|
158
|
-
src\tools\transactionTools.ts:188: amount: z.number().int('Subtransaction amount must be an integer in milliunits'),
|
|
159
|
-
src\tools\transactionTools.ts:626: amount: z.number().int('Amount must be an integer in milliunits').optional(),
|
|
160
|
-
src\tools\transactionTools.ts:651: amount: z.number().int('Amount must be an integer in milliunits').optional(),
|
|
161
|
-
src\tools\transactionTools.ts:808: amount: milliunitsToAmount(transaction.amount),
|
|
162
|
-
src\tools\transactionTools.ts:832: amount: milliunitsToAmount(transaction.amount),
|
|
163
|
-
src\tools\transactionTools.ts:906: amount: milliunitsToAmount(transaction.amount),
|
|
164
|
-
src\tools\transactionTools.ts:979: amount: params.amount, // Already validated as integer milliunits
|
|
165
|
-
src\tools\transactionTools.ts:1047: amount: milliunitsToAmount(transaction.amount),
|
|
166
|
-
src\tools\transactionTools.ts:1066: amount: milliunitsToAmount(subtransaction.amount),
|
|
167
|
-
src\tools\transactionTools.ts:1089: subtotal_milliunits: number;
|
|
168
|
-
src\tools\transactionTools.ts:1090: tax_milliunits: number;
|
|
169
|
-
src\tools\transactionTools.ts:1093: amount_milliunits: number;
|
|
170
|
-
src\tools\transactionTools.ts:1123: subtotalMilliunits: number,
|
|
171
|
-
src\tools\transactionTools.ts:1124: totalTaxMilliunits: number,
|
|
172
|
-
src\tools\transactionTools.ts:1127: if (totalTaxMilliunits === 0) {
|
|
173
|
-
src\tools\transactionTools.ts:1128: for (const category of categories) category.tax_milliunits = 0;
|
|
174
|
-
src\tools\transactionTools.ts:1132: if (subtotalMilliunits <= 0) {
|
|
175
|
-
src\tools\transactionTools.ts:1139: category.tax_milliunits = totalTaxMilliunits - allocated;
|
|
176
|
-
src\tools\transactionTools.ts:1142: (totalTaxMilliunits * category.subtotal_milliunits) / subtotalMilliunits,
|
|
177
|
-
src\tools\transactionTools.ts:1144: category.tax_milliunits = proportionalTax;
|
|
178
|
-
src\tools\transactionTools.ts:1176: amount_milliunits: amountToMilliunits(item.amount),
|
|
179
|
-
src\tools\transactionTools.ts:1180: const subtotalMilliunits = items.reduce((sum, item) => sum + item.amount_milliunits, 0);
|
|
180
|
-
src\tools\transactionTools.ts:1184: subtotal_milliunits: subtotalMilliunits,
|
|
181
|
-
src\tools\transactionTools.ts:1185: tax_milliunits: 0,
|
|
182
|
-
src\tools\transactionTools.ts:1190: const subtotalMilliunits = categoryCalculations.reduce(
|
|
183
|
-
src\tools\transactionTools.ts:1191: (sum, category) => sum + category.subtotal_milliunits,
|
|
184
|
-
src\tools\transactionTools.ts:1195: const declaredSubtotalMilliunits =
|
|
185
|
-
src\tools\transactionTools.ts:1196: params.receipt_subtotal !== undefined ? amountToMilliunits(params.receipt_subtotal) : undefined;
|
|
186
|
-
src\tools\transactionTools.ts:1198: declaredSubtotalMilliunits !== undefined &&
|
|
187
|
-
src\tools\transactionTools.ts:1199: Math.abs(declaredSubtotalMilliunits - subtotalMilliunits) > 1
|
|
188
|
-
src\tools\transactionTools.ts:1202: `Categorized items subtotal (${milliunitsToAmount(subtotalMilliunits)}) does not match receipt subtotal (${milliunitsToAmount(declaredSubtotalMilliunits)})`,
|
|
189
|
-
src\tools\transactionTools.ts:1206: const taxMilliunits = amountToMilliunits(params.receipt_tax);
|
|
190
|
-
src\tools\transactionTools.ts:1207: const totalMilliunits = amountToMilliunits(params.receipt_total);
|
|
191
|
-
src\tools\transactionTools.ts:1208: const computedTotal = subtotalMilliunits + taxMilliunits;
|
|
192
|
-
src\tools\transactionTools.ts:1209: if (Math.abs(computedTotal - totalMilliunits) > 1) {
|
|
193
|
-
src\tools\transactionTools.ts:1211: `Receipt total (${milliunitsToAmount(totalMilliunits)}) does not equal subtotal plus tax (${milliunitsToAmount(computedTotal)})`,
|
|
194
|
-
src\tools\transactionTools.ts:1215: distributeTaxProportionally(subtotalMilliunits, taxMilliunits, categoryCalculations);
|
|
195
|
-
src\tools\transactionTools.ts:1221: amount: -item.amount_milliunits,
|
|
196
|
-
src\tools\transactionTools.ts:1229: category.tax_milliunits > 0
|
|
197
|
-
src\tools\transactionTools.ts:1232: amount: -category.tax_milliunits,
|
|
198
|
-
src\tools\transactionTools.ts:1243: subtotal: milliunitsToAmount(subtotalMilliunits),
|
|
199
|
-
src\tools\transactionTools.ts:1244: tax: milliunitsToAmount(taxMilliunits),
|
|
200
|
-
src\tools\transactionTools.ts:1245: total: milliunitsToAmount(totalMilliunits),
|
|
201
|
-
src\tools\transactionTools.ts:1252: amount: milliunitsToAmount(item.amount_milliunits),
|
|
202
|
-
src\tools\transactionTools.ts:1255: subtotal: milliunitsToAmount(category.subtotal_milliunits),
|
|
203
|
-
src\tools\transactionTools.ts:1256: tax: milliunitsToAmount(category.tax_milliunits),
|
|
204
|
-
src\tools\transactionTools.ts:1257: total: milliunitsToAmount(category.subtotal_milliunits + category.tax_milliunits),
|
|
205
|
-
src\tools\transactionTools.ts:1273: amount: milliunitsToAmount(totalMilliunits),
|
|
206
|
-
src\tools\transactionTools.ts:1278: amount: milliunitsToAmount(-subtransaction.amount),
|
|
207
|
-
src\tools\transactionTools.ts:1291: amount: -totalMilliunits,
|
|
208
|
-
src\tools\transactionTools.ts:1494: amount: milliunitsToAmount(transaction.amount),
|
|
209
|
-
src\tools\transactionTools.ts:1733: amount: milliunitsToAmount(transaction.amount),
|
|
210
|
-
src\tools\transactionTools.ts:1751: total_amount: milliunitsToAmount(totalAmount),
|
|
211
|
-
src\tools\transactionTools.ts:2132: before['amount'] = milliunitsToAmount(currentState.amount);
|
|
212
|
-
src\tools\transactionTools.ts:2133: after['amount'] = milliunitsToAmount(transaction.amount);
|
|
213
|
-
src\tools\utilityTools.ts:13: to_milliunits: z.boolean(),
|
|
214
|
-
src\tools\utilityTools.ts:49: * Converts between dollars and milliunits with integer arithmetic for precision
|
|
215
|
-
src\tools\utilityTools.ts:54: const { amount, to_milliunits } = params;
|
|
216
|
-
src\tools\utilityTools.ts:59: if (to_milliunits) {
|
|
217
|
-
src\tools\utilityTools.ts:60: // Convert from dollars to milliunits
|
|
218
|
-
src\tools\utilityTools.ts:63: description = `$${amount.toFixed(2)} = ${result} milliunits`;
|
|
219
|
-
src\tools\utilityTools.ts:65: // Convert from milliunits to dollars
|
|
220
|
-
src\tools\utilityTools.ts:66: // Assume input amount is in milliunits
|
|
221
|
-
src\tools\utilityTools.ts:68: description = `${amount} milliunits = $${result.toFixed(2)}`;
|
|
222
|
-
src\tools\utilityTools.ts:79: to_milliunits,
|
|
223
|
-
src\tools\reconciliation\__tests__\adapter.causes.test.ts:59: bank_statement_balance_milliunits: -921240,
|
|
224
|
-
src\tools\reconciliation\__tests__\adapter.causes.test.ts:60: ynab_calculated_balance_milliunits: -899020,
|
|
225
|
-
src\tools\reconciliation\__tests__\adapter.causes.test.ts:61: discrepancy_milliunits: -22220,
|
|
226
|
-
src\tools\reconciliation\__tests__\adapter.causes.test.ts:72: amount_milliunits: -1500,
|
|
227
|
-
src\tools\reconciliation\__tests__\adapter.causes.test.ts:80: amount_milliunits: 500,
|
|
228
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:9: value_milliunits: Math.round(value * 1000),
|
|
229
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:149: expect(structured.matches.auto[0].bank_transaction.amount_money.value_milliunits).toBe(-45230);
|
|
230
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:183: bank_statement_balance_milliunits: -921240,
|
|
231
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:184: ynab_calculated_balance_milliunits: -899020,
|
|
232
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:185: discrepancy_milliunits: -22220,
|
|
233
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:195: amount_milliunits: 22220,
|
|
234
|
-
src\tools\reconciliation\__tests__\adapter.test.ts:224: expect(structured.execution.account_balance.after.cleared_balance.value_milliunits).toBe(
|
|
235
|
-
src\tools\reconciliation\matcher.ts:4: * V2 matcher works natively in milliunits using canonical BankTransaction
|
|
236
|
-
src\tools\reconciliation\matcher.ts:50: amountToleranceMilliunits: 10, // 1 cent
|
|
237
|
-
src\tools\reconciliation\matcher.ts:67: amountToleranceMilliunits:
|
|
238
|
-
src\tools\reconciliation\matcher.ts:68: config.amountToleranceMilliunits ?? DEFAULT_CONFIG.amountToleranceMilliunits,
|
|
239
|
-
src\tools\reconciliation\matcher.ts:293: if (amountDiff > config.amountToleranceMilliunits) {
|
|
240
|
-
src\tools\reconciliation\matcher.ts:338: // Amount score - now using INTEGER comparison (milliunits)
|
|
241
|
-
src\tools\reconciliation\matcher.ts:345: } else if (amountDiff <= config.amountToleranceMilliunits) {
|
|
242
|
-
src\tools\reconciliation\__tests__\analyzer.test.ts:24: amount: -45230, // milliunits
|
|
243
|
-
src\tools\reconciliation\__tests__\analyzer.test.ts:33: amount: -100000, // milliunits
|
|
244
|
-
src\tools\reconciliation\ynabAdapter.ts:10: * NOTE: Amount stays in milliunits - no conversion needed since
|
|
245
|
-
src\tools\reconciliation\ynabAdapter.ts:11: * YNAB API already uses milliunits natively.
|
|
246
|
-
src\tools\reconciliation\ynabAdapter.ts:17: amount: txn.amount, // Already in milliunits - no conversion!
|
|
247
|
-
src\server\YNABMCPServer.ts:901: description: 'Convert between dollars and milliunits with integer arithmetic for precision',
|
|
248
|
-
src\utils\amountUtils.ts:2: * Utility functions for converting between YNAB milliunits and dollars
|
|
249
|
-
src\utils\amountUtils.ts:6: * Converts an amount from milliunits to dollars
|
|
250
|
-
src\utils\amountUtils.ts:7: * @param milliunits - Amount in milliunits (1000 milliunits = $1.00)
|
|
251
|
-
src\utils\amountUtils.ts:10:export function milliunitsToAmount(milliunits: number): number {
|
|
252
|
-
src\utils\amountUtils.ts:11: return Math.round(milliunits) / 1000;
|
|
253
|
-
src\utils\amountUtils.ts:15: * Converts an amount from dollars to milliunits
|
|
254
|
-
src\utils\amountUtils.ts:17: * @returns Amount in milliunits
|
|
255
|
-
src\utils\amountUtils.ts:19:export function amountToMilliunits(amount: number): number {
|
|
256
|
-
src\utils\amountUtils.ts:24: * Formats an amount from milliunits to a currency string
|
|
257
|
-
src\utils\amountUtils.ts:25: * @param milliunits - Amount in milliunits
|
|
258
|
-
src\utils\amountUtils.ts:29:export function formatAmount(milliunits: number, currencySymbol = '$'): string {
|
|
259
|
-
src\utils\amountUtils.ts:30: const amount = milliunitsToAmount(milliunits);
|
|
260
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:260: expect(rec.parameters.amount).toBe(-75500); // In milliunits
|
|
261
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:458: expect(rec.parameters.amount).toBe(-45000); // In milliunits
|
|
262
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:548: expect(rec.parameters.amount).toBe(-123450); // In milliunits
|
|
263
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:569: expect(rec.parameters.amount).toBe(500000); // In milliunits
|
|
264
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:594: expect(rec.parameters.amount).toBe(-99990); // In milliunits
|
|
265
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:610: expect(rec.parameters.amount).toBe(0); // Zero in milliunits is still zero
|
|
266
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:921: expect(rec.parameters.amount).toBe(-10); // In milliunits (0.01 * 1000)
|
|
267
|
-
src\tools\reconciliation\__tests__\recommendationEngine.test.ts:937: expect(rec.parameters.amount).toBe(-999999990); // In milliunits
|
|
268
|
-
src\tools\reconciliation\__tests__\recommendationEngine.integration.test.ts:17: amount: number, // in milliunits
|
|
269
|
-
src\tools\reconciliation\__tests__\recommendationEngine.integration.test.ts:87: expect(rec.parameters.amount).toBe(22220); // In milliunits
|
|
270
|
-
src\tools\reconciliation\__tests__\recommendationEngine.integration.test.ts:141: expect(evoCarShareRec!.parameters.amount).toBe(22220); // In milliunits
|
|
271
|
-
src\tools\reconciliation\__tests__\recommendationEngine.integration.test.ts:552: // 500 dollars in milliunits
|
|
272
|
-
src\tools\reconciliation\__tests__\recommendationEngine.integration.test.ts:651: expect(createRec!.parameters.amount).toBe(25500); // In milliunits
|
|
273
|
-
src\tools\reconciliation\__tests__\matcher.test.ts:15: amountToleranceMilliunits: 10,
|
|
274
|
-
src\tools\reconciliation\__tests__\matcher.test.ts:41: amount: -45230, // milliunits
|
|
275
|
-
src\tools\reconciliation\__tests__\matcher.test.ts:339: config.amountToleranceMilliunits = 10; // 1 cent
|
|
276
|
-
src\tools\reconciliation\__tests__\matcher.test.ts:532: amountToleranceMilliunits: 100, // 10 cents
|
|
277
|
-
src\tools\reconciliation\__tests__\matcher.test.ts:626: amount: -10, // 1 cent in milliunits
|
|
278
|
-
src\tools\reconciliation\__tests__\matcher.test.ts:652: amount: -10000000, // $10,000 in milliunits
|
|
279
|
-
src\tools\reconciliation\__tests__\reportFormatter.test.ts:20: value_milliunits: Math.round(value * 1000),
|
|
280
|
-
src\tools\schemas\outputs\accountOutputs.ts:68: * Represents account data with balances in dollars (converted from YNAB milliunits).
|
|
281
|
-
src\tools\__tests__\accountTools.test.ts:401: // Verify the API was called with balance 0 in milliunits
|
|
282
|
-
src\tools\__tests__\accountTools.test.ts:411: it('should convert balance to milliunits', async () => {
|
|
283
|
-
src\tools\__tests__\accountTools.test.ts:435: balance: 150, // $150 should become 150000 milliunits
|
|
284
|
-
src\tools\__tests__\accountTools.test.ts:438: // Verify the API was called with balance converted to milliunits
|
|
285
|
-
src\tools\reconciliation\__tests__\scenarios\adapterCurrency.scenario.test.ts:6: value_milliunits: Math.round(value * 1000),
|
|
286
|
-
src\tools\reconciliation\__tests__\scenarios\repeatAmount.scenario.test.ts:18: // Three -22.22 transactions in milliunits: one will match YNAB, two will remain unmatched
|
|
287
|
-
src\tools\schemas\outputs\categoryOutputs.ts:9: * goal_overall_funded, goal_overall_left) are converted from YNAB API milliunits to
|
|
288
|
-
src\tools\schemas\outputs\categoryOutputs.ts:123: /** Goal target amount in dollars (converted from YNAB API milliunits, optional) */
|
|
289
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:344: * IMPORTANT: `amount` is the raw YNAB amount in **milliunits** (not dollar amounts).
|
|
290
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:346: * For example, $25.50 is represented as 25500 milliunits.
|
|
291
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:352: * @see src/tools/exportTransactions.ts:204 - Amount field directly from transaction.amount (milliunits)
|
|
292
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:357: amount: z.number(), // Raw YNAB milliunits
|
|
293
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:365: amount: z.number(), // Raw YNAB milliunits
|
|
294
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:417: * { id: "txn-1", date: "2025-11-15", amount: -25500, payee_name: "Grocery Store", cleared: "cleared" }, // amount is milliunits
|
|
295
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:435: * amount: -25500, // Raw milliunits: -$25.50
|
|
296
|
-
src\tools\schemas\outputs\comparisonOutputs.ts:592: amount: z.number(), // Raw YNAB milliunits
|
|
297
|
-
src\utils\__tests__\money.test.ts:19: it('converts dollars to milliunits correctly', () => {
|
|
298
|
-
src\utils\__tests__\money.test.ts:32: it('converts milliunits with 2 decimal digits (USD) by default', () => {
|
|
299
|
-
src\utils\__tests__\money.test.ts:38: it('converts milliunits with 0 decimal digits (JPY)', () => {
|
|
300
|
-
src\utils\__tests__\money.test.ts:43: it('converts milliunits with 3 decimal digits (BHD)', () => {
|
|
301
|
-
src\utils\__tests__\money.test.ts:48: it('converts milliunits with explicit 2 decimal digits', () => {
|
|
302
|
-
src\utils\__tests__\money.test.ts:61: expect(() => assertMilli(1.5)).toThrow('Expected safe integer milliunits');
|
|
303
|
-
src\utils\__tests__\money.test.ts:63: 'Expected safe integer milliunits',
|
|
304
|
-
src\utils\__tests__\money.test.ts:69: it('adds milliunits correctly', () => {
|
|
305
|
-
src\utils\__tests__\money.test.ts:75: expect(() => addMilli(Number.MAX_SAFE_INTEGER, 1)).toThrow('Milliunit sum overflow');
|
|
306
|
-
src\utils\__tests__\money.test.ts:152: it('formats milliunits into currency strings with default 2 decimals', () => {
|
|
307
|
-
src\utils\__tests__\money.test.ts:157: it('formats milliunits with custom currency format', () => {
|
|
308
|
-
src\utils\__tests__\money.test.ts:163: it('creates money values from milliunits with default 2 decimals', () => {
|
|
309
|
-
src\utils\__tests__\money.test.ts:184: expect(value.value_milliunits).toBe(-45670);
|
|
310
|
-
src\tools\schemas\outputs\monthOutputs.ts:128: /** Goal target amount in milliunits (optional) */
|
|
311
|
-
src\tools\schemas\outputs\monthOutputs.ts:129: goal_target: z.number().optional().describe('Goal target in milliunits'),
|
|
312
|
-
src\server\__tests__\prompts.test.ts:173: expect(text).toContain('Create the transaction with the correct amount in milliunits');
|
|
313
|
-
src\server\__tests__\prompts.test.ts:251: expect(text).toContain('Convert milliunits to dollars');
|
|
314
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:17: * account_balance: 1500000, // Raw milliunits: $1,500.00
|
|
315
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:18: * account_cleared_balance: 1000000 // Raw milliunits: $1,000.00
|
|
316
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:77: * IMPORTANT: `account_balance` and `account_cleared_balance` are **raw YNAB milliunits** (not user-facing dollar amounts).
|
|
317
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:79: * For example, $1,250.50 is represented as 1250500 milliunits.
|
|
318
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:85: account_balance: z.number().optional(), // Raw YNAB milliunits
|
|
319
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:86: account_cleared_balance: z.number().optional(), // Raw YNAB milliunits
|
|
320
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:258: * account_balance: 1500000, // Raw milliunits: $1,500.00
|
|
321
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:259: * account_cleared_balance: 1000000 // Raw milliunits: $1,000.00
|
|
322
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:392: * updated_balance: 1450000, // Raw milliunits: $1,450.00
|
|
323
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:393: * updated_cleared_balance: 950000 // Raw milliunits: $950.00
|
|
324
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:412: updated_balance: z.number(), // Raw YNAB milliunits
|
|
325
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:413: updated_cleared_balance: z.number(), // Raw YNAB milliunits
|
|
326
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:529: updated_balance: z.number(), // Raw YNAB milliunits
|
|
327
|
-
src\tools\schemas\outputs\transactionMutationOutputs.ts:530: updated_cleared_balance: z.number(), // Raw YNAB milliunits
|
|
328
|
-
src\tools\schemas\outputs\transactionOutputs.ts:98: * Represents full transaction data with amounts in dollars (converted from YNAB milliunits).
|
|
329
|
-
src\tools\schemas\outputs\utilityOutputs.ts:56: * Contains the conversion result between dollars and YNAB milliunits.
|
|
330
|
-
src\tools\schemas\outputs\utilityOutputs.ts:61: to_milliunits: z.boolean(),
|
|
331
|
-
src\tools\schemas\outputs\utilityOutputs.ts:68: * Converts between dollars and YNAB milliunits (1 dollar = 1000 milliunits).
|
|
332
|
-
src\tools\schemas\outputs\utilityOutputs.ts:78: * to_milliunits: true,
|
|
333
|
-
src\tools\schemas\outputs\utilityOutputs.ts:79: * description: "$25.50 converted to 25500 milliunits"
|
|
334
|
-
src\tools\__tests__\categoryTools.integration.test.ts:133: console.warn(` - Budgeted: ${category.budgeted} milliunits`);
|
|
335
|
-
src\tools\__tests__\categoryTools.integration.test.ts:134: console.warn(` - Activity: ${category.activity} milliunits`);
|
|
336
|
-
src\tools\__tests__\categoryTools.integration.test.ts:135: console.warn(` - Balance: ${category.balance} milliunits`);
|
|
337
|
-
src\tools\__tests__\categoryTools.integration.test.ts:170: // Update with a test amount (add 1000 milliunits = $1.00)
|
|
338
|
-
src\tools\__tests__\categoryTools.integration.test.ts:204: console.warn(`✅ Successfully updated category budget to ${testBudgetedAmount} milliunits`);
|
|
339
|
-
src\tools\__tests__\categoryTools.integration.test.ts:214: console.warn(`✅ Restored original budget amount: ${originalBudgetedAmount} milliunits`);
|
|
340
|
-
src\tools\__tests__\categoryTools.integration.test.ts:281: `✅ Successfully set negative budget amount: ${negativeBudgetedAmount} milliunits`,
|
|
341
|
-
src\tools\__tests__\categoryTools.integration.test.ts:291: console.warn(`✅ Restored original budget amount: ${originalBudgetedAmount} milliunits`);
|
|
342
|
-
src\tools\schemas\outputs\__tests__\comparisonOutputs.test.ts:403: amount: -25500, // Milliunits
|
|
343
|
-
src\tools\schemas\outputs\__tests__\comparisonOutputs.test.ts:436: amount: -15000, // Milliunits: -$15.00
|
|
344
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:7: amountToMilliunits,
|
|
345
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:78: describe('amountToMilliunits', () => {
|
|
346
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:80: expect(amountToMilliunits('123.45')).toBe(123450);
|
|
347
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:84: expect(amountToMilliunits('-123.45')).toBe(-123450);
|
|
348
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:88: expect(amountToMilliunits('(123.45)')).toBe(-123450);
|
|
349
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:92: expect(amountToMilliunits('$123.45')).toBe(123450);
|
|
350
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:96: expect(amountToMilliunits('1,234.56')).toBe(1234560);
|
|
351
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:100: expect(amountToMilliunits('+123.45')).toBe(123450);
|
|
352
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:104: expect(amountToMilliunits('0.00')).toBe(0);
|
|
353
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:108: expect(amountToMilliunits(' 123.45 ')).toBe(123450);
|
|
354
|
-
src\tools\__tests__\compareTransactions\parser.test.ts:112: expect(amountToMilliunits('999999.99')).toBe(999999990);
|
|
355
|
-
src\tools\__tests__\utilityTools.test.ts:85: it('should convert dollars to milliunits correctly', async () => {
|
|
356
|
-
src\tools\__tests__\utilityTools.test.ts:86: const params = { amount: 10.5, to_milliunits: true };
|
|
357
|
-
src\tools\__tests__\utilityTools.test.ts:93: expect(response.conversion.to_milliunits).toBe(true);
|
|
358
|
-
src\tools\__tests__\utilityTools.test.ts:94: expect(response.conversion.description).toBe('$10.50 = 10500 milliunits');
|
|
359
|
-
src\tools\__tests__\utilityTools.test.ts:97: it('should convert milliunits to dollars correctly', async () => {
|
|
360
|
-
src\tools\__tests__\utilityTools.test.ts:98: const params = { amount: 10500, to_milliunits: false };
|
|
361
|
-
src\tools\__tests__\utilityTools.test.ts:105: expect(response.conversion.to_milliunits).toBe(false);
|
|
362
|
-
src\tools\__tests__\utilityTools.test.ts:106: expect(response.conversion.description).toBe('10500 milliunits = $10.50');
|
|
363
|
-
src\tools\__tests__\utilityTools.test.ts:110: const params = { amount: 0, to_milliunits: true };
|
|
364
|
-
src\tools\__tests__\utilityTools.test.ts:117: expect(response.conversion.description).toBe('$0.00 = 0 milliunits');
|
|
365
|
-
src\tools\__tests__\utilityTools.test.ts:121: const params = { amount: -5.25, to_milliunits: true };
|
|
366
|
-
src\tools\__tests__\utilityTools.test.ts:128: expect(response.conversion.description).toBe('$-5.25 = -5250 milliunits');
|
|
367
|
-
src\tools\__tests__\utilityTools.test.ts:132: const params = { amount: 0.01, to_milliunits: true };
|
|
368
|
-
src\tools\__tests__\utilityTools.test.ts:141: const params = { amount: 999999.99, to_milliunits: true };
|
|
369
|
-
src\tools\__tests__\utilityTools.test.ts:149: it('should round to nearest milliunit when converting from dollars', async () => {
|
|
370
|
-
src\tools\__tests__\utilityTools.test.ts:150: const params = { amount: 10.5555, to_milliunits: true };
|
|
371
|
-
src\tools\__tests__\utilityTools.test.ts:161: const validParams = { amount: 10.5, to_milliunits: true };
|
|
372
|
-
src\tools\__tests__\utilityTools.test.ts:171: const invalidParams = { amount: Infinity, to_milliunits: true };
|
|
373
|
-
src\tools\__tests__\utilityTools.test.ts:178: const invalidParams = { amount: NaN, to_milliunits: true };
|
|
374
|
-
src\tools\__tests__\utilityTools.test.ts:185: const invalidParams = { to_milliunits: true };
|
|
375
|
-
src\tools\__tests__\utilityTools.test.ts:191: it('should reject missing to_milliunits parameter', () => {
|
|
376
|
-
src\tools\__tests__\utilityTools.test.ts:198: it('should reject non-boolean to_milliunits parameter', () => {
|
|
377
|
-
src\tools\__tests__\utilityTools.test.ts:199: const invalidParams = { amount: 10.5, to_milliunits: 'true' };
|
|
378
|
-
src\tools\__tests__\compareTransactions.test.ts:78: amount: 100000, // $100.00 in milliunits
|
|
379
|
-
src\tools\__tests__\compareTransactions.test.ts:90: amount: -50000, // -$50.00 in milliunits
|
|
380
|
-
src\tools\__tests__\transactionTools.test.ts:136: amount: -50000, // $50.00 outflow in milliunits
|
|
381
|
-
src\tools\__tests__\transactionTools.test.ts:558: amount: -50000, // $50.00 outflow in milliunits
|
|
382
|
-
src\tools\__tests__\transactionTools.test.ts:618: expect(result.error.issues[0].message).toContain('Amount must be an integer in milliunits');
|
|
383
|
-
src\tools\__tests__\transactionTools.test.ts:1456: expect(result.error.issues[0].message).toContain('Amount must be an integer in milliunits');
|
|
384
|
-
src\tools\__tests__\transactionTools.test.ts:1881: it('should require integer milliunit amounts', () => {
|
|
385
|
-
src\tools\__tests__\transactionTools.test.ts:2704: it('should require integer milliunit amounts when provided', () => {
|
|
386
|
-
src\tools\__tests__\utilityTools.integration.test.ts:47: 'should convert various dollar amounts to milliunits',
|
|
387
|
-
src\tools\__tests__\utilityTools.integration.test.ts:51: { dollars: 1.0, expectedMilliunits: 1000 },
|
|
388
|
-
src\tools\__tests__\utilityTools.integration.test.ts:52: { dollars: 0.01, expectedMilliunits: 10 },
|
|
389
|
-
src\tools\__tests__\utilityTools.integration.test.ts:53: { dollars: 10.5, expectedMilliunits: 10500 },
|
|
390
|
-
src\tools\__tests__\utilityTools.integration.test.ts:54: { dollars: 999.99, expectedMilliunits: 999990 },
|
|
391
|
-
src\tools\__tests__\utilityTools.integration.test.ts:55: { dollars: 0, expectedMilliunits: 0 },
|
|
392
|
-
src\tools\__tests__\utilityTools.integration.test.ts:56: { dollars: -5.25, expectedMilliunits: -5250 },
|
|
393
|
-
src\tools\__tests__\utilityTools.integration.test.ts:62: to_milliunits: true,
|
|
394
|
-
src\tools\__tests__\utilityTools.integration.test.ts:66: expect(response.conversion.converted_amount).toBe(testCase.expectedMilliunits);
|
|
395
|
-
src\tools\__tests__\utilityTools.integration.test.ts:67: expect(response.conversion.to_milliunits).toBe(true);
|
|
396
|
-
src\tools\__tests__\utilityTools.integration.test.ts:70: `${testCase.expectedMilliunits} milliunits`,
|
|
397
|
-
src\tools\__tests__\utilityTools.integration.test.ts:77: 'should convert various milliunit amounts to dollars',
|
|
398
|
-
src\tools\__tests__\utilityTools.integration.test.ts:81: { milliunits: 1000, expectedDollars: 1.0 },
|
|
399
|
-
src\tools\__tests__\utilityTools.integration.test.ts:82: { milliunits: 10, expectedDollars: 0.01 },
|
|
400
|
-
src\tools\__tests__\utilityTools.integration.test.ts:83: { milliunits: 10500, expectedDollars: 10.5 },
|
|
401
|
-
src\tools\__tests__\utilityTools.integration.test.ts:84: { milliunits: 999990, expectedDollars: 999.99 },
|
|
402
|
-
src\tools\__tests__\utilityTools.integration.test.ts:85: { milliunits: 0, expectedDollars: 0 },
|
|
403
|
-
src\tools\__tests__\utilityTools.integration.test.ts:86: { milliunits: -5250, expectedDollars: -5.25 },
|
|
404
|
-
src\tools\__tests__\utilityTools.integration.test.ts:91: amount: testCase.milliunits,
|
|
405
|
-
src\tools\__tests__\utilityTools.integration.test.ts:92: to_milliunits: false,
|
|
406
|
-
src\tools\__tests__\utilityTools.integration.test.ts:97: expect(response.conversion.to_milliunits).toBe(false);
|
|
407
|
-
src\tools\__tests__\utilityTools.integration.test.ts:98: expect(response.conversion.description).toContain(`${testCase.milliunits} milliunits`);
|
|
408
|
-
src\tools\__tests__\utilityTools.integration.test.ts:112: { amount: 0.1 + 0.2, to_milliunits: true }, // Should handle 0.30000000000000004
|
|
409
|
-
src\tools\__tests__\utilityTools.integration.test.ts:113: { amount: 1.005, to_milliunits: true }, // Should round correctly
|
|
410
|
-
src\tools\__tests__\utilityTools.integration.test.ts:114: { amount: 999.999, to_milliunits: true }, // Should handle near-integer values
|
|
411
|
-
src\tools\__tests__\monthTools.integration.test.ts:63: console.warn(` - Income: ${firstMonth.income} milliunits`);
|
|
412
|
-
src\tools\__tests__\monthTools.integration.test.ts:64: console.warn(` - Budgeted: ${firstMonth.budgeted} milliunits`);
|
|
413
|
-
src\tools\__tests__\monthTools.integration.test.ts:126: console.warn(` - Income: ${month.income} milliunits`);
|
|
414
|
-
src\tools\__tests__\monthTools.integration.test.ts:127: console.warn(` - Budgeted: ${month.budgeted} milliunits`);
|
|
415
|
-
src\tools\__tests__\monthTools.integration.test.ts:128: console.warn(` - Activity: ${month.activity} milliunits`);
|
|
416
|
-
src\tools\__tests__\monthTools.integration.test.ts:129: console.warn(` - To be budgeted: ${month.to_be_budgeted} milliunits`);
|