@dizzlkheinz/ynab-mcpb 0.12.2 → 0.15.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/.code/agents/01a13ef4-3f23-4f52-b33b-3585b73cfa60/error.txt +3 -0
- package/.code/agents/084fd32f-e298-4728-9103-a78d7dc39613/error.txt +3 -0
- package/.code/agents/0fed51e1-a943-4b97-a2a8-a6f0f27c844d/status.txt +1 -0
- package/.code/agents/1059b6bd-5ccd-4d83-a12c-7c9d89137399/error.txt +5 -0
- package/.code/agents/110/exec-call_F9BDNG7JfxKkq7Vc8ESAvdft.txt +1569 -0
- package/.code/agents/11ebcef3-b13f-4e44-ad80-d94a866804b7/error.txt +3 -0
- package/.code/agents/1398/exec-call_CjItcWMU1G6JoPshX62QvpaR.txt +2832 -0
- package/.code/agents/1398/exec-call_SUVq2ivmONQ5LMCmd7ngmOqr.txt +2709 -0
- package/.code/agents/1398/exec-call_SdNY4NOffdcC5pRYjVXHjPCK.txt +2832 -0
- package/.code/agents/1398/exec-call_qblJo9et1gsFFB63TtLOiji2.txt +2832 -0
- package/.code/agents/1398/exec-call_zaRrzlGz7GJcNzVfkAmML7Zg.txt +2709 -0
- package/.code/agents/171834fd-5905-42fc-bbcc-2c755145b0fc/status.txt +1 -0
- package/.code/agents/1724/exec-call_HvHQe0w5CCG3T7Q3ULT6MO3g.txt +5217 -0
- package/.code/agents/1724/exec-call_QwUNESVzfxxk78K1frh1Vahb.txt +2594 -0
- package/.code/agents/1724/exec-call_aJ1Xwz71XmIpD4SBxSHERzLe.txt +2594 -0
- package/.code/agents/1d7d7ab7-7473-4b69-8b97-6e914f56056a/result.txt +231 -0
- package/.code/agents/210/exec-call_0tQCsKNJ1WTuIchb8wlcFJpW.txt +2590 -0
- package/.code/agents/210/exec-call_8ZlY9cUc8Ft1twi4ch8UJ6IN.txt +5195 -0
- package/.code/agents/2188/exec-call_5HqayBxIteJtoI8oPTiLWgvJ.txt +286 -0
- package/.code/agents/2188/exec-call_XRbBKBq3adZe6dcppAvQtM7G.txt +218 -0
- package/.code/agents/2188/exec-call_ehA0SjpYtrUi6GJXmibLjp4i.txt +180 -0
- package/.code/agents/21902821-ecaf-4759-bb9d-222b90921af5/error.txt +3 -0
- package/.code/agents/232073be-aa0e-46da-b478-5b64dbf03cf5/status.txt +1 -0
- package/.code/agents/234ff534-2336-4771-a8d9-aa04421a63be/result.txt +747 -0
- package/.code/agents/253e2695-dc36-4022-b436-27655e0fc6c7/status.txt +1 -0
- package/.code/agents/2583/exec-call_M59I4eDjpjlBIWBiSxyS0YlJ.txt +2594 -0
- package/.code/agents/2583/exec-call_usLRGh7OhVHtsRBL4iUwRhjq.txt +2594 -0
- package/.code/agents/292aa3ff-dbab-470f-97c9-e7e8fd65e0db/result.txt +144 -0
- package/.code/agents/3134/exec-call_IgCAMGx19lWfuo8zfYIt5FFC.txt +416 -0
- package/.code/agents/3134/exec-call_IxvLR2Oo7kba2QTsI1gHVko8.txt +2590 -0
- package/.code/agents/3134/exec-call_jYvc8hksZChSiysbzKjl2ZbB.txt +2590 -0
- package/.code/agents/329/exec-call_4QdP3SfSO7HGPCwVcqZIth6s.txt +2590 -0
- package/.code/agents/472/exec-call_4AxzEEcWwkKhpqRB3bE8Ha4L.txt +790 -0
- package/.code/agents/472/exec-call_CB3LPYQA8QIZRi8I6kj4J17A.txt +766 -0
- package/.code/agents/472/exec-call_YeoUWvaFoktay2nqVUsa9KKX.txt +790 -0
- package/.code/agents/472/exec-call_jPWgKVquBBXTg0T3Lks5ZfkK.txt +2594 -0
- package/.code/agents/472/exec-call_qBkvunpGBDEHph2jPmTwtcsb.txt +1000 -0
- package/.code/agents/472/exec-call_v0ffRV1p0kTckBmJPzzHAEy0.txt +3489 -0
- package/.code/agents/472/exec-call_xAX5FXqWIlk02d9WubHbHWh8.txt +766 -0
- package/.code/agents/5346/exec-call_9q0muXUuLaucwEqI51Pt7idT.txt +2594 -0
- package/.code/agents/5346/exec-call_B2el3B79rVkq9LhWTI2VYlz7.txt +2456 -0
- package/.code/agents/5346/exec-call_BfX08f02qkZI9uJD5dvCvuoj.txt +2594 -0
- package/.code/agents/543328d0-61d6-4fd1-a723-bb168656e2e2/error.txt +18 -0
- package/.code/agents/5580c02c-1383-4d18-9cbd-cc8a06e3408d/result.txt +48 -0
- package/.code/agents/60ce1a22-5126-44b2-b977-1d5b56142a7b/status.txt +1 -0
- package/.code/agents/6215d9db-7fa9-4429-aeec-3835c3212291/error.txt +1 -0
- package/.code/agents/6743db55-30e5-4b4e-9366-a8214fc7f714/error.txt +1 -0
- package/.code/agents/6bf9591b-b9c9-422c-b0a5-e968c7d8422a/status.txt +1 -0
- package/.code/agents/7/exec-call_eww3GfdEiJZx61sJEQ9wNmt3.txt +1271 -0
- package/.code/agents/70/exec-call_owUtDMYiVgqDf8vsz1i32PFf.txt +1570 -0
- package/.code/agents/8/exec-call_UtrjAcLbhYLatxR4O97fZgnm.txt +2590 -0
- package/.code/agents/82490bc9-f34e-4b1b-8a8e-bccc2e6254f5/error.txt +3 -0
- package/.code/agents/841/exec-call_7nTNhSBCNjTDUIJv7py6CepO.txt +3299 -0
- package/.code/agents/841/exec-call_TLI0yUdUijuUAvI4o3DXEvHO.txt +3299 -0
- package/.code/agents/9/exec-call_XaABQT1hIlRpnKZ2uyBMWsTC.txt +1882 -0
- package/.code/agents/941/exec-call_GuGHRx7NNXWIDAnxUG2NEWPa.txt +2594 -0
- package/.code/agents/95d9fbab-19a2-48af-83f9-c792566a347f/error.txt +1 -0
- package/.code/agents/b0098cb8-cb32-4ada-9bc4-37c587518896/result.txt +170 -0
- package/.code/agents/b4fe59a4-81df-42e2-a112-0153e504faca/error.txt +1 -0
- package/.code/agents/bf4ce152-f623-49d7-aa52-c18631625c3c/error.txt +3 -0
- package/.code/agents/d7d1db75-d7eb-468e-adea-4ef4d916d187/status.txt +1 -0
- package/.code/agents/e2baa9c8-bac3-49e3-a39d-024333e6a990/status.txt +1 -0
- package/.code/agents/e350b8c3-8483-408c-b2bb-94515f492a11/error.txt +3 -0
- package/.code/agents/e63f9919-719f-4ad0-bccf-01b1a596e1e9/status.txt +1 -0
- package/.code/agents/e71695a8-3044-478d-8f12-ed13d02884c7/status.txt +1 -0
- package/.code/agents/f95b7464-3e25-4897-b153-c8dfd63fd605/error.txt +5 -0
- package/.code/agents/fa3c5ddf-cdf7-47a2-930a-b806c6363689/status.txt +1 -0
- package/.github/workflows/ci-tests.yml +6 -2
- package/.github/workflows/publish.yml +3 -3
- package/.github/workflows/release.yml +4 -0
- package/CHANGELOG.md +89 -1
- package/NUL +1 -1
- package/README.md +36 -10
- package/dist/bundle/index.cjs +65 -42
- package/dist/index.js +9 -20
- package/dist/server/YNABMCPServer.d.ts +2 -1
- package/dist/server/YNABMCPServer.js +61 -27
- package/dist/server/cacheKeys.d.ts +8 -0
- package/dist/server/cacheKeys.js +8 -0
- package/dist/server/config.d.ts +22 -3
- package/dist/server/config.js +16 -17
- package/dist/server/errorHandler.d.ts +2 -0
- package/dist/server/errorHandler.js +49 -5
- package/dist/server/securityMiddleware.js +3 -6
- package/dist/server/toolRegistry.js +8 -10
- package/dist/tools/accountTools.js +4 -3
- package/dist/tools/categoryTools.js +8 -7
- package/dist/tools/monthTools.js +2 -1
- package/dist/tools/payeeTools.js +2 -1
- package/dist/tools/reconcileAdapter.js +10 -5
- package/dist/tools/reconciliation/analyzer.d.ts +4 -2
- package/dist/tools/reconciliation/analyzer.js +120 -404
- package/dist/tools/reconciliation/csvParser.d.ts +51 -0
- package/dist/tools/reconciliation/csvParser.js +413 -0
- package/dist/tools/reconciliation/executor.d.ts +8 -0
- package/dist/tools/reconciliation/executor.js +277 -50
- package/dist/tools/reconciliation/index.d.ts +7 -7
- package/dist/tools/reconciliation/index.js +115 -39
- package/dist/tools/reconciliation/matcher.d.ts +24 -3
- package/dist/tools/reconciliation/matcher.js +175 -133
- package/dist/tools/reconciliation/recommendationEngine.js +22 -18
- package/dist/tools/reconciliation/reportFormatter.js +9 -8
- package/dist/tools/reconciliation/signDetector.d.ts +2 -0
- package/dist/tools/reconciliation/signDetector.js +54 -0
- package/dist/tools/reconciliation/types.d.ts +20 -34
- package/dist/tools/reconciliation/types.js +1 -7
- package/dist/tools/reconciliation/ynabAdapter.d.ts +4 -0
- package/dist/tools/reconciliation/ynabAdapter.js +15 -0
- package/dist/tools/transactionTools.d.ts +3 -17
- package/dist/tools/transactionTools.js +5 -17
- package/dist/types/reconciliation.d.ts +24 -0
- package/dist/types/reconciliation.js +1 -0
- package/dist/utils/baseError.d.ts +3 -0
- package/dist/utils/baseError.js +7 -0
- package/dist/utils/errors.d.ts +13 -0
- package/dist/utils/errors.js +15 -0
- package/dist/utils/validationError.d.ts +3 -0
- package/dist/utils/validationError.js +3 -0
- package/docs/guides/ARCHITECTURE.md +12 -129
- package/docs/plans/2025-11-20-reloadable-config-token-validation.md +93 -0
- package/docs/plans/2025-11-21-fix-transaction-cached-property.md +362 -0
- package/docs/plans/2025-11-21-reconciliation-error-handling.md +90 -0
- package/docs/plans/2025-11-21-v014-hardening.md +153 -0
- package/docs/plans/reconciliation-v2-redesign.md +1571 -0
- package/package.json +8 -2
- package/scripts/run-throttled-integration-tests.js +9 -3
- package/scripts/test-recommendations.ts +1 -1
- package/src/__tests__/performance.test.ts +12 -5
- package/src/__tests__/testUtils.ts +62 -5
- package/src/__tests__/tools/reconciliation/csvParser.integration.test.ts +129 -0
- package/src/__tests__/tools/reconciliation/real-world.integration.test.ts +53 -0
- package/src/__tests__/workflows.e2e.test.ts +33 -0
- package/src/index.ts +8 -31
- package/src/server/YNABMCPServer.ts +81 -42
- package/src/server/__tests__/YNABMCPServer.integration.test.ts +10 -12
- package/src/server/__tests__/YNABMCPServer.test.ts +27 -15
- package/src/server/__tests__/config.test.ts +76 -152
- package/src/server/__tests__/server-startup.integration.test.ts +42 -14
- package/src/server/__tests__/toolRegistry.test.ts +1 -1
- package/src/server/cacheKeys.ts +8 -0
- package/src/server/config.ts +20 -38
- package/src/server/errorHandler.ts +52 -5
- package/src/server/securityMiddleware.ts +3 -7
- package/src/server/toolRegistry.ts +14 -10
- package/src/tools/__tests__/categoryTools.test.ts +37 -19
- package/src/tools/__tests__/transactionTools.test.ts +58 -2
- package/src/tools/accountTools.ts +8 -3
- package/src/tools/categoryTools.ts +12 -7
- package/src/tools/monthTools.ts +7 -1
- package/src/tools/payeeTools.ts +7 -1
- package/src/tools/reconcileAdapter.ts +10 -5
- package/src/tools/reconciliation/__tests__/adapter.test.ts +28 -22
- package/src/tools/reconciliation/__tests__/analyzer.test.ts +114 -180
- package/src/tools/reconciliation/__tests__/csvParser.test.ts +87 -0
- package/src/tools/reconciliation/__tests__/executor.integration.test.ts +26 -6
- package/src/tools/reconciliation/__tests__/executor.test.ts +133 -60
- package/src/tools/reconciliation/__tests__/matcher.test.ts +68 -54
- package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +37 -30
- package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +6 -5
- package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +30 -11
- package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +50 -15
- package/src/tools/reconciliation/__tests__/signDetector.test.ts +211 -0
- package/src/tools/reconciliation/__tests__/ynabAdapter.test.ts +61 -0
- package/src/tools/reconciliation/analyzer.ts +174 -545
- package/src/tools/reconciliation/csvParser.ts +617 -0
- package/src/tools/reconciliation/executor.ts +344 -58
- package/src/tools/reconciliation/index.ts +141 -48
- package/src/tools/reconciliation/matcher.ts +234 -214
- package/src/tools/reconciliation/recommendationEngine.ts +23 -19
- package/src/tools/reconciliation/reportFormatter.ts +16 -11
- package/src/tools/reconciliation/signDetector.ts +117 -0
- package/src/tools/reconciliation/types.ts +39 -61
- package/src/tools/reconciliation/ynabAdapter.ts +33 -0
- package/src/tools/schemas/outputs/utilityOutputs.ts +1 -1
- package/src/tools/transactionTools.ts +7 -18
- package/src/types/reconciliation.ts +49 -0
- package/src/utils/baseError.ts +7 -0
- package/src/utils/errors.ts +21 -0
- package/src/utils/validationError.ts +3 -0
- package/temp-recon.ts +126 -0
- package/test-exports/ynab_since_2025-10-16_account_53298e13_238items_2025-11-28_13-46-20.json +3662 -0
- package/test_mcp_tools.mjs +75 -0
- package/.code/agents/0427d95e-edca-431f-a214-5e53264e29c4/error.txt +0 -8
- package/.code/agents/0d675174-d1e1-41c3-9975-4c2e275819a9/error.txt +0 -3
- package/.code/agents/0d8c5afd-4787-422b-abf8-2e5943fc7e67/error.txt +0 -3
- package/.code/agents/0ec34a70-ed5d-4b9e-bee4-bb0e4cccbc4b/error.txt +0 -1
- package/.code/agents/0ef51a21-1ab1-49d7-9561-0eaa43875ebc/error.txt +0 -12
- package/.code/agents/15db95d7-abad-4b4d-9c3b-8446089cb61d/error.txt +0 -1
- package/.code/agents/19ab9acb-f675-4ff0-902a-09a5476f8149/error.txt +0 -1
- package/.code/agents/1ef7e12d-f6ff-4897-8a9b-152d523d898e/error.txt +0 -5
- package/.code/agents/2465/exec-call_lroN9KKzJVWC7t5423DK1nT9.txt +0 -1453
- package/.code/agents/28edb6fe-95a9-41a0-ae69-aa0100d26c0c/error.txt +0 -8
- package/.code/agents/2ae40cf5-b4bf-42e2-92bf-7ea350a7755e/error.txt +0 -9
- package/.code/agents/2bfc4e1f-ac4b-45a5-b6df-bf89d4dbb54c/error.txt +0 -1
- package/.code/agents/2e2e1134-eff0-49be-ba25-8e2c3468a564/error.txt +0 -5
- package/.code/agents/3/exec-call_203OC4TNVkLxW7z2HCVEQ1cM.txt +0 -81
- package/.code/agents/3/exec-call_SS5T0XSiXB4LSNzUKTl75wkh.txt +0 -610
- package/.code/agents/3322c003-ce5e-48e3-a342-f5049c5bf9a2/error.txt +0 -1
- package/.code/agents/391e9b08-1ebc-468c-9bcd-6d0cc3193b37/error.txt +0 -1
- package/.code/agents/3ab0aa84-b7bb-4054-afa3-40b8fd7d3be0/error.txt +0 -1
- package/.code/agents/3bed368d-50fe-477e-aee3-a6707eaa1ab9/error.txt +0 -3
- package/.code/agents/3e40b925-db12-442f-8d7a-a25fc69a6672/error.txt +0 -8
- package/.code/agents/414d5776-cf58-41f3-9328-a6daed503a50/error.txt +0 -5
- package/.code/agents/42687751-4565-4610-b240-67835b17d861/error.txt +0 -1
- package/.code/agents/46b98876-1a39-43c9-9e2f-507ca6d47335/error.txt +0 -9
- package/.code/agents/4a7d9491-b26f-43dd-850d-2ecdc49b5d1b/error.txt +0 -1
- package/.code/agents/4e60f00a-1b3e-447f-87f3-7faf9deddec3/error.txt +0 -13
- package/.code/agents/5138fc1c-4d49-4b74-a7da-ccdb3a8e44e7/error.txt +0 -14
- package/.code/agents/521cff39-a7a3-42e5-a557-134f0f7daaa0/error.txt +0 -5
- package/.code/agents/53302dc5-3857-4413-9a47-9e0f64a51dc4/error.txt +0 -5
- package/.code/agents/567c7c2e-6a6f-4761-a08d-d36deeb2e0ac/error.txt +0 -5
- package/.code/agents/57b00845-80dc-47c9-953c-3028d16275d6/error.txt +0 -3
- package/.code/agents/593d9005-c2a5-48fd-8813-ece0d3f2de96/error.txt +0 -1
- package/.code/agents/5a112e66-0e1a-42f9-877c-53af56ea3551/error.txt +0 -1
- package/.code/agents/5b05e8ed-7788-4738-b7ee-9faa8180f992/error.txt +0 -5
- package/.code/agents/5f888d6f-d7ca-4ac8-be23-9ea1bf753951/error.txt +0 -5
- package/.code/agents/607db3ab-e4b0-435b-b497-93e9aa525549/error.txt +0 -8
- package/.code/agents/67dcb2a2-900f-4c78-b3fc-80b5213e0ddf/error.txt +0 -8
- package/.code/agents/69ad848c-4e98-49b3-b16c-0094ac2d1759/error.txt +0 -5
- package/.code/agents/6c9cfc5f-0d0b-445c-b121-9f60082c4f70/error.txt +0 -1
- package/.code/agents/6f6f8f77-4ab0-4f6e-9f30-40e8be0bd8f5/error.txt +0 -1
- package/.code/agents/72a7cde4-fa8a-4024-9038-27faa550539b/error.txt +0 -1
- package/.code/agents/7b48335c-8247-43aa-9949-5f820ba8e199/error.txt +0 -1
- package/.code/agents/80944249-bea9-4ac5-87de-a666c4df306e/error.txt +0 -1
- package/.code/agents/826099df-1b66-4186-a915-7eb59f9db19d/error.txt +0 -5
- package/.code/agents/8291d158-18a8-4a92-b799-4e9a4d9cce88/error.txt +0 -1
- package/.code/agents/82fb71a3-20fb-4341-804a-a2fc900f95bc/error.txt +0 -1
- package/.code/agents/855790ea-54ee-43e4-8209-a66994e37590/error.txt +0 -1
- package/.code/agents/88ce3a2e-04f2-42be-9062-bf97aa798da0/error.txt +0 -3
- package/.code/agents/9a17e398-b6ed-4218-bb55-bc64a8d38ce8/error.txt +0 -8
- package/.code/agents/9a4f4bfc-a2a6-4f40-a896-9335b41a7ed1/error.txt +0 -1
- package/.code/agents/9b633e55-ef84-47d6-94bb-fd3dd172ad97/error.txt +0 -1
- package/.code/agents/9b81f3ab-c72b-4a81-9a8f-28a49ddba84a/error.txt +0 -8
- package/.code/agents/a35daf29-b2d1-4aef-9b42-dad63a76bd47/error.txt +0 -3
- package/.code/agents/a81990cc-69ee-44d2-b907-17403c9bc5d7/error.txt +0 -5
- package/.code/agents/ab56260a-4a83-4ad4-9410-f88a23d6520a/error.txt +0 -1
- package/.code/agents/ad722c31-2d1d-45f7-bae2-3f02ca455b60/error.txt +0 -1
- package/.code/agents/b62e8690-3324-4b97-9309-731bee79416b/error.txt +0 -5
- package/.code/agents/baf60a3a-752b-4ad8-99d6-df32423ed2eb/error.txt +0 -1
- package/.code/agents/be049042-7dcb-4ac8-9beb-c8f1aea67742/error.txt +0 -14
- package/.code/agents/bed1dcb4-bfce-4a9f-8594-0f994962aafd/error.txt +0 -1
- package/.code/agents/c324a6cf-e935-4ede-9529-b3ebc18e8d6b/error.txt +0 -5
- package/.code/agents/c37c06ff-dfe3-43f2-9bbc-3ec73ec8f41d/error.txt +0 -5
- package/.code/agents/c8cd6671-433a-456b-9f88-e51cb2df6bfc/error.txt +0 -11
- package/.code/agents/ca2ccb67-2f24-428e-b27d-9365beadd140/error.txt +0 -1
- package/.code/agents/cf08c0c8-e7f0-423e-93ba-547e8e818340/error.txt +0 -8
- package/.code/agents/d579c74f-874b-40a4-9d56-ced1eb6a701d/error.txt +0 -1
- package/.code/agents/df412c98-7378-4deb-8e1e-76c416931181/error.txt +0 -3
- package/.code/agents/e5134eb3-2af4-45b0-8998-051cb4afdb45/error.txt +0 -3
- package/.code/agents/e6308471-aa45-4e9e-9496-2e9404164d97/error.txt +0 -8
- package/.code/agents/e7bd8bc7-23fb-4f46-98dc-b0dcf11b75a1/error.txt +0 -1
- package/.code/agents/e92bec35-378d-4fe1-8ac0-6e1bb3c86911/error.txt +0 -5
- package/.code/agents/ed918fbf-2dc4-4aa2-bfc5-04b65d9471ea/error.txt +0 -1
- package/.code/agents/ef1d756f-b272-48fc-8729-f05c494674f7/error.txt +0 -1
- package/.code/agents/ef359853-0249-4e41-a804-c0fc459fe456/error.txt +0 -1
- package/.code/agents/effc7b4a-4b90-40a0-8c86-a7a99d2d5fd2/error.txt +0 -1
- package/.code/agents/fa15f8d5-8359-4a8b-83a3-2f2056b3ff40/error.txt +0 -3
- package/.code/agents/fbef4193-eadf-4c8a-83ff-4878a6310f25/error.txt +0 -8
- package/.code/agents/fd0a4b4a-fda4-4964-a6d6-2b8a2da387c6/error.txt +0 -1
- package/.gemini/settings.json +0 -8
- package/ADOS-2-Module-1-Complete-Manual.md +0 -757
- package/WARP.md +0 -245
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
# YNAB MCP Server Architecture
|
|
2
2
|
|
|
3
|
-
This guide explains the
|
|
3
|
+
This guide explains the modular architecture, core components, and architectural patterns.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
7
|
-
- [
|
|
7
|
+
- [Modular Architecture](#modular-architecture)
|
|
8
8
|
- [Core Components](#core-components)
|
|
9
9
|
- [Dependency Injection Pattern](#dependency-injection-pattern)
|
|
10
|
-
- [Developing Tools
|
|
10
|
+
- [Developing Tools](#developing-tools)
|
|
11
11
|
- [Cache Management](#cache-management)
|
|
12
12
|
- [Service Module Patterns](#service-module-patterns)
|
|
13
|
-
- [Migration from v0.7.x](#migration-from-v07x)
|
|
14
13
|
|
|
15
|
-
##
|
|
14
|
+
## Modular Architecture
|
|
16
15
|
|
|
17
|
-
The
|
|
16
|
+
The server uses a modular architecture that improves maintainability, testability, and performance.
|
|
18
17
|
|
|
19
18
|
### Architecture Overview
|
|
20
19
|
|
|
21
|
-
The
|
|
20
|
+
The architecture consists of several key components working together:
|
|
22
21
|
|
|
23
22
|
```
|
|
24
23
|
┌─────────────────────────────────────────────────────────────┐
|
|
@@ -92,10 +91,10 @@ Focused modules handling specific server concerns:
|
|
|
92
91
|
|
|
93
92
|
## Dependency Injection Pattern
|
|
94
93
|
|
|
95
|
-
The
|
|
94
|
+
The architecture uses explicit dependency injection for better testability and maintainability:
|
|
96
95
|
|
|
97
96
|
```typescript
|
|
98
|
-
//
|
|
97
|
+
// Explicit dependency injection pattern
|
|
99
98
|
class MyService {
|
|
100
99
|
constructor(
|
|
101
100
|
private cacheManager: CacheManager,
|
|
@@ -120,11 +119,11 @@ class MyService {
|
|
|
120
119
|
const myService = new MyService(cacheManager, errorHandler, budgetResolver);
|
|
121
120
|
```
|
|
122
121
|
|
|
123
|
-
## Developing Tools
|
|
122
|
+
## Developing Tools
|
|
124
123
|
|
|
125
124
|
### Tool Development Patterns
|
|
126
125
|
|
|
127
|
-
Creating new tools
|
|
126
|
+
Creating new tools follows the Tool Registry pattern for consistency and maintainability.
|
|
128
127
|
|
|
129
128
|
#### 1. Define Tool Schema
|
|
130
129
|
|
|
@@ -250,7 +249,7 @@ export async function handleMyTool(params: MyToolRequest): Promise<any> {
|
|
|
250
249
|
|
|
251
250
|
### Understanding the Enhanced Cache System
|
|
252
251
|
|
|
253
|
-
The
|
|
252
|
+
The server includes a sophisticated caching system designed for performance and observability.
|
|
254
253
|
|
|
255
254
|
#### Cache Configuration
|
|
256
255
|
|
|
@@ -423,7 +422,7 @@ export async function handleSetDefaultBudget(params: SetDefaultBudgetRequest) {
|
|
|
423
422
|
|
|
424
423
|
### Working with Service Modules
|
|
425
424
|
|
|
426
|
-
The
|
|
425
|
+
The server decomposes functionality into focused service modules.
|
|
427
426
|
|
|
428
427
|
#### Resource Manager
|
|
429
428
|
|
|
@@ -528,122 +527,6 @@ class MyDiagnosticManager extends DiagnosticManager {
|
|
|
528
527
|
}
|
|
529
528
|
```
|
|
530
529
|
|
|
531
|
-
## Migration from v0.7.x
|
|
532
|
-
|
|
533
|
-
### No Breaking Changes for Users
|
|
534
|
-
|
|
535
|
-
**Important:** All v0.7.x tool calls, parameters, and responses work identically in v0.8.x. This section is for developers working with the internal architecture.
|
|
536
|
-
|
|
537
|
-
### Internal API Changes
|
|
538
|
-
|
|
539
|
-
#### Error Handling Migration
|
|
540
|
-
|
|
541
|
-
**v0.7.x Pattern:**
|
|
542
|
-
```typescript
|
|
543
|
-
// Direct error throwing
|
|
544
|
-
if (!budgetId) {
|
|
545
|
-
throw new Error('No budget ID provided');
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**v0.8.x Pattern:**
|
|
550
|
-
```typescript
|
|
551
|
-
// Centralized error handling with consistent format
|
|
552
|
-
const result = BudgetResolver.resolveBudgetId(providedId, defaultId);
|
|
553
|
-
if (typeof result !== 'string') {
|
|
554
|
-
return result; // Returns properly formatted CallToolResult
|
|
555
|
-
}
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
#### Caching Migration
|
|
559
|
-
|
|
560
|
-
**v0.7.x Pattern:**
|
|
561
|
-
```typescript
|
|
562
|
-
// Manual cache management
|
|
563
|
-
const cached = cacheManager.get(key);
|
|
564
|
-
if (cached && !isExpired(cached)) {
|
|
565
|
-
return cached.data;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
const result = await apiCall();
|
|
569
|
-
cacheManager.set(key, result, ttl);
|
|
570
|
-
return result;
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
**v0.8.x Pattern:**
|
|
574
|
-
```typescript
|
|
575
|
-
// Enhanced cache wrapper with observability
|
|
576
|
-
return cacheManager.wrap(key, {
|
|
577
|
-
ttl: CACHE_TTLS.ACCOUNTS,
|
|
578
|
-
staleWhileRevalidate: 120000,
|
|
579
|
-
loader: () => apiCall()
|
|
580
|
-
});
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
#### Tool Registration Migration
|
|
584
|
-
|
|
585
|
-
**v0.7.x Pattern:**
|
|
586
|
-
```typescript
|
|
587
|
-
// Direct switch statement in handleCallTool
|
|
588
|
-
case 'my_tool':
|
|
589
|
-
return withSecurityWrapper(async () => {
|
|
590
|
-
const validated = MyToolSchema.parse(params);
|
|
591
|
-
return await handleMyTool(validated);
|
|
592
|
-
});
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
**v0.8.x Pattern:**
|
|
596
|
-
```typescript
|
|
597
|
-
// Registry-based registration
|
|
598
|
-
registry.register({
|
|
599
|
-
name: 'my_tool',
|
|
600
|
-
description: 'Tool description',
|
|
601
|
-
inputSchema: MyToolSchema,
|
|
602
|
-
handler: adapt(handleMyTool),
|
|
603
|
-
defaultArgumentResolver: resolveBudgetId()
|
|
604
|
-
});
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
### Testing Pattern Updates
|
|
608
|
-
|
|
609
|
-
**Enhanced Dependency Injection for Testing:**
|
|
610
|
-
|
|
611
|
-
```typescript
|
|
612
|
-
// v0.8.x - Mock individual services
|
|
613
|
-
const mockCacheManager = {
|
|
614
|
-
wrap: vi.fn().mockImplementation((key, options) => options.loader()),
|
|
615
|
-
getStats: vi.fn().mockReturnValue({ hit_rate: 0.5 })
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
const mockErrorHandler = {
|
|
619
|
-
createErrorResponse: vi.fn().mockReturnValue({ success: false })
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
// Test with mocked dependencies
|
|
623
|
-
const service = new MyService(mockCacheManager, mockErrorHandler);
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### Import Path Updates
|
|
627
|
-
|
|
628
|
-
Most imports remain the same due to barrel exports:
|
|
629
|
-
|
|
630
|
-
```typescript
|
|
631
|
-
// Still works (barrel export)
|
|
632
|
-
import { handleMyTool } from '../tools/myTool.js';
|
|
633
|
-
|
|
634
|
-
// New modular imports available
|
|
635
|
-
import { parseCSV } from '../tools/compareTransactions/parser.js';
|
|
636
|
-
import { findMatches } from '../tools/compareTransactions/matcher.js';
|
|
637
|
-
import { formatResults } from '../tools/compareTransactions/formatter.js';
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
### Performance Improvements to Expect
|
|
641
|
-
|
|
642
|
-
- **Cache Hit Rate**: 60-80% for repeated operations
|
|
643
|
-
- **Initial Load Time**: Faster due to cache warming
|
|
644
|
-
- **Memory Usage**: More efficient with LRU eviction
|
|
645
|
-
- **Error Response Time**: Faster with pre-formatted responses
|
|
646
|
-
|
|
647
530
|
---
|
|
648
531
|
|
|
649
532
|
For practical development patterns and examples, see [`DEVELOPMENT.md`](DEVELOPMENT.md).
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Reloadable Config & Token Validation Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Make config parsing reloadable for env-mutation tests/CI, harden token validation against malformed responses, and confirm integration runs with a valid YNAB token.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Parse env vars on-demand via `loadConfig()` (with a backward-compatible `config` singleton), inject per-server config instances instead of module globals, and wrap YNAB token validation failures (including non-JSON responses) into `AuthenticationError` with clear messaging.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node + TypeScript, Zod, dotenv, Vitest, YNAB SDK, esbuild.
|
|
10
|
+
|
|
11
|
+
### Task 1: Reloadable config loader
|
|
12
|
+
|
|
13
|
+
**Files:**
|
|
14
|
+
- Modify: `src/server/config.ts`
|
|
15
|
+
- Modify: `src/server/__tests__/config.test.ts`
|
|
16
|
+
|
|
17
|
+
**Step 1: Write failing test**
|
|
18
|
+
Add a test that calls `loadConfig()` twice after mutating `process.env.YNAB_ACCESS_TOKEN` (without re-importing the module) and expects the second call to return the updated token.
|
|
19
|
+
|
|
20
|
+
**Step 2: Run test to verify failure**
|
|
21
|
+
Run `npx vitest run src/server/__tests__/config.test.ts` and confirm the new test fails because the loader is still tied to initial state.
|
|
22
|
+
|
|
23
|
+
**Step 3: Implement reloadable loader**
|
|
24
|
+
Keep the Zod schema and explicit `config` singleton, but ensure `loadConfig()` re-parses `process.env` on every call (optionally allowing an env override for tests) and throws `ValidationError` on failure; keep `import 'dotenv/config'` so `.env` is loaded for Node execution.
|
|
25
|
+
|
|
26
|
+
**Step 4: Re-run targeted test**
|
|
27
|
+
Re-run `npx vitest run src/server/__tests__/config.test.ts` to confirm the reloadable behavior passes.
|
|
28
|
+
|
|
29
|
+
### Task 2: Inject per-instance config into YNABMCPServer
|
|
30
|
+
|
|
31
|
+
**Files:**
|
|
32
|
+
- Modify: `src/server/YNABMCPServer.ts`
|
|
33
|
+
- Modify: `src/server/__tests__/YNABMCPServer.test.ts`
|
|
34
|
+
- Modify: `src/server/__tests__/server-startup.integration.test.ts`
|
|
35
|
+
|
|
36
|
+
**Step 1: Add/adjust tests**
|
|
37
|
+
Add coverage that changing `process.env.YNAB_ACCESS_TOKEN` before constructing a new `YNABMCPServer` produces a server wired to the new token (no module cache reset), and update expectations to align with `ValidationError` from `loadConfig()` where appropriate.
|
|
38
|
+
|
|
39
|
+
**Step 2: Run tests to see failures**
|
|
40
|
+
Run `npx vitest run src/server/__tests__/YNABMCPServer.test.ts src/server/__tests__/server-startup.integration.test.ts`.
|
|
41
|
+
|
|
42
|
+
**Step 3: Apply code changes**
|
|
43
|
+
Ensure the constructor stores `const configInstance = loadConfig()` and uses it for YNAB API creation, token validation, and tool execution auth; remove any lingering usage of the `config` singleton for runtime behavior.
|
|
44
|
+
|
|
45
|
+
**Step 4: Re-run the affected tests**
|
|
46
|
+
Re-run the same Vitest targets to verify per-instance config wiring passes.
|
|
47
|
+
|
|
48
|
+
### Task 3: Token validation resilience
|
|
49
|
+
|
|
50
|
+
**Files:**
|
|
51
|
+
- Modify: `src/server/YNABMCPServer.ts`
|
|
52
|
+
- Modify: `src/server/__tests__/server-startup.integration.test.ts`
|
|
53
|
+
|
|
54
|
+
**Step 1: Write failing test**
|
|
55
|
+
Mock `ynab.API().user.getUser` to reject with a `SyntaxError`/HTML-shaped error and expect `validateToken()` to reject with `AuthenticationError("Unexpected response from YNAB during token validation")` instead of surfacing the raw syntax failure.
|
|
56
|
+
|
|
57
|
+
**Step 2: Run test to confirm failure**
|
|
58
|
+
Run `npx vitest run src/server/__tests__/server-startup.integration.test.ts`.
|
|
59
|
+
|
|
60
|
+
**Step 3: Implement graceful handling**
|
|
61
|
+
Wrap token validation to catch non-JSON/SyntaxError cases (or responses lacking expected shape) and throw `AuthenticationError` with the clear message while preserving existing 401/403 mapping.
|
|
62
|
+
|
|
63
|
+
**Step 4: Re-run validation tests**
|
|
64
|
+
Re-run the targeted integration test to ensure the new mapping passes.
|
|
65
|
+
|
|
66
|
+
### Task 4: Test alignment & runner portability
|
|
67
|
+
|
|
68
|
+
**Files:**
|
|
69
|
+
- Modify: `src/server/__tests__/config.test.ts`
|
|
70
|
+
- Modify: `scripts/run-throttled-integration-tests.js`
|
|
71
|
+
|
|
72
|
+
**Step 1: Align config test patterns**
|
|
73
|
+
Update any assertions relying on module-level parsing side effects to use `vi.resetModules()` + `loadConfig()` explicitly for reload checks; keep singleton expectations where intentional.
|
|
74
|
+
|
|
75
|
+
**Step 2: Harden integration runner on Windows**
|
|
76
|
+
Change the throttled runner to spawn Vitest via a platform-portable path (e.g., `node` + resolved `vitest` bin) to avoid `spawn EINVAL` with `.cmd` on Windows.
|
|
77
|
+
|
|
78
|
+
**Step 3: Run quick smoke**
|
|
79
|
+
Run `node scripts/run-throttled-integration-tests.js --help` or kick a single file to ensure the wrapper executes without path errors.
|
|
80
|
+
|
|
81
|
+
### Task 5: Full verification
|
|
82
|
+
|
|
83
|
+
**Files/Commands:**
|
|
84
|
+
- Commands: `npm test`, `npm run test:integration:core` (with `YNAB_ACCESS_TOKEN` set), optionally `npm run test:integration:domain`.
|
|
85
|
+
|
|
86
|
+
**Step 1: Run unit suite**
|
|
87
|
+
Execute `npm test` to ensure unit coverage stays green.
|
|
88
|
+
|
|
89
|
+
**Step 2: Run core integrations with real token**
|
|
90
|
+
Execute `npm run test:integration:core` using a known-good `YNAB_ACCESS_TOKEN`; capture any regressions.
|
|
91
|
+
|
|
92
|
+
**Step 3: Optional extended coverage**
|
|
93
|
+
If time permits, run `npm run test:integration:domain` for broader confidence; note any skips or rate-limit impacts.
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# Fix Missing `cached` Property in Large Transaction Responses
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Fix GitHub Action test failure by adding the missing `cached` property to large transaction list responses.
|
|
6
|
+
|
|
7
|
+
**Architecture:** The `handleListTransactions` function in `transactionTools.ts` has two response paths: normal (lines 815+) and large response (lines 788-812). The large response path is missing the `cached` and `cache_info` properties that the normal path includes, causing test assertion failures when transaction data exceeds 90KB.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Vitest, YNAB API integration tests
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Background
|
|
14
|
+
|
|
15
|
+
**Current Issue:**
|
|
16
|
+
- GitHub Action failing: `src/tools/__tests__/accountTools.delta.integration.test.ts:94`
|
|
17
|
+
- Error: `expected undefined to be false // Object.is equality`
|
|
18
|
+
- Test code: `expect(firstPayload.cached).toBe(false);`
|
|
19
|
+
|
|
20
|
+
**Root Cause:**
|
|
21
|
+
File `src/tools/transactionTools.ts` has two response code paths:
|
|
22
|
+
1. **Large response path** (lines 788-812): When transactions > 90KB, returns preview + summary
|
|
23
|
+
2. **Normal path** (lines 815+): Returns full transaction list
|
|
24
|
+
|
|
25
|
+
The large response path returns an object WITHOUT the `cached` property.
|
|
26
|
+
The normal path returns an object WITH `cached: cacheHit` and `cache_info`.
|
|
27
|
+
|
|
28
|
+
**Test accounts with many transactions trigger the large response path, causing `cached` to be undefined.**
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Task 1: Add Unit Test Coverage for Large Response Path
|
|
33
|
+
|
|
34
|
+
**Files:**
|
|
35
|
+
- Read: `src/tools/__tests__/transactionTools.test.ts`
|
|
36
|
+
- Modify: `src/tools/__tests__/transactionTools.test.ts` (add test after existing tests)
|
|
37
|
+
|
|
38
|
+
**Step 1: Read the existing test file to understand patterns**
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cat src/tools/__tests__/transactionTools.test.ts | head -100
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Expected: See test structure, mocking patterns, imports
|
|
45
|
+
|
|
46
|
+
**Step 2: Write failing test for large response cached property**
|
|
47
|
+
|
|
48
|
+
Add this test to `src/tools/__tests__/transactionTools.test.ts` in the appropriate describe block:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
it('should include cached property in large response path', async () => {
|
|
52
|
+
// Create large transaction list (> 90KB)
|
|
53
|
+
const largeTransactionList: ynab.TransactionDetail[] = [];
|
|
54
|
+
for (let i = 0; i < 5000; i++) {
|
|
55
|
+
largeTransactionList.push({
|
|
56
|
+
id: `transaction-${i}`,
|
|
57
|
+
date: '2025-01-01',
|
|
58
|
+
amount: -10000,
|
|
59
|
+
memo: 'Test transaction with long memo to increase size '.repeat(10),
|
|
60
|
+
cleared: 'cleared',
|
|
61
|
+
approved: true,
|
|
62
|
+
flag_color: null,
|
|
63
|
+
account_id: 'test-account',
|
|
64
|
+
payee_id: null,
|
|
65
|
+
category_id: null,
|
|
66
|
+
transfer_account_id: null,
|
|
67
|
+
transfer_transaction_id: null,
|
|
68
|
+
matched_transaction_id: null,
|
|
69
|
+
import_id: null,
|
|
70
|
+
import_payee_name: null,
|
|
71
|
+
import_payee_name_original: null,
|
|
72
|
+
debt_transaction_type: null,
|
|
73
|
+
deleted: false,
|
|
74
|
+
account_name: 'Test Account',
|
|
75
|
+
payee_name: 'Test Payee',
|
|
76
|
+
category_name: 'Test Category',
|
|
77
|
+
subtransactions: [],
|
|
78
|
+
} as ynab.TransactionDetail);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const mockDeltaFetcher = {
|
|
82
|
+
fetchTransactionsByAccount: vi.fn().mockResolvedValue({
|
|
83
|
+
data: largeTransactionList,
|
|
84
|
+
wasCached: false,
|
|
85
|
+
usedDelta: false,
|
|
86
|
+
}),
|
|
87
|
+
} as unknown as DeltaFetcher;
|
|
88
|
+
|
|
89
|
+
const result = await handleListTransactions(mockYnabAPI, mockDeltaFetcher, {
|
|
90
|
+
budget_id: 'test-budget',
|
|
91
|
+
account_id: 'test-account',
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const content = result.content?.[0];
|
|
95
|
+
expect(content).toBeDefined();
|
|
96
|
+
expect(content?.type).toBe('text');
|
|
97
|
+
|
|
98
|
+
const parsedResponse = JSON.parse(content!.text);
|
|
99
|
+
|
|
100
|
+
// Should have cached property even in large response path
|
|
101
|
+
expect(parsedResponse.cached).toBeDefined();
|
|
102
|
+
expect(parsedResponse.cached).toBe(false);
|
|
103
|
+
expect(parsedResponse.cache_info).toBeDefined();
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Step 3: Run the test to verify it fails**
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run test:unit -- src/tools/__tests__/transactionTools.test.ts -t "should include cached property in large response path"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Expected: FAIL with error about `cached` being undefined
|
|
114
|
+
|
|
115
|
+
**Step 4: Commit the failing test**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
git add src/tools/__tests__/transactionTools.test.ts
|
|
119
|
+
git commit -m "test: add failing test for cached property in large transaction responses"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Task 2: Fix Large Response Path to Include Cached Property
|
|
125
|
+
|
|
126
|
+
**Files:**
|
|
127
|
+
- Modify: `src/tools/transactionTools.ts:788-812`
|
|
128
|
+
|
|
129
|
+
**Step 1: Read the current large response code**
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cat src/tools/transactionTools.ts | sed -n '788,812p'
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Expected: See the current implementation missing `cached` and `cache_info`
|
|
136
|
+
|
|
137
|
+
**Step 2: Add cached properties to large response**
|
|
138
|
+
|
|
139
|
+
In `src/tools/transactionTools.ts`, replace lines 788-812 with:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
if (estimatedSize > sizeLimit) {
|
|
143
|
+
// Return summary and suggest export
|
|
144
|
+
const preview = transactions.slice(0, 50);
|
|
145
|
+
return {
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: 'text',
|
|
149
|
+
text: responseFormatter.format({
|
|
150
|
+
message: `Found ${transactions.length} transactions (${Math.round(estimatedSize / 1024)}KB). Too large to display all.`,
|
|
151
|
+
suggestion: "Use 'export_transactions' tool to save all transactions to a file.",
|
|
152
|
+
showing: `First ${preview.length} transactions:`,
|
|
153
|
+
total_count: transactions.length,
|
|
154
|
+
estimated_size_kb: Math.round(estimatedSize / 1024),
|
|
155
|
+
cached: cacheHit,
|
|
156
|
+
cache_info: cacheHit
|
|
157
|
+
? `Data retrieved from cache for improved performance${usedDelta ? ' (delta merge applied)' : ''}`
|
|
158
|
+
: 'Fresh data retrieved from YNAB API',
|
|
159
|
+
preview_transactions: preview.map((transaction) => ({
|
|
160
|
+
id: transaction.id,
|
|
161
|
+
date: transaction.date,
|
|
162
|
+
amount: milliunitsToAmount(transaction.amount),
|
|
163
|
+
memo: transaction.memo,
|
|
164
|
+
payee_name: transaction.payee_name,
|
|
165
|
+
category_name: transaction.category_name,
|
|
166
|
+
})),
|
|
167
|
+
}),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Changes:**
|
|
175
|
+
- Added `cached: cacheHit,` after `estimated_size_kb`
|
|
176
|
+
- Added `cache_info` with same pattern as normal response path
|
|
177
|
+
|
|
178
|
+
**Step 3: Run unit tests to verify fix**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
npm run test:unit -- src/tools/__tests__/transactionTools.test.ts -t "should include cached property in large response path"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Expected: PASS
|
|
185
|
+
|
|
186
|
+
**Step 4: Run all transaction tool tests**
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
npm run test:unit -- src/tools/__tests__/transactionTools.test.ts
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Expected: All tests PASS
|
|
193
|
+
|
|
194
|
+
**Step 5: Commit the fix**
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
git add src/tools/transactionTools.ts
|
|
198
|
+
git commit -m "fix: add cached property to large transaction response path
|
|
199
|
+
|
|
200
|
+
- Large responses (>90KB) now include cached and cache_info properties
|
|
201
|
+
- Maintains consistency with normal response path
|
|
202
|
+
- Fixes test failure in delta integration tests"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Task 3: Verify Integration Test Now Passes
|
|
208
|
+
|
|
209
|
+
**Files:**
|
|
210
|
+
- Test: `src/tools/__tests__/accountTools.delta.integration.test.ts`
|
|
211
|
+
|
|
212
|
+
**Step 1: Run the failing integration test locally**
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npm run test:integration -- src/tools/__tests__/accountTools.delta.integration.test.ts -t "reports delta usage for list_transactions after a change"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Expected: PASS (requires YNAB_ACCESS_TOKEN environment variable)
|
|
219
|
+
|
|
220
|
+
Note: If you don't have a YNAB token or want to skip, this is acceptable - the GitHub Action will verify.
|
|
221
|
+
|
|
222
|
+
**Step 2: Run type checking**
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm run type-check
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Expected: No TypeScript errors
|
|
229
|
+
|
|
230
|
+
**Step 3: Run all unit tests to ensure no regressions**
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
npm run test:unit
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Expected: All tests PASS
|
|
237
|
+
|
|
238
|
+
**Step 4: Commit verification checkpoint**
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
git add -A
|
|
242
|
+
git commit -m "test: verify integration test passes with cached property fix"
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Task 4: Update CHANGELOG and Documentation
|
|
248
|
+
|
|
249
|
+
**Files:**
|
|
250
|
+
- Modify: `CHANGELOG.md` (add entry at top of Unreleased section)
|
|
251
|
+
|
|
252
|
+
**Step 1: Add CHANGELOG entry**
|
|
253
|
+
|
|
254
|
+
Add this entry to the `## [Unreleased]` section in `CHANGELOG.md`:
|
|
255
|
+
|
|
256
|
+
```markdown
|
|
257
|
+
### Fixed
|
|
258
|
+
- Fixed missing `cached` property in large transaction list responses (>90KB)
|
|
259
|
+
- Large response path now includes `cached` and `cache_info` properties
|
|
260
|
+
- Maintains consistency with normal response path
|
|
261
|
+
- Resolves integration test failures when accounts have many transactions
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Step 2: Commit documentation**
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
git add CHANGELOG.md
|
|
268
|
+
git commit -m "docs: add CHANGELOG entry for cached property fix"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Task 5: Push and Verify GitHub Action
|
|
274
|
+
|
|
275
|
+
**Files:**
|
|
276
|
+
- Remote: GitHub Actions CI
|
|
277
|
+
|
|
278
|
+
**Step 1: Push all commits to remote**
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
git push origin HEAD
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Expected: Push successful
|
|
285
|
+
|
|
286
|
+
**Step 2: Monitor GitHub Action**
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
gh run watch
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Expected:
|
|
293
|
+
- Job `unit-tests` should PASS
|
|
294
|
+
- Job `integration-core` should PASS (was previously failing at accountTools.delta.integration.test.ts)
|
|
295
|
+
|
|
296
|
+
**Step 3: Verify specific test that was failing**
|
|
297
|
+
|
|
298
|
+
Check GitHub Action logs for:
|
|
299
|
+
```
|
|
300
|
+
✓ src/tools/__tests__/accountTools.delta.integration.test.ts > Delta-backed account tool handlers > reports delta usage for list_transactions after a change
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Expected: Green checkmark, no assertion errors
|
|
304
|
+
|
|
305
|
+
**Step 4: Create completion summary**
|
|
306
|
+
|
|
307
|
+
Document verification results:
|
|
308
|
+
```markdown
|
|
309
|
+
## Verification Complete
|
|
310
|
+
|
|
311
|
+
- ✅ Unit tests passing locally
|
|
312
|
+
- ✅ Integration tests passing locally (if run)
|
|
313
|
+
- ✅ Type checking passing
|
|
314
|
+
- ✅ GitHub Actions CI passing
|
|
315
|
+
- ✅ Specific failing test now passes
|
|
316
|
+
|
|
317
|
+
The `cached` property is now consistently included in all transaction list responses.
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Testing Strategy
|
|
323
|
+
|
|
324
|
+
**Unit Tests:**
|
|
325
|
+
- New test verifies large response path includes `cached` property
|
|
326
|
+
- Existing tests verify normal response path unchanged
|
|
327
|
+
|
|
328
|
+
**Integration Tests:**
|
|
329
|
+
- `accountTools.delta.integration.test.ts` verifies delta fetcher integration
|
|
330
|
+
- Test creates real transaction, expects `cached: false` on first call
|
|
331
|
+
- Was failing because large accounts returned `cached: undefined`
|
|
332
|
+
|
|
333
|
+
**Manual Verification:**
|
|
334
|
+
- GitHub Action will run full integration suite with real YNAB API
|
|
335
|
+
- Throttled test runner prevents rate limit issues
|
|
336
|
+
- Sequential execution ensures reliable results
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Rate Limiting Context (For Reference)
|
|
341
|
+
|
|
342
|
+
**Note:** The GitHub Action failure was NOT a rate limiting issue. The codebase already has excellent rate limiting:
|
|
343
|
+
|
|
344
|
+
**Existing Rate Limit Infrastructure:**
|
|
345
|
+
- `scripts/run-throttled-integration-tests.js` - Sequential test execution with request tracking
|
|
346
|
+
- Client-side throttling (200 req/hour with 20 req buffer)
|
|
347
|
+
- Request history pruning (60-minute sliding window)
|
|
348
|
+
- Intelligent wait logic with min/max bounds
|
|
349
|
+
- Per-test estimated API call counts
|
|
350
|
+
|
|
351
|
+
**No changes needed to rate limiting.** The issue was purely a missing property in the response object.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Success Criteria
|
|
356
|
+
|
|
357
|
+
- ✅ Unit test passes for large response cached property
|
|
358
|
+
- ✅ Integration test `accountTools.delta.integration.test.ts:94` passes
|
|
359
|
+
- ✅ GitHub Action CI pipeline passes completely
|
|
360
|
+
- ✅ No TypeScript errors
|
|
361
|
+
- ✅ CHANGELOG updated
|
|
362
|
+
- ✅ All commits follow conventional commit format
|