@dizzlkheinz/ynab-mcpb 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. package/.chunkhound.json +11 -0
  2. package/.code/agents/0427d95e-edca-431f-a214-5e53264e29c4/error.txt +8 -0
  3. package/.code/agents/0d675174-d1e1-41c3-9975-4c2e275819a9/error.txt +3 -0
  4. package/.code/agents/0d8c5afd-4787-422b-abf8-2e5943fc7e67/error.txt +3 -0
  5. package/.code/agents/0ec34a70-ed5d-4b9e-bee4-bb0e4cccbc4b/error.txt +1 -0
  6. package/.code/agents/0ef51a21-1ab1-49d7-9561-0eaa43875ebc/error.txt +12 -0
  7. package/.code/agents/15db95d7-abad-4b4d-9c3b-8446089cb61d/error.txt +1 -0
  8. package/.code/agents/19ab9acb-f675-4ff0-902a-09a5476f8149/error.txt +1 -0
  9. package/.code/agents/1ef7e12d-f6ff-4897-8a9b-152d523d898e/error.txt +5 -0
  10. package/.code/agents/2465/exec-call_lroN9KKzJVWC7t5423DK1nT9.txt +1453 -0
  11. package/.code/agents/28edb6fe-95a9-41a0-ae69-aa0100d26c0c/error.txt +8 -0
  12. package/.code/agents/2ae40cf5-b4bf-42e2-92bf-7ea350a7755e/error.txt +9 -0
  13. package/.code/agents/2bfc4e1f-ac4b-45a5-b6df-bf89d4dbb54c/error.txt +1 -0
  14. package/.code/agents/2e2e1134-eff0-49be-ba25-8e2c3468a564/error.txt +5 -0
  15. package/.code/agents/3/exec-call_203OC4TNVkLxW7z2HCVEQ1cM.txt +81 -0
  16. package/.code/agents/3/exec-call_SS5T0XSiXB4LSNzUKTl75wkh.txt +610 -0
  17. package/.code/agents/3322c003-ce5e-48e3-a342-f5049c5bf9a2/error.txt +1 -0
  18. package/.code/agents/391e9b08-1ebc-468c-9bcd-6d0cc3193b37/error.txt +1 -0
  19. package/.code/agents/3ab0aa84-b7bb-4054-afa3-40b8fd7d3be0/error.txt +1 -0
  20. package/.code/agents/3bed368d-50fe-477e-aee3-a6707eaa1ab9/error.txt +3 -0
  21. package/.code/agents/3e40b925-db12-442f-8d7a-a25fc69a6672/error.txt +8 -0
  22. package/.code/agents/414d5776-cf58-41f3-9328-a6daed503a50/error.txt +5 -0
  23. package/.code/agents/42687751-4565-4610-b240-67835b17d861/error.txt +1 -0
  24. package/.code/agents/46b98876-1a39-43c9-9e2f-507ca6d47335/error.txt +9 -0
  25. package/.code/agents/4a7d9491-b26f-43dd-850d-2ecdc49b5d1b/error.txt +1 -0
  26. package/.code/agents/4e60f00a-1b3e-447f-87f3-7faf9deddec3/error.txt +13 -0
  27. package/.code/agents/5138fc1c-4d49-4b74-a7da-ccdb3a8e44e7/error.txt +14 -0
  28. package/.code/agents/521cff39-a7a3-42e5-a557-134f0f7daaa0/error.txt +5 -0
  29. package/.code/agents/53302dc5-3857-4413-9a47-9e0f64a51dc4/error.txt +5 -0
  30. package/.code/agents/567c7c2e-6a6f-4761-a08d-d36deeb2e0ac/error.txt +5 -0
  31. package/.code/agents/57b00845-80dc-47c9-953c-3028d16275d6/error.txt +3 -0
  32. package/.code/agents/593d9005-c2a5-48fd-8813-ece0d3f2de96/error.txt +1 -0
  33. package/.code/agents/5a112e66-0e1a-42f9-877c-53af56ea3551/error.txt +1 -0
  34. package/.code/agents/5b05e8ed-7788-4738-b7ee-9faa8180f992/error.txt +5 -0
  35. package/.code/agents/5f888d6f-d7ca-4ac8-be23-9ea1bf753951/error.txt +5 -0
  36. package/.code/agents/607db3ab-e4b0-435b-b497-93e9aa525549/error.txt +8 -0
  37. package/.code/agents/67dcb2a2-900f-4c78-b3fc-80b5213e0ddf/error.txt +8 -0
  38. package/.code/agents/69ad848c-4e98-49b3-b16c-0094ac2d1759/error.txt +5 -0
  39. package/.code/agents/6c9cfc5f-0d0b-445c-b121-9f60082c4f70/error.txt +1 -0
  40. package/.code/agents/6f6f8f77-4ab0-4f6e-9f30-40e8be0bd8f5/error.txt +1 -0
  41. package/.code/agents/72a7cde4-fa8a-4024-9038-27faa550539b/error.txt +1 -0
  42. package/.code/agents/7b48335c-8247-43aa-9949-5f820ba8e199/error.txt +1 -0
  43. package/.code/agents/80944249-bea9-4ac5-87de-a666c4df306e/error.txt +1 -0
  44. package/.code/agents/826099df-1b66-4186-a915-7eb59f9db19d/error.txt +5 -0
  45. package/.code/agents/8291d158-18a8-4a92-b799-4e9a4d9cce88/error.txt +1 -0
  46. package/.code/agents/82fb71a3-20fb-4341-804a-a2fc900f95bc/error.txt +1 -0
  47. package/.code/agents/855790ea-54ee-43e4-8209-a66994e37590/error.txt +1 -0
  48. package/.code/agents/88ce3a2e-04f2-42be-9062-bf97aa798da0/error.txt +3 -0
  49. package/.code/agents/9a17e398-b6ed-4218-bb55-bc64a8d38ce8/error.txt +8 -0
  50. package/.code/agents/9a4f4bfc-a2a6-4f40-a896-9335b41a7ed1/error.txt +1 -0
  51. package/.code/agents/9b633e55-ef84-47d6-94bb-fd3dd172ad97/error.txt +1 -0
  52. package/.code/agents/9b81f3ab-c72b-4a81-9a8f-28a49ddba84a/error.txt +8 -0
  53. package/.code/agents/a35daf29-b2d1-4aef-9b42-dad63a76bd47/error.txt +3 -0
  54. package/.code/agents/a81990cc-69ee-44d2-b907-17403c9bc5d7/error.txt +5 -0
  55. package/.code/agents/ab56260a-4a83-4ad4-9410-f88a23d6520a/error.txt +1 -0
  56. package/.code/agents/ad722c31-2d1d-45f7-bae2-3f02ca455b60/error.txt +1 -0
  57. package/.code/agents/b62e8690-3324-4b97-9309-731bee79416b/error.txt +5 -0
  58. package/.code/agents/baf60a3a-752b-4ad8-99d6-df32423ed2eb/error.txt +1 -0
  59. package/.code/agents/be049042-7dcb-4ac8-9beb-c8f1aea67742/error.txt +14 -0
  60. package/.code/agents/bed1dcb4-bfce-4a9f-8594-0f994962aafd/error.txt +1 -0
  61. package/.code/agents/c324a6cf-e935-4ede-9529-b3ebc18e8d6b/error.txt +5 -0
  62. package/.code/agents/c37c06ff-dfe3-43f2-9bbc-3ec73ec8f41d/error.txt +5 -0
  63. package/.code/agents/c8cd6671-433a-456b-9f88-e51cb2df6bfc/error.txt +11 -0
  64. package/.code/agents/ca2ccb67-2f24-428e-b27d-9365beadd140/error.txt +1 -0
  65. package/.code/agents/cf08c0c8-e7f0-423e-93ba-547e8e818340/error.txt +8 -0
  66. package/.code/agents/d579c74f-874b-40a4-9d56-ced1eb6a701d/error.txt +1 -0
  67. package/.code/agents/df412c98-7378-4deb-8e1e-76c416931181/error.txt +3 -0
  68. package/.code/agents/e5134eb3-2af4-45b0-8998-051cb4afdb45/error.txt +3 -0
  69. package/.code/agents/e6308471-aa45-4e9e-9496-2e9404164d97/error.txt +8 -0
  70. package/.code/agents/e7bd8bc7-23fb-4f46-98dc-b0dcf11b75a1/error.txt +1 -0
  71. package/.code/agents/e92bec35-378d-4fe1-8ac0-6e1bb3c86911/error.txt +5 -0
  72. package/.code/agents/ed918fbf-2dc4-4aa2-bfc5-04b65d9471ea/error.txt +1 -0
  73. package/.code/agents/ef1d756f-b272-48fc-8729-f05c494674f7/error.txt +1 -0
  74. package/.code/agents/ef359853-0249-4e41-a804-c0fc459fe456/error.txt +1 -0
  75. package/.code/agents/effc7b4a-4b90-40a0-8c86-a7a99d2d5fd2/error.txt +1 -0
  76. package/.code/agents/fa15f8d5-8359-4a8b-83a3-2f2056b3ff40/error.txt +3 -0
  77. package/.code/agents/fbef4193-eadf-4c8a-83ff-4878a6310f25/error.txt +8 -0
  78. package/.code/agents/fd0a4b4a-fda4-4964-a6d6-2b8a2da387c6/error.txt +1 -0
  79. package/.dxtignore +57 -0
  80. package/.env.example +44 -0
  81. package/.gemini/settings.json +8 -0
  82. package/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
  83. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  84. package/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  85. package/.github/ISSUE_TEMPLATE/release_checklist.md +31 -0
  86. package/.github/pull_request_template.md +41 -0
  87. package/.github/workflows/ci-tests.yml +41 -0
  88. package/.github/workflows/claude-code-review.yml +57 -0
  89. package/.github/workflows/claude.yml +50 -0
  90. package/.github/workflows/full-integration.yml +22 -0
  91. package/.github/workflows/pr-description-check.yml +88 -0
  92. package/.github/workflows/publish.yml +33 -0
  93. package/.github/workflows/release.yml +89 -0
  94. package/.mcpbignore +58 -0
  95. package/.prettierignore +10 -0
  96. package/.prettierrc.json +10 -0
  97. package/ADOS-2-Module-1-Complete-Manual.md +757 -0
  98. package/AGENTS.md +36 -0
  99. package/CHANGELOG.md +187 -0
  100. package/CLAUDE.md +414 -0
  101. package/CODEREVIEW_RESPONSE.md +128 -0
  102. package/LICENSE +17 -0
  103. package/NUL +1 -0
  104. package/README.md +222 -0
  105. package/SCHEMA_IMPROVEMENT_SUMMARY.md +120 -0
  106. package/TESTING_NOTES.md +217 -0
  107. package/WARP.md +245 -0
  108. package/accountactivity-merged.csv +149 -0
  109. package/bin/ynab-mcp-server.cjs +4 -0
  110. package/bin/ynab-mcp-server.js +8 -0
  111. package/bundle-analysis.html +13110 -0
  112. package/dist/bundle/index.cjs +124 -0
  113. package/dist/index.d.ts +2 -0
  114. package/dist/index.js +85 -0
  115. package/dist/server/YNABMCPServer.d.ts +264 -0
  116. package/dist/server/YNABMCPServer.js +845 -0
  117. package/dist/server/budgetResolver.d.ts +15 -0
  118. package/dist/server/budgetResolver.js +99 -0
  119. package/dist/server/cacheManager.d.ts +74 -0
  120. package/dist/server/cacheManager.js +306 -0
  121. package/dist/server/config.d.ts +3 -0
  122. package/dist/server/config.js +19 -0
  123. package/dist/server/deltaCache.d.ts +61 -0
  124. package/dist/server/deltaCache.js +206 -0
  125. package/dist/server/deltaCache.merge.d.ts +9 -0
  126. package/dist/server/deltaCache.merge.js +111 -0
  127. package/dist/server/diagnostics.d.ts +90 -0
  128. package/dist/server/diagnostics.js +163 -0
  129. package/dist/server/errorHandler.d.ts +69 -0
  130. package/dist/server/errorHandler.js +524 -0
  131. package/dist/server/prompts.d.ts +31 -0
  132. package/dist/server/prompts.js +205 -0
  133. package/dist/server/rateLimiter.d.ts +27 -0
  134. package/dist/server/rateLimiter.js +82 -0
  135. package/dist/server/requestLogger.d.ts +62 -0
  136. package/dist/server/requestLogger.js +190 -0
  137. package/dist/server/resources.d.ts +39 -0
  138. package/dist/server/resources.js +85 -0
  139. package/dist/server/responseFormatter.d.ts +14 -0
  140. package/dist/server/responseFormatter.js +42 -0
  141. package/dist/server/securityMiddleware.d.ts +87 -0
  142. package/dist/server/securityMiddleware.js +117 -0
  143. package/dist/server/serverKnowledgeStore.d.ts +11 -0
  144. package/dist/server/serverKnowledgeStore.js +42 -0
  145. package/dist/server/toolRegistry.d.ts +85 -0
  146. package/dist/server/toolRegistry.js +272 -0
  147. package/dist/tools/__tests__/deltaTestUtils.d.ts +18 -0
  148. package/dist/tools/__tests__/deltaTestUtils.js +26 -0
  149. package/dist/tools/accountTools.d.ts +37 -0
  150. package/dist/tools/accountTools.js +175 -0
  151. package/dist/tools/budgetTools.d.ts +10 -0
  152. package/dist/tools/budgetTools.js +68 -0
  153. package/dist/tools/categoryTools.d.ts +27 -0
  154. package/dist/tools/categoryTools.js +232 -0
  155. package/dist/tools/compareTransactions/formatter.d.ts +71 -0
  156. package/dist/tools/compareTransactions/formatter.js +97 -0
  157. package/dist/tools/compareTransactions/index.d.ts +30 -0
  158. package/dist/tools/compareTransactions/index.js +160 -0
  159. package/dist/tools/compareTransactions/matcher.d.ts +12 -0
  160. package/dist/tools/compareTransactions/matcher.js +140 -0
  161. package/dist/tools/compareTransactions/parser.d.ts +14 -0
  162. package/dist/tools/compareTransactions/parser.js +430 -0
  163. package/dist/tools/compareTransactions/types.d.ts +27 -0
  164. package/dist/tools/compareTransactions/types.js +1 -0
  165. package/dist/tools/compareTransactions.d.ts +1 -0
  166. package/dist/tools/compareTransactions.js +1 -0
  167. package/dist/tools/deltaFetcher.d.ts +22 -0
  168. package/dist/tools/deltaFetcher.js +137 -0
  169. package/dist/tools/deltaSupport.d.ts +20 -0
  170. package/dist/tools/deltaSupport.js +176 -0
  171. package/dist/tools/exportTransactions.d.ts +17 -0
  172. package/dist/tools/exportTransactions.js +191 -0
  173. package/dist/tools/monthTools.d.ts +16 -0
  174. package/dist/tools/monthTools.js +107 -0
  175. package/dist/tools/payeeTools.d.ts +17 -0
  176. package/dist/tools/payeeTools.js +82 -0
  177. package/dist/tools/reconcileAdapter.d.ts +25 -0
  178. package/dist/tools/reconcileAdapter.js +167 -0
  179. package/dist/tools/reconciliation/analyzer.d.ts +3 -0
  180. package/dist/tools/reconciliation/analyzer.js +567 -0
  181. package/dist/tools/reconciliation/executor.d.ts +94 -0
  182. package/dist/tools/reconciliation/executor.js +611 -0
  183. package/dist/tools/reconciliation/index.d.ts +54 -0
  184. package/dist/tools/reconciliation/index.js +249 -0
  185. package/dist/tools/reconciliation/matcher.d.ts +3 -0
  186. package/dist/tools/reconciliation/matcher.js +160 -0
  187. package/dist/tools/reconciliation/payeeNormalizer.d.ts +6 -0
  188. package/dist/tools/reconciliation/payeeNormalizer.js +77 -0
  189. package/dist/tools/reconciliation/recommendationEngine.d.ts +2 -0
  190. package/dist/tools/reconciliation/recommendationEngine.js +273 -0
  191. package/dist/tools/reconciliation/reportFormatter.d.ts +13 -0
  192. package/dist/tools/reconciliation/reportFormatter.js +214 -0
  193. package/dist/tools/reconciliation/types.d.ts +172 -0
  194. package/dist/tools/reconciliation/types.js +7 -0
  195. package/dist/tools/schemas/outputs/accountOutputs.d.ts +58 -0
  196. package/dist/tools/schemas/outputs/accountOutputs.js +24 -0
  197. package/dist/tools/schemas/outputs/budgetOutputs.d.ts +48 -0
  198. package/dist/tools/schemas/outputs/budgetOutputs.js +15 -0
  199. package/dist/tools/schemas/outputs/categoryOutputs.d.ts +93 -0
  200. package/dist/tools/schemas/outputs/categoryOutputs.js +37 -0
  201. package/dist/tools/schemas/outputs/comparisonOutputs.d.ts +269 -0
  202. package/dist/tools/schemas/outputs/comparisonOutputs.js +181 -0
  203. package/dist/tools/schemas/outputs/index.d.ts +14 -0
  204. package/dist/tools/schemas/outputs/index.js +14 -0
  205. package/dist/tools/schemas/outputs/monthOutputs.d.ts +122 -0
  206. package/dist/tools/schemas/outputs/monthOutputs.js +51 -0
  207. package/dist/tools/schemas/outputs/payeeOutputs.d.ts +34 -0
  208. package/dist/tools/schemas/outputs/payeeOutputs.js +16 -0
  209. package/dist/tools/schemas/outputs/reconciliationOutputs.d.ts +1275 -0
  210. package/dist/tools/schemas/outputs/reconciliationOutputs.js +377 -0
  211. package/dist/tools/schemas/outputs/transactionMutationOutputs.d.ts +717 -0
  212. package/dist/tools/schemas/outputs/transactionMutationOutputs.js +260 -0
  213. package/dist/tools/schemas/outputs/transactionOutputs.d.ts +98 -0
  214. package/dist/tools/schemas/outputs/transactionOutputs.js +49 -0
  215. package/dist/tools/schemas/outputs/utilityOutputs.d.ts +219 -0
  216. package/dist/tools/schemas/outputs/utilityOutputs.js +120 -0
  217. package/dist/tools/schemas/shared/commonOutputs.d.ts +24 -0
  218. package/dist/tools/schemas/shared/commonOutputs.js +27 -0
  219. package/dist/tools/toolCategories.d.ts +32 -0
  220. package/dist/tools/toolCategories.js +32 -0
  221. package/dist/tools/transactionTools.d.ts +315 -0
  222. package/dist/tools/transactionTools.js +1722 -0
  223. package/dist/tools/utilityTools.d.ts +10 -0
  224. package/dist/tools/utilityTools.js +56 -0
  225. package/dist/types/index.d.ts +20 -0
  226. package/dist/types/index.js +16 -0
  227. package/dist/types/toolAnnotations.d.ts +7 -0
  228. package/dist/types/toolAnnotations.js +1 -0
  229. package/dist/utils/amountUtils.d.ts +3 -0
  230. package/dist/utils/amountUtils.js +10 -0
  231. package/dist/utils/dateUtils.d.ts +9 -0
  232. package/dist/utils/dateUtils.js +43 -0
  233. package/dist/utils/money.d.ts +21 -0
  234. package/dist/utils/money.js +51 -0
  235. package/docs/README.md +72 -0
  236. package/docs/assets/examples/reconciliation-with-recommendations.json +68 -0
  237. package/docs/assets/schemas/reconciliation-v2.json +338 -0
  238. package/docs/getting-started/CONFIGURATION.md +175 -0
  239. package/docs/getting-started/INSTALLATION.md +333 -0
  240. package/docs/getting-started/QUICKSTART.md +282 -0
  241. package/docs/guides/ARCHITECTURE.md +650 -0
  242. package/docs/guides/DEPLOYMENT.md +189 -0
  243. package/docs/guides/INTEGRATION_TESTING.md +730 -0
  244. package/docs/guides/TESTING.md +591 -0
  245. package/docs/reconciliation-flow.md +83 -0
  246. package/docs/reference/API.md +1450 -0
  247. package/docs/reference/EXAMPLES.md +946 -0
  248. package/docs/reference/TOOLS.md +348 -0
  249. package/docs/reference/TROUBLESHOOTING.md +481 -0
  250. package/esbuild.config.mjs +68 -0
  251. package/eslint.config.js +49 -0
  252. package/fix-types.sh +17 -0
  253. package/meta.json +12550 -0
  254. package/package.json +105 -0
  255. package/package.json.tmp +105 -0
  256. package/scripts/analyze-bundle.mjs +41 -0
  257. package/scripts/create-pr-description.js +203 -0
  258. package/scripts/generate-mcpb.ps1 +96 -0
  259. package/scripts/run-domain-integration-tests.js +33 -0
  260. package/scripts/run-generate-mcpb.js +29 -0
  261. package/scripts/run-throttled-integration-tests.js +116 -0
  262. package/scripts/test-delta-params.mjs +140 -0
  263. package/scripts/test-recommendations.ts +53 -0
  264. package/scripts/tmpTransaction.ts +48 -0
  265. package/scripts/validate-env.js +122 -0
  266. package/scripts/verify-build.js +105 -0
  267. package/scripts/watch-and-restart.ps1 +50 -0
  268. package/src/__tests__/comprehensive.integration.test.ts +1196 -0
  269. package/src/__tests__/delta.performance.test.ts +80 -0
  270. package/src/__tests__/performance.test.ts +725 -0
  271. package/src/__tests__/setup.ts +449 -0
  272. package/src/__tests__/testRunner.ts +444 -0
  273. package/src/__tests__/testUtils.ts +563 -0
  274. package/src/__tests__/workflows.e2e.test.ts +1675 -0
  275. package/src/index.ts +124 -0
  276. package/src/server/.gitkeep +1 -0
  277. package/src/server/YNABMCPServer.ts +1188 -0
  278. package/src/server/__tests__/YNABMCPServer.integration.test.ts +903 -0
  279. package/src/server/__tests__/YNABMCPServer.test.ts +894 -0
  280. package/src/server/__tests__/budgetResolver.test.ts +425 -0
  281. package/src/server/__tests__/cacheManager.test.ts +880 -0
  282. package/src/server/__tests__/config.test.ts +166 -0
  283. package/src/server/__tests__/deltaCache.merge.test.ts +724 -0
  284. package/src/server/__tests__/deltaCache.swr.test.ts +168 -0
  285. package/src/server/__tests__/deltaCache.test.ts +774 -0
  286. package/src/server/__tests__/diagnostics.test.ts +823 -0
  287. package/src/server/__tests__/errorHandler.integration.test.ts +466 -0
  288. package/src/server/__tests__/errorHandler.test.ts +416 -0
  289. package/src/server/__tests__/prompts.test.ts +354 -0
  290. package/src/server/__tests__/rateLimiter.test.ts +314 -0
  291. package/src/server/__tests__/requestLogger.test.ts +408 -0
  292. package/src/server/__tests__/resources.test.ts +299 -0
  293. package/src/server/__tests__/security.integration.test.ts +426 -0
  294. package/src/server/__tests__/securityMiddleware.test.ts +449 -0
  295. package/src/server/__tests__/server-startup.integration.test.ts +477 -0
  296. package/src/server/__tests__/serverKnowledgeStore.test.ts +174 -0
  297. package/src/server/__tests__/toolRegistry.test.ts +855 -0
  298. package/src/server/budgetResolver.ts +235 -0
  299. package/src/server/cacheManager.ts +503 -0
  300. package/src/server/config.ts +41 -0
  301. package/src/server/deltaCache.merge.ts +149 -0
  302. package/src/server/deltaCache.ts +341 -0
  303. package/src/server/diagnostics.ts +338 -0
  304. package/src/server/errorHandler.ts +756 -0
  305. package/src/server/prompts.ts +291 -0
  306. package/src/server/rateLimiter.ts +156 -0
  307. package/src/server/requestLogger.ts +344 -0
  308. package/src/server/resources.ts +168 -0
  309. package/src/server/responseFormatter.ts +51 -0
  310. package/src/server/securityMiddleware.ts +236 -0
  311. package/src/server/serverKnowledgeStore.ts +91 -0
  312. package/src/server/toolRegistry.ts +489 -0
  313. package/src/tools/.gitkeep +1 -0
  314. package/src/tools/__tests__/accountTools.delta.integration.test.ts +128 -0
  315. package/src/tools/__tests__/accountTools.integration.test.ts +117 -0
  316. package/src/tools/__tests__/accountTools.test.ts +653 -0
  317. package/src/tools/__tests__/budgetTools.delta.integration.test.ts +90 -0
  318. package/src/tools/__tests__/budgetTools.integration.test.ts +134 -0
  319. package/src/tools/__tests__/budgetTools.test.ts +423 -0
  320. package/src/tools/__tests__/categoryTools.delta.integration.test.ts +80 -0
  321. package/src/tools/__tests__/categoryTools.integration.test.ts +295 -0
  322. package/src/tools/__tests__/categoryTools.test.ts +622 -0
  323. package/src/tools/__tests__/compareTransactions/formatter.test.ts +486 -0
  324. package/src/tools/__tests__/compareTransactions/index.test.ts +383 -0
  325. package/src/tools/__tests__/compareTransactions/matcher.test.ts +410 -0
  326. package/src/tools/__tests__/compareTransactions/parser.test.ts +764 -0
  327. package/src/tools/__tests__/compareTransactions.test.ts +342 -0
  328. package/src/tools/__tests__/compareTransactions.window.test.ts +147 -0
  329. package/src/tools/__tests__/deltaFetcher.scheduled.integration.test.ts +76 -0
  330. package/src/tools/__tests__/deltaFetcher.test.ts +270 -0
  331. package/src/tools/__tests__/deltaSupport.test.ts +188 -0
  332. package/src/tools/__tests__/deltaTestUtils.ts +46 -0
  333. package/src/tools/__tests__/exportTransactions.test.ts +213 -0
  334. package/src/tools/__tests__/monthTools.delta.integration.test.ts +80 -0
  335. package/src/tools/__tests__/monthTools.integration.test.ts +174 -0
  336. package/src/tools/__tests__/monthTools.test.ts +523 -0
  337. package/src/tools/__tests__/payeeTools.delta.integration.test.ts +80 -0
  338. package/src/tools/__tests__/payeeTools.integration.test.ts +150 -0
  339. package/src/tools/__tests__/payeeTools.test.ts +445 -0
  340. package/src/tools/__tests__/transactionTools.integration.test.ts +762 -0
  341. package/src/tools/__tests__/transactionTools.test.ts +3521 -0
  342. package/src/tools/__tests__/utilityTools.integration.test.ts +128 -0
  343. package/src/tools/__tests__/utilityTools.test.ts +205 -0
  344. package/src/tools/accountTools.ts +283 -0
  345. package/src/tools/budgetTools.ts +112 -0
  346. package/src/tools/categoryTools.ts +366 -0
  347. package/src/tools/compareTransactions/formatter.ts +163 -0
  348. package/src/tools/compareTransactions/index.ts +228 -0
  349. package/src/tools/compareTransactions/matcher.ts +240 -0
  350. package/src/tools/compareTransactions/parser.ts +557 -0
  351. package/src/tools/compareTransactions/types.ts +60 -0
  352. package/src/tools/compareTransactions.ts +3 -0
  353. package/src/tools/deltaFetcher.ts +278 -0
  354. package/src/tools/deltaSupport.ts +293 -0
  355. package/src/tools/exportTransactions.ts +273 -0
  356. package/src/tools/monthTools.ts +164 -0
  357. package/src/tools/payeeTools.ts +140 -0
  358. package/src/tools/reconcileAdapter.ts +312 -0
  359. package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +122 -0
  360. package/src/tools/reconciliation/__tests__/adapter.test.ts +234 -0
  361. package/src/tools/reconciliation/__tests__/analyzer.test.ts +406 -0
  362. package/src/tools/reconciliation/__tests__/executor.integration.test.ts +366 -0
  363. package/src/tools/reconciliation/__tests__/executor.test.ts +779 -0
  364. package/src/tools/reconciliation/__tests__/matcher.test.ts +650 -0
  365. package/src/tools/reconciliation/__tests__/payeeNormalizer.test.ts +278 -0
  366. package/src/tools/reconciliation/__tests__/recommendationEngine.integration.test.ts +658 -0
  367. package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +1000 -0
  368. package/src/tools/reconciliation/__tests__/reconciliation.delta.integration.test.ts +151 -0
  369. package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +573 -0
  370. package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +78 -0
  371. package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +47 -0
  372. package/src/tools/reconciliation/__tests__/scenarios/repeatAmount.scenario.test.ts +61 -0
  373. package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +49 -0
  374. package/src/tools/reconciliation/analyzer.ts +824 -0
  375. package/src/tools/reconciliation/executor.ts +880 -0
  376. package/src/tools/reconciliation/index.ts +400 -0
  377. package/src/tools/reconciliation/matcher.ts +269 -0
  378. package/src/tools/reconciliation/payeeNormalizer.ts +167 -0
  379. package/src/tools/reconciliation/recommendationEngine.ts +506 -0
  380. package/src/tools/reconciliation/reportFormatter.ts +363 -0
  381. package/src/tools/reconciliation/types.ts +314 -0
  382. package/src/tools/schemas/outputs/__tests__/accountOutputs.test.ts +424 -0
  383. package/src/tools/schemas/outputs/__tests__/budgetOutputs.test.ts +310 -0
  384. package/src/tools/schemas/outputs/__tests__/categoryOutputs.test.ts +448 -0
  385. package/src/tools/schemas/outputs/__tests__/comparisonOutputs.test.ts +519 -0
  386. package/src/tools/schemas/outputs/__tests__/dateValidation.test.ts +155 -0
  387. package/src/tools/schemas/outputs/__tests__/discrepancyDirection.test.ts +288 -0
  388. package/src/tools/schemas/outputs/__tests__/monthOutputs.test.ts +478 -0
  389. package/src/tools/schemas/outputs/__tests__/payeeOutputs.test.ts +370 -0
  390. package/src/tools/schemas/outputs/__tests__/reconciliationOutputs.test.ts +401 -0
  391. package/src/tools/schemas/outputs/__tests__/transactionMutationSchemas.test.ts +213 -0
  392. package/src/tools/schemas/outputs/__tests__/transactionOutputs.test.ts +474 -0
  393. package/src/tools/schemas/outputs/__tests__/utilityOutputs.test.ts +333 -0
  394. package/src/tools/schemas/outputs/accountOutputs.ts +137 -0
  395. package/src/tools/schemas/outputs/budgetOutputs.ts +86 -0
  396. package/src/tools/schemas/outputs/categoryOutputs.ts +194 -0
  397. package/src/tools/schemas/outputs/comparisonOutputs.ts +600 -0
  398. package/src/tools/schemas/outputs/index.ts +270 -0
  399. package/src/tools/schemas/outputs/monthOutputs.ts +243 -0
  400. package/src/tools/schemas/outputs/payeeOutputs.ts +105 -0
  401. package/src/tools/schemas/outputs/reconciliationOutputs.ts +796 -0
  402. package/src/tools/schemas/outputs/transactionMutationOutputs.ts +758 -0
  403. package/src/tools/schemas/outputs/transactionOutputs.ts +243 -0
  404. package/src/tools/schemas/outputs/utilityOutputs.ts +411 -0
  405. package/src/tools/schemas/shared/commonOutputs.ts +140 -0
  406. package/src/tools/toolCategories.ts +140 -0
  407. package/src/tools/transactionTools.ts +2509 -0
  408. package/src/tools/utilityTools.ts +90 -0
  409. package/src/types/.gitkeep +1 -0
  410. package/src/types/__tests__/index.test.ts +52 -0
  411. package/src/types/index.ts +67 -0
  412. package/src/types/integration-tests.d.ts +35 -0
  413. package/src/types/toolAnnotations.ts +44 -0
  414. package/src/utils/__tests__/dateUtils.test.ts +170 -0
  415. package/src/utils/__tests__/money.test.ts +189 -0
  416. package/src/utils/amountUtils.ts +32 -0
  417. package/src/utils/dateUtils.ts +108 -0
  418. package/src/utils/money.ts +123 -0
  419. package/test-csv-sample.csv +28 -0
  420. package/test-exports/sample_bank_statement.csv +7 -0
  421. package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_09-04-53.json +23 -0
  422. package/test-exports/ynab_account_e9ddc2a6_minimal_1items_2025-11-19_10-37-42.json +23 -0
  423. package/test-exports/ynab_account_e9ddc2a6_minimal_4items_2025-11-19_09-02-09.json +44 -0
  424. package/test-exports/ynab_account_e9ddc2a6_minimal_6items_2025-11-19_10-37-52.json +58 -0
  425. package/test-exports/ynab_since_2025-11-01_account_4c18e9f0_minimal_14items_2025-11-16_10-07-10.json +115 -0
  426. package/test-reconcile-autodetect.js +40 -0
  427. package/test-reconcile-tool.js +152 -0
  428. package/test-reconcile-with-csv.cjs +89 -0
  429. package/test-statement.csv +8 -0
  430. package/test_debug.js +47 -0
  431. package/test_simple.mjs +16 -0
  432. package/tsconfig.json +31 -0
  433. package/tsconfig.prod.json +18 -0
  434. package/vitest-reporters/split-json-reporter.ts +211 -0
  435. package/vitest.config.ts +96 -0
@@ -0,0 +1,600 @@
1
+ /**
2
+ * @fileoverview Transaction comparison and export output schemas for YNAB MCP server.
3
+ * Defines Zod validation schemas for comparing bank CSV transactions with YNAB transactions
4
+ * and exporting transactions to JSON files with metadata.
5
+ *
6
+ * @see src/tools/compareTransactions/index.ts - Main comparison handler (lines 63-228)
7
+ * @see src/tools/compareTransactions/types.ts - Type definitions for comparison entities
8
+ * @see src/tools/compareTransactions/formatter.ts - Result formatting logic
9
+ * @see src/tools/exportTransactions.ts - Transaction export handler (lines 147-274)
10
+ *
11
+ * @example
12
+ * // Transaction comparison result
13
+ * {
14
+ * summary: {
15
+ * total_bank_transactions: 50,
16
+ * total_ynab_transactions: 52,
17
+ * matched_count: 45,
18
+ * unmatched_bank_count: 5,
19
+ * unmatched_ynab_count: 7,
20
+ * match_rate_percentage: 90.0
21
+ * },
22
+ * matches: [
23
+ * {
24
+ * bank_transaction: { date: "2025-10-15", amount: -25500, description: "Grocery Store" },
25
+ * ynab_transaction: { id: "txn-1", date: "2025-10-15", amount: -25500, payee_name: "Grocery Store" },
26
+ * match_score: 95,
27
+ * match_reasons: ["exact_amount_match", "exact_date_match", "payee_similarity"]
28
+ * }
29
+ * ],
30
+ * unmatched_bank: [...],
31
+ * parameters: { amount_tolerance: 0, date_tolerance_days: 2 }
32
+ * }
33
+ *
34
+ * @example
35
+ * // Transaction export result
36
+ * {
37
+ * message: "Successfully exported 150 transactions",
38
+ * filename: "ynab_transactions_2025-11-18.json",
39
+ * full_path: "/Users/username/Downloads/ynab_transactions_2025-11-18.json",
40
+ * export_mode: "full",
41
+ * preview_count: 5,
42
+ * total_count: 150,
43
+ * preview_transactions: [...]
44
+ * }
45
+ */
46
+
47
+ import { z } from 'zod';
48
+
49
+ // ============================================================================
50
+ // DATE VALIDATION HELPERS
51
+ // ============================================================================
52
+
53
+ /**
54
+ * Validates that a string is both correctly formatted as YYYY-MM-DD and represents
55
+ * a valid calendar date. Rejects invalid dates like "2024-02-31" or "2024-13-01".
56
+ *
57
+ * @param dateStr - ISO date string to validate
58
+ * @returns true if the date is valid, false otherwise
59
+ *
60
+ * @remarks
61
+ * This validation checks:
62
+ * 1. Format: YYYY-MM-DD (via regex)
63
+ * 2. Parseability: Date.parse() succeeds
64
+ * 3. Calendar validity: Parsed components match original string
65
+ * 4. Not NaN: The parsed date is a valid number
66
+ *
67
+ * @example
68
+ * isValidISODate("2024-02-29") // true (leap year)
69
+ * isValidISODate("2024-02-30") // false (February has max 29 days)
70
+ * isValidISODate("2024-13-01") // false (invalid month)
71
+ * isValidISODate("2024-02-31") // false (February doesn't have 31 days)
72
+ */
73
+ function isValidISODate(dateStr: string): boolean {
74
+ // First check format
75
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
76
+ return false;
77
+ }
78
+
79
+ // Parse and validate
80
+ const parsed = Date.parse(dateStr);
81
+ if (isNaN(parsed)) {
82
+ return false;
83
+ }
84
+
85
+ // Verify that the parsed date components match the original string
86
+ // This catches cases like "2024-02-31" which Date.parse might coerce to "2024-03-03"
87
+ const date = new Date(parsed);
88
+ const year = date.getUTCFullYear();
89
+ const month = String(date.getUTCMonth() + 1).padStart(2, '0');
90
+ const day = String(date.getUTCDate()).padStart(2, '0');
91
+ const reconstructed = `${year}-${month}-${day}`;
92
+
93
+ return reconstructed === dateStr;
94
+ }
95
+ /**
96
+ * Reusable Zod schema for validating ISO date strings (YYYY-MM-DD).
97
+ * Validates both format and calendar validity.
98
+ *
99
+ * @example
100
+ * const schema = z.object({ date: ISODateStringSchema });
101
+ * schema.parse({ date: "2024-02-29" }); // OK (leap year)
102
+ * schema.parse({ date: "2024-02-31" }); // Error: Invalid calendar date
103
+ */
104
+ export const ISODateStringSchema = z
105
+ .string()
106
+ .regex(/^\d{4}-\d{2}-\d{2}$/, 'Date must be in YYYY-MM-DD format')
107
+ .refine(isValidISODate, {
108
+ message: 'Invalid calendar date (e.g., month must be 01-12, day must be valid for the month)',
109
+ });
110
+
111
+ // ============================================================================
112
+ // NESTED SCHEMAS FOR COMPOSITION
113
+ // ============================================================================
114
+
115
+ /**
116
+ * Bank transaction for comparison analysis (formatted output).
117
+ * Represents missing transactions in YNAB with payee suggestions.
118
+ *
119
+ * @remarks
120
+ * The formatter uses `.toFixed(2)` to format amounts as decimal strings with exactly 2 decimal places.
121
+ * Dates are formatted as ISO strings (YYYY-MM-DD) via `.toISOString().split('T')[0]`.
122
+ *
123
+ * @see src/tools/compareTransactions/formatter.ts:92-102 - formatUnmatchedBank function
124
+ */
125
+ export const MissingInYNABItemSchema = z.object({
126
+ date: ISODateStringSchema,
127
+ amount: z
128
+ .string()
129
+ .regex(/^-?\d+\.\d{2}$/, 'Amount must be a decimal string with exactly 2 decimal places'),
130
+ description: z.string(),
131
+ row_number: z.number(),
132
+ suggested_payee_id: z.string().optional(),
133
+ suggested_payee_name: z.string().optional(),
134
+ suggestion_reason: z.string().optional(),
135
+ });
136
+
137
+ export type MissingInYNABItem = z.infer<typeof MissingInYNABItemSchema>;
138
+
139
+ /**
140
+ * YNAB transaction missing from bank CSV (formatted output).
141
+ * Represents transactions that exist in YNAB but not in the bank file.
142
+ *
143
+ * @remarks
144
+ * The formatter uses `.toFixed(2)` to format amounts as decimal strings with exactly 2 decimal places.
145
+ * Dates are formatted as ISO strings (YYYY-MM-DD) via `.toISOString().split('T')[0]`.
146
+ *
147
+ * @see src/tools/compareTransactions/formatter.ts:108-116 - formatUnmatchedYNAB function
148
+ */
149
+ export const MissingInBankItemSchema = z.object({
150
+ id: z.string(),
151
+ date: ISODateStringSchema,
152
+ amount: z
153
+ .string()
154
+ .regex(/^-?\d+\.\d{2}$/, 'Amount must be a decimal string with exactly 2 decimal places'),
155
+ payee_name: z.string().nullable(),
156
+ memo: z.string().nullable(),
157
+ cleared: z.string(),
158
+ });
159
+
160
+ export type MissingInBankItem = z.infer<typeof MissingInBankItemSchema>;
161
+
162
+ /**
163
+ * Matched transaction pair (formatted output).
164
+ * Links a bank transaction to a YNAB transaction with confidence metrics.
165
+ *
166
+ * @remarks
167
+ * The formatter uses `.toFixed(2)` to format amounts as decimal strings with exactly 2 decimal places.
168
+ * Dates are formatted as ISO strings (YYYY-MM-DD) via `.toISOString().split('T')[0]`.
169
+ *
170
+ * @see src/tools/compareTransactions/formatter.ts:72-86 - formatMatches function
171
+ */
172
+ export const MatchItemSchema = z.object({
173
+ bank_date: ISODateStringSchema,
174
+ bank_amount: z
175
+ .string()
176
+ .regex(/^-?\d+\.\d{2}$/, 'Amount must be a decimal string with exactly 2 decimal places'),
177
+ bank_description: z.string(),
178
+ ynab_date: ISODateStringSchema,
179
+ ynab_amount: z
180
+ .string()
181
+ .regex(/^-?\d+\.\d{2}$/, 'Amount must be a decimal string with exactly 2 decimal places'),
182
+ ynab_payee: z.string().nullable(),
183
+ ynab_transaction: z.object({
184
+ id: z.string(),
185
+ cleared: z.string(),
186
+ }),
187
+ match_score: z.number(),
188
+ match_reasons: z.array(z.string()),
189
+ });
190
+
191
+ export type MatchItem = z.infer<typeof MatchItemSchema>;
192
+
193
+ // ============================================================================
194
+ // INTERNAL SCHEMAS (for reference, not used in main output validation)
195
+ // ============================================================================
196
+
197
+ /**
198
+ * Bank transaction (internal type, used during matching).
199
+ * Not part of the formatted output; see MissingInYNABItemSchema for output format.
200
+ *
201
+ * @remarks
202
+ * **WARNING:** This is an internal schema used during the matching algorithm.
203
+ * It is NOT part of the public tool output contract and may change without
204
+ * maintaining backward compatibility. Do not rely on this schema for stable
205
+ * integrations - use CompareTransactionsOutputSchema instead.
206
+ *
207
+ * @see src/tools/compareTransactions/types.ts - BankTransaction interface
208
+ * @internal
209
+ */
210
+ export const BankTransactionComparisonSchema = z.object({
211
+ date: ISODateStringSchema,
212
+ amount: z.number(),
213
+ description: z.string(),
214
+ raw_amount: z.string(),
215
+ raw_date: z.string(),
216
+ row_number: z.number(),
217
+ });
218
+
219
+ export type BankTransactionComparison = z.infer<typeof BankTransactionComparisonSchema>;
220
+
221
+ /**
222
+ * YNAB transaction (internal type, used during matching).
223
+ * Not part of the formatted output; see MissingInBankItemSchema for output format.
224
+ *
225
+ * @remarks
226
+ * **WARNING:** This is an internal schema used during the matching algorithm.
227
+ * It is NOT part of the public tool output contract and may change without
228
+ * maintaining backward compatibility. Do not rely on this schema for stable
229
+ * integrations - use CompareTransactionsOutputSchema instead.
230
+ *
231
+ * @see src/tools/compareTransactions/types.ts - YNABTransaction interface
232
+ * @internal
233
+ */
234
+ export const YNABTransactionComparisonSchema = z.object({
235
+ id: z.string(),
236
+ date: ISODateStringSchema,
237
+ amount: z.number(),
238
+ payee_name: z.string().nullable(),
239
+ memo: z.string().nullable(),
240
+ cleared: z.string(),
241
+ account_name: z.string().optional(),
242
+ category_name: z.string().optional(),
243
+ });
244
+
245
+ export type YNABTransactionComparison = z.infer<typeof YNABTransactionComparisonSchema>;
246
+
247
+ /**
248
+ * Matched transaction pair (internal type, used during matching).
249
+ * Not part of the formatted output; see MatchItemSchema for output format.
250
+ *
251
+ * @remarks
252
+ * **WARNING:** This is an internal schema used during the matching algorithm.
253
+ * It is NOT part of the public tool output contract and may change without
254
+ * maintaining backward compatibility. Do not rely on this schema for stable
255
+ * integrations - use CompareTransactionsOutputSchema instead.
256
+ *
257
+ * @see src/tools/compareTransactions/types.ts - TransactionMatch interface
258
+ * @internal
259
+ */
260
+ export const TransactionMatchComparisonSchema = z.object({
261
+ bank_transaction: BankTransactionComparisonSchema,
262
+ ynab_transaction: YNABTransactionComparisonSchema,
263
+ match_score: z.number().min(0).max(100),
264
+ match_reasons: z.array(z.string()),
265
+ });
266
+
267
+ export type TransactionMatchComparison = z.infer<typeof TransactionMatchComparisonSchema>;
268
+
269
+ /**
270
+ * Comparison configuration parameters.
271
+ * Documents tolerance settings used for matching.
272
+ */
273
+ export const ComparisonParametersSchema = z.object({
274
+ amount_tolerance: z.number().optional(),
275
+ date_tolerance_days: z.number().optional(),
276
+ });
277
+
278
+ export type ComparisonParameters = z.infer<typeof ComparisonParametersSchema>;
279
+
280
+ /**
281
+ * Date range for comparison analysis.
282
+ * Specifies the period covered by compared transactions.
283
+ *
284
+ * @remarks
285
+ * Validates that:
286
+ * 1. Both start and end are valid ISO dates (YYYY-MM-DD)
287
+ * 2. Start date is before or equal to end date
288
+ *
289
+ * @example
290
+ * DateRangeSchema.parse({ start: "2024-01-01", end: "2024-12-31" }) // OK
291
+ * DateRangeSchema.parse({ start: "2024-12-31", end: "2024-01-01" }) // Error: start date must be before or equal to end date
292
+ */
293
+ export const DateRangeSchema = z
294
+ .object({
295
+ start: ISODateStringSchema,
296
+ end: ISODateStringSchema,
297
+ })
298
+ .refine(
299
+ (data) => {
300
+ // Parse both dates - we know they're valid ISO dates due to ISODateStringSchema
301
+ const startDate = Date.parse(data.start);
302
+ const endDate = Date.parse(data.end);
303
+
304
+ // Validate logical ordering: start must be <= end
305
+ return startDate <= endDate;
306
+ },
307
+ {
308
+ message: 'Start date must be before or equal to end date',
309
+ },
310
+ );
311
+
312
+ export type DateRange = z.infer<typeof DateRangeSchema>;
313
+
314
+ /**
315
+ * Export metadata and configuration (written to disk).
316
+ * Documents export settings and timestamp.
317
+ *
318
+ * @remarks
319
+ * This schema represents the export_info object written to the JSON file.
320
+ * Note: The tool response does NOT include this object - see ExportTransactionsOutputSchema for the tool response format.
321
+ *
322
+ * @see src/tools/exportTransactions.ts:184-197 - Export info construction
323
+ */
324
+ export const ExportInfoSchema = z.object({
325
+ exported_at: z.string(),
326
+ total_transactions: z.number(),
327
+ minimal: z.boolean(),
328
+ filters: z.object({
329
+ budget_id: z.string().optional(),
330
+ account_id: z.string().nullable(),
331
+ category_id: z.string().nullable(),
332
+ since_date: z.string().nullable(),
333
+ type: z.string().nullable(),
334
+ }),
335
+ });
336
+
337
+ export type ExportInfo = z.infer<typeof ExportInfoSchema>;
338
+
339
+ /**
340
+ * Exported transaction schema (written to disk, no export_mode discriminator).
341
+ * The actual JSON file does not include an export_mode field on each transaction.
342
+ *
343
+ * @remarks
344
+ * IMPORTANT: `amount` is the raw YNAB amount in **milliunits** (not dollar amounts).
345
+ * These values come directly from the YNAB API and represent 1/1000th of the currency unit.
346
+ * For example, $25.50 is represented as 25500 milliunits.
347
+ *
348
+ * Minimal mode includes: id, date, amount, payee_name, cleared
349
+ * Full mode includes: all transaction fields
350
+ *
351
+ * @see src/tools/exportTransactions.ts:198-232 - Transaction export logic
352
+ * @see src/tools/exportTransactions.ts:204 - Amount field directly from transaction.amount (milliunits)
353
+ */
354
+ export const ExportedTransactionMinimalSchema = z.object({
355
+ id: z.string(),
356
+ date: z.string(),
357
+ amount: z.number(), // Raw YNAB milliunits
358
+ payee_name: z.string().nullable(),
359
+ cleared: z.string(),
360
+ });
361
+
362
+ export const ExportedTransactionFullSchema = z.object({
363
+ id: z.string(),
364
+ date: z.string(),
365
+ amount: z.number(), // Raw YNAB milliunits
366
+ memo: z.string().nullable(),
367
+ cleared: z.string(),
368
+ approved: z.boolean(),
369
+ flag_color: z.string().nullable(),
370
+ account_id: z.string(),
371
+ payee_id: z.string().nullable(),
372
+ category_id: z.string().nullable(),
373
+ transfer_account_id: z.string().nullable(),
374
+ transfer_transaction_id: z.string().nullable(),
375
+ matched_transaction_id: z.string().nullable(),
376
+ import_id: z.string().nullable(),
377
+ deleted: z.boolean(),
378
+ account_name: z.string().optional(),
379
+ payee_name: z.string().nullable(),
380
+ category_name: z.string().nullable(),
381
+ });
382
+
383
+ export const ExportedTransactionSchema = z.union([
384
+ ExportedTransactionMinimalSchema,
385
+ ExportedTransactionFullSchema,
386
+ ]);
387
+
388
+ export type ExportedTransaction = z.infer<typeof ExportedTransactionSchema>;
389
+
390
+ /**
391
+ * Complete exported file structure (written to disk).
392
+ * Represents the full JSON file structure created by export_transactions tool.
393
+ *
394
+ * @remarks
395
+ * This is the structure of the file written to disk, NOT the tool response.
396
+ * For the tool response format, see ExportTransactionsOutputSchema.
397
+ *
398
+ * @see src/tools/exportTransactions.ts:184-233 - Export data construction and file writing
399
+ *
400
+ * @example
401
+ * // Minimal export file
402
+ * {
403
+ * export_info: {
404
+ * exported_at: "2025-11-18T10:30:00Z",
405
+ * total_transactions: 150,
406
+ * minimal: true,
407
+ * filters: {
408
+ * budget_id: "budget-123",
409
+ * account_id: "account-456",
410
+ * category_id: null,
411
+ * since_date: "2025-01-01",
412
+ * type: null,
413
+ * minimal: true
414
+ * }
415
+ * },
416
+ * transactions: [
417
+ * { id: "txn-1", date: "2025-11-15", amount: -25500, payee_name: "Grocery Store", cleared: "cleared" }, // amount is milliunits
418
+ * ...
419
+ * ]
420
+ * }
421
+ *
422
+ * @example
423
+ * // Full export file
424
+ * {
425
+ * export_info: {
426
+ * exported_at: "2025-11-18T10:30:00Z",
427
+ * total_transactions: 150,
428
+ * minimal: false,
429
+ * filters: { ... }
430
+ * },
431
+ * transactions: [
432
+ * {
433
+ * id: "txn-1",
434
+ * date: "2025-11-15",
435
+ * amount: -25500, // Raw milliunits: -$25.50
436
+ * memo: "Weekly groceries",
437
+ * cleared: "cleared",
438
+ * approved: true,
439
+ * flag_color: null,
440
+ * account_id: "account-456",
441
+ * payee_id: "payee-789",
442
+ * payee_name: "Grocery Store",
443
+ * category_id: "category-123",
444
+ * category_name: "Food",
445
+ * ...
446
+ * },
447
+ * ...
448
+ * ]
449
+ * }
450
+ */
451
+ export const ExportFileSchema = z.object({
452
+ export_info: ExportInfoSchema,
453
+ transactions: z.array(ExportedTransactionSchema),
454
+ });
455
+
456
+ export type ExportFile = z.infer<typeof ExportFileSchema>;
457
+
458
+ // ============================================================================
459
+ // MAIN OUTPUT SCHEMAS
460
+ // ============================================================================
461
+
462
+ /**
463
+ * Transaction comparison analysis result.
464
+ * Returns matched pairs, unmatched transactions, and summary statistics.
465
+ *
466
+ * @see src/tools/compareTransactions/formatter.ts - buildComparisonResult function (lines 122-163)
467
+ * @see src/tools/compareTransactions/formatter.ts - buildSummary function (lines 46-67)
468
+ *
469
+ * @example
470
+ * {
471
+ * summary: {
472
+ * bank_transactions_count: 50,
473
+ * ynab_transactions_count: 52,
474
+ * matches_found: 45,
475
+ * missing_in_ynab: 5,
476
+ * missing_in_bank: 7,
477
+ * date_range: { start: "2025-10-01", end: "2025-10-31" },
478
+ * parameters: { amount_tolerance: 0, date_tolerance_days: 2 }
479
+ * },
480
+ * matches: [
481
+ * {
482
+ * bank_date: "2025-10-15",
483
+ * bank_amount: "25.50",
484
+ * bank_description: "Grocery Store",
485
+ * ynab_date: "2025-10-15",
486
+ * ynab_amount: "25.50",
487
+ * ynab_payee: "Grocery Store",
488
+ * ynab_transaction: { id: "txn-1", cleared: "cleared" },
489
+ * match_score: 95,
490
+ * match_reasons: ["exact_amount_match", "exact_date_match", "payee_similarity"]
491
+ * }
492
+ * ],
493
+ * missing_in_ynab: [
494
+ * {
495
+ * date: "2025-10-20",
496
+ * amount: "15.00",
497
+ * description: "Unknown Store",
498
+ * row_number: 12,
499
+ * suggested_payee_name: "Unknown Store",
500
+ * suggestion_reason: "No matching payee found. Suggested new payee name from description."
501
+ * }
502
+ * ],
503
+ * missing_in_bank: [
504
+ * {
505
+ * id: "txn-99",
506
+ * date: "2025-10-22",
507
+ * amount: "20.00",
508
+ * payee_name: "Coffee Shop",
509
+ * memo: null,
510
+ * cleared: "cleared"
511
+ * }
512
+ * ]
513
+ * }
514
+ */
515
+ export const CompareTransactionsOutputSchema = z.object({
516
+ summary: z.object({
517
+ bank_transactions_count: z.number(),
518
+ ynab_transactions_count: z.number(),
519
+ matches_found: z.number(),
520
+ missing_in_ynab: z.number(),
521
+ missing_in_bank: z.number(),
522
+ date_range: DateRangeSchema,
523
+ parameters: ComparisonParametersSchema,
524
+ }),
525
+ matches: z.array(MatchItemSchema),
526
+ missing_in_ynab: z.array(MissingInYNABItemSchema),
527
+ missing_in_bank: z.array(MissingInBankItemSchema),
528
+ });
529
+
530
+ export type CompareTransactionsOutput = z.infer<typeof CompareTransactionsOutputSchema>;
531
+
532
+ /**
533
+ * Transaction export tool response (MCP tool result).
534
+ * Returns export location, mode, and preview of exported data.
535
+ *
536
+ * @remarks
537
+ * IMPORTANT: This schema represents the tool's response payload, NOT the file contents.
538
+ * The tool response does NOT include `export_info` or the full `transactions` array.
539
+ * For the file structure written to disk, see ExportFileSchema.
540
+ *
541
+ * @see src/tools/exportTransactions.ts:242-269 - Handler response construction
542
+ * @see ExportFileSchema - For the JSON file structure written to disk
543
+ *
544
+ * @example
545
+ * // Tool response (minimal export mode)
546
+ * {
547
+ * message: "Successfully exported 150 transactions (minimal fields)",
548
+ * filename: "ynab_transactions_minimal_2025-11-18.json",
549
+ * full_path: "/Users/username/Downloads/ynab_transactions_minimal_2025-11-18.json",
550
+ * export_directory: "/Users/username/Downloads",
551
+ * export_mode: "minimal",
552
+ * minimal_fields: "id, date, amount, payee_name, cleared",
553
+ * filename_explanation: "Filename format: ynab_{filters}_{count}items_{timestamp}.json...",
554
+ * preview_count: 10,
555
+ * total_count: 150,
556
+ * preview_transactions: [
557
+ * { id: "txn-1", date: "2025-11-15", amount: -25500, memo: "Groceries", payee_name: "Grocery Store", category_name: "Food" }
558
+ * ]
559
+ * }
560
+ *
561
+ * @example
562
+ * // Tool response (full export mode)
563
+ * {
564
+ * message: "Successfully exported 150 transactions (full fields)",
565
+ * filename: "ynab_transactions_2025-11-18.json",
566
+ * full_path: "/Users/username/Downloads/ynab_transactions_2025-11-18.json",
567
+ * export_directory: "/Users/username/Downloads",
568
+ * export_mode: "full",
569
+ * minimal_fields: null,
570
+ * filename_explanation: "Filename format: ynab_{filters}_{count}items_{timestamp}.json...",
571
+ * preview_count: 10,
572
+ * total_count: 150,
573
+ * preview_transactions: [
574
+ * { id: "txn-2", date: "2025-11-16", amount: -15000, memo: "Coffee", payee_name: "Cafe", category_name: "Dining" }
575
+ * ]
576
+ * }
577
+ */
578
+ export const ExportTransactionsOutputSchema = z.object({
579
+ message: z.string(),
580
+ filename: z.string(),
581
+ full_path: z.string(),
582
+ export_directory: z.string(),
583
+ export_mode: z.enum(['minimal', 'full']),
584
+ minimal_fields: z.string().nullable(),
585
+ filename_explanation: z.string(),
586
+ preview_count: z.number(),
587
+ total_count: z.number(),
588
+ preview_transactions: z.array(
589
+ z.object({
590
+ id: z.string(),
591
+ date: z.string(),
592
+ amount: z.number(), // Raw YNAB milliunits
593
+ memo: z.string().nullable().optional(),
594
+ payee_name: z.string().nullable().optional(),
595
+ category_name: z.string().nullable().optional(),
596
+ }),
597
+ ),
598
+ });
599
+
600
+ export type ExportTransactionsOutput = z.infer<typeof ExportTransactionsOutputSchema>;