@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,758 @@
1
+ /**
2
+ * @fileoverview Transaction mutation output schemas for YNAB MCP server.
3
+ * Defines Zod validation schemas for transaction, account, and category mutation operations
4
+ * including single/bulk creates, updates, deletes with dry-run and balance tracking.
5
+ *
6
+ * @see src/tools/transactionTools.ts - Transaction mutation handlers (create, update, delete, bulk operations)
7
+ * @see src/tools/accountTools.ts - Account creation handler (create_account)
8
+ * @see src/tools/categoryTools.ts - Category update handler (update_category)
9
+ *
10
+ * @example
11
+ * // Single transaction creation response
12
+ * {
13
+ * transaction: {
14
+ * id: "txn-123",
15
+ * date: "2025-11-18",
16
+ * amount: -25500,
17
+ * account_balance: 1500000, // Raw milliunits: $1,500.00
18
+ * account_cleared_balance: 1000000 // Raw milliunits: $1,000.00
19
+ * }
20
+ * }
21
+ *
22
+ * @example
23
+ * // Bulk transaction creation response
24
+ * {
25
+ * success: true,
26
+ * summary: {
27
+ * total_requested: 100,
28
+ * created: 95,
29
+ * duplicates: 3,
30
+ * failed: 2
31
+ * },
32
+ * results: [
33
+ * { request_index: 0, status: "created", transaction_id: "txn-1", correlation_key: "import-123" },
34
+ * { request_index: 1, status: "duplicate", correlation_key: "import-124" }
35
+ * ],
36
+ * mode: "summary"
37
+ * }
38
+ */
39
+
40
+ import { z } from 'zod';
41
+ import { TransactionSchema } from './transactionOutputs.js';
42
+ import { AccountSchema } from './accountOutputs.js';
43
+ import { CategorySchema } from './categoryOutputs.js';
44
+
45
+ // ============================================================================
46
+ // NESTED SCHEMAS FOR COMPOSITION
47
+ // ============================================================================
48
+
49
+ /**
50
+ * Subtransaction schema for split transaction line items.
51
+ * Used in create_transaction and create_receipt_split_transaction responses.
52
+ *
53
+ * @see src/tools/transactionTools.ts:950-1094 - create_transaction handler
54
+ * @see src/tools/transactionTools.ts:1160-1335 - create_receipt_split_transaction handler
55
+ */
56
+ export const SubtransactionSchema = z.object({
57
+ id: z.string(),
58
+ transaction_id: z.string(),
59
+ amount: z.number(),
60
+ memo: z.string().optional(),
61
+ payee_id: z.string().optional(),
62
+ payee_name: z.string().optional(),
63
+ category_id: z.string().optional(),
64
+ category_name: z.string().optional(),
65
+ transfer_account_id: z.string().optional(),
66
+ transfer_transaction_id: z.string().optional(),
67
+ deleted: z.boolean(),
68
+ });
69
+
70
+ export type Subtransaction = z.infer<typeof SubtransactionSchema>;
71
+
72
+ /**
73
+ * Transaction with account balance information.
74
+ * Extends base transaction schema with balance tracking.
75
+ *
76
+ * @remarks
77
+ * IMPORTANT: `account_balance` and `account_cleared_balance` are **raw YNAB milliunits** (not user-facing dollar amounts).
78
+ * These values come directly from the YNAB API Account object and represent 1/1000th of the currency unit.
79
+ * For example, $1,250.50 is represented as 1250500 milliunits.
80
+ *
81
+ * @see src/tools/transactionTools.ts:950-1094 - create_transaction handler
82
+ * @see src/tools/transactionTools.ts:1336-1530 - update_transaction handler
83
+ */
84
+ export const TransactionWithBalanceSchema = TransactionSchema.extend({
85
+ account_balance: z.number().optional(), // Raw YNAB milliunits
86
+ account_cleared_balance: z.number().optional(), // Raw YNAB milliunits
87
+ subtransactions: z.array(SubtransactionSchema).optional(),
88
+ });
89
+
90
+ export type TransactionWithBalance = z.infer<typeof TransactionWithBalanceSchema>;
91
+
92
+ /**
93
+ * Individual receipt line item.
94
+ * Used in create_receipt_split_transaction for itemized receipt breakdown.
95
+ *
96
+ * @see src/tools/transactionTools.ts:1160-1335 - create_receipt_split_transaction handler
97
+ */
98
+ export const ReceiptItemSchema = z.object({
99
+ name: z.string(),
100
+ quantity: z.number().optional(),
101
+ amount: z.number(),
102
+ memo: z.string().optional(),
103
+ });
104
+
105
+ export type ReceiptItem = z.infer<typeof ReceiptItemSchema>;
106
+
107
+ /**
108
+ * Category-level receipt breakdown.
109
+ * Groups receipt items by category with subtotals.
110
+ *
111
+ * @see src/tools/transactionTools.ts:1160-1335 - create_receipt_split_transaction handler
112
+ */
113
+ export const ReceiptCategoryBreakdownSchema = z.object({
114
+ category_id: z.string(),
115
+ category_name: z.string().optional(),
116
+ items: z.array(ReceiptItemSchema),
117
+ subtotal: z.number(),
118
+ tax: z.number(),
119
+ total: z.number(),
120
+ });
121
+
122
+ export type ReceiptCategoryBreakdown = z.infer<typeof ReceiptCategoryBreakdownSchema>;
123
+
124
+ /**
125
+ * Complete receipt breakdown summary.
126
+ * Includes category-level breakdowns and totals.
127
+ *
128
+ * @see src/tools/transactionTools.ts:1160-1335 - create_receipt_split_transaction handler
129
+ */
130
+ export const ReceiptSummarySchema = z.object({
131
+ subtotal: z.number(),
132
+ tax: z.number(),
133
+ total: z.number(),
134
+ categories: z.array(ReceiptCategoryBreakdownSchema),
135
+ });
136
+
137
+ export type ReceiptSummary = z.infer<typeof ReceiptSummarySchema>;
138
+
139
+ /**
140
+ * Summary statistics for bulk operations.
141
+ * Tracks success/duplicate/failure counts for bulk create/update operations.
142
+ *
143
+ * @see src/tools/transactionTools.ts:1636-1855 - create_transactions handler
144
+ * @see src/tools/transactionTools.ts:2057-2462 - update_transactions handler
145
+ */
146
+ export const BulkOperationSummarySchema = z.object({
147
+ total_requested: z.number(),
148
+ created: z.number().optional(),
149
+ updated: z.number().optional(),
150
+ duplicates: z.number().optional(),
151
+ failed: z.number(),
152
+ });
153
+
154
+ export type BulkOperationSummary = z.infer<typeof BulkOperationSummarySchema>;
155
+
156
+ /**
157
+ * Individual result in bulk operation.
158
+ * Tracks status and correlation for each transaction in bulk create/update.
159
+ *
160
+ * @remarks
161
+ * This schema uses `.passthrough()` to allow forward-compatible extension with additional
162
+ * correlation metadata fields (e.g., `import_id`, `hash`, `batch_id`, `execution_id`)
163
+ * that may be added in future versions without breaking existing validation.
164
+ *
165
+ * Core fields guaranteed to be present:
166
+ * - request_index: Position in the original request array
167
+ * - status: Operation outcome (created/duplicate/updated/failed)
168
+ * - transaction_id: YNAB transaction ID (if operation succeeded)
169
+ * - correlation_key: Key used to correlate request with response (import_id or hash)
170
+ * - error_code: Machine-readable error code (if operation failed)
171
+ * - error: Human-readable error message (if operation failed)
172
+ *
173
+ * @see src/tools/transactionTools.ts:1636-1855 - create_transactions handler
174
+ * @see src/tools/transactionTools.ts:2057-2462 - update_transactions handler
175
+ */
176
+ export const BulkResultSchema = z
177
+ .object({
178
+ request_index: z.number(),
179
+ status: z.enum(['created', 'duplicate', 'updated', 'failed']),
180
+ transaction_id: z.string().optional(),
181
+ correlation_key: z.string(),
182
+ error_code: z.string().optional(),
183
+ error: z.string().optional(),
184
+ })
185
+ .passthrough(); // Allow additional correlation metadata fields
186
+
187
+ export type BulkResult = z.infer<typeof BulkResultSchema>;
188
+
189
+ /**
190
+ * Transaction diff fields for bulk update dry-run before/after comparison.
191
+ * Contains only the fields that changed between current and updated state.
192
+ *
193
+ * @see src/tools/transactionTools.ts:2139-2192 - update_transactions dry-run diff building
194
+ */
195
+ export const TransactionDiffFieldsSchema = z.object({
196
+ amount: z.number().optional(),
197
+ date: z
198
+ .string()
199
+ .regex(/^\d{4}-\d{2}-\d{2}$/)
200
+ .optional(),
201
+ memo: z.string().optional(),
202
+ payee_id: z.string().nullable().optional(),
203
+ payee_name: z.string().nullable().optional(),
204
+ category_id: z.string().nullable().optional(),
205
+ cleared: z.enum(['cleared', 'uncleared', 'reconciled']).optional(),
206
+ approved: z.boolean().optional(),
207
+ flag_color: z.enum(['red', 'orange', 'yellow', 'green', 'blue', 'purple']).nullable().optional(),
208
+ });
209
+
210
+ export type TransactionDiffFields = z.infer<typeof TransactionDiffFieldsSchema>;
211
+
212
+ /**
213
+ * Before/after preview for bulk update dry-run.
214
+ * Shows changed fields for each transaction in dry-run mode.
215
+ *
216
+ * @see src/tools/transactionTools.ts:2057-2462 - update_transactions handler
217
+ */
218
+ export const DryRunPreviewItemSchema = z.object({
219
+ transaction_id: z.string(),
220
+ before: z.union([z.literal('unavailable'), TransactionDiffFieldsSchema]),
221
+ after: TransactionDiffFieldsSchema,
222
+ });
223
+
224
+ export type DryRunPreviewItem = z.infer<typeof DryRunPreviewItemSchema>;
225
+
226
+ /**
227
+ * Warning in dry-run responses.
228
+ * Alerts about potential issues before execution.
229
+ *
230
+ * @see src/tools/transactionTools.ts:2057-2462 - update_transactions handler
231
+ */
232
+ export const DryRunWarningSchema = z.object({
233
+ code: z.string(),
234
+ count: z.number(),
235
+ message: z.string(),
236
+ sample_ids: z.array(z.string()).optional(),
237
+ });
238
+
239
+ export type DryRunWarning = z.infer<typeof DryRunWarningSchema>;
240
+
241
+ // ============================================================================
242
+ // MAIN OUTPUT SCHEMAS
243
+ // ============================================================================
244
+
245
+ /**
246
+ * Single transaction creation output.
247
+ * Returns created transaction with account balance information.
248
+ *
249
+ * @see src/tools/transactionTools.ts:950-1094 - create_transaction handler
250
+ *
251
+ * @example
252
+ * // Normal execution
253
+ * {
254
+ * transaction: {
255
+ * id: "txn-123",
256
+ * date: "2025-11-18",
257
+ * amount: -25500,
258
+ * account_balance: 1500000, // Raw milliunits: $1,500.00
259
+ * account_cleared_balance: 1000000 // Raw milliunits: $1,000.00
260
+ * }
261
+ * }
262
+ *
263
+ * @example
264
+ * // Dry-run mode
265
+ * {
266
+ * dry_run: true,
267
+ * action: "create_transaction",
268
+ * request: { date: "2025-11-18", amount: -25.50, account_id: "acct-1" }
269
+ * }
270
+ */
271
+ export const CreateTransactionOutputSchema = z.union([
272
+ z.object({
273
+ dry_run: z.literal(true),
274
+ action: z.literal('create_transaction'),
275
+ request: z.record(z.string(), z.unknown()),
276
+ }),
277
+ z.object({
278
+ transaction: TransactionWithBalanceSchema,
279
+ }),
280
+ ]);
281
+
282
+ export type CreateTransactionOutput = z.infer<typeof CreateTransactionOutputSchema>;
283
+
284
+ /**
285
+ * Transaction preview item for bulk create dry-run.
286
+ * Shows planned transaction details before execution.
287
+ *
288
+ * @see src/tools/transactionTools.ts:1742-1752 - create_transactions dry-run preview
289
+ */
290
+ export const CreateTransactionPreviewSchema = z.object({
291
+ request_index: z.number(),
292
+ account_id: z.string(),
293
+ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
294
+ amount: z.number(),
295
+ memo: z.string().optional(),
296
+ payee_id: z.string().optional(),
297
+ payee_name: z.string().optional(),
298
+ category_id: z.string().optional(),
299
+ import_id: z.string().optional(),
300
+ });
301
+
302
+ export type CreateTransactionPreview = z.infer<typeof CreateTransactionPreviewSchema>;
303
+
304
+ /**
305
+ * Bulk transaction creation output.
306
+ * Returns summary, correlation results, and optional full transaction data.
307
+ * Response mode (full/summary/ids_only) adapts to result size for MCP 100KB limit.
308
+ *
309
+ * @see src/tools/transactionTools.ts:1636-1855 - create_transactions handler
310
+ *
311
+ * @example
312
+ * // Dry-run mode
313
+ * {
314
+ * dry_run: true,
315
+ * action: "create_transactions",
316
+ * validation: "passed",
317
+ * summary: {
318
+ * total_transactions: 100,
319
+ * total_amount: 1500.00,
320
+ * accounts_affected: ["acct-1", "acct-2"],
321
+ * date_range: { earliest: "2025-01-01", latest: "2025-01-31" },
322
+ * categories_affected: ["cat-1", "cat-2"]
323
+ * },
324
+ * transactions_preview: [
325
+ * { request_index: 0, account_id: "acct-1", date: "2025-01-15", amount: 25.50, ... }
326
+ * ],
327
+ * note: "This is a dry run. No transactions were created."
328
+ * }
329
+ *
330
+ * @example
331
+ * // Execution mode (summary)
332
+ * {
333
+ * success: true,
334
+ * summary: { total_requested: 100, created: 95, duplicates: 3, failed: 2 },
335
+ * results: [
336
+ * { request_index: 0, status: "created", transaction_id: "txn-1", correlation_key: "import-123" },
337
+ * { request_index: 1, status: "duplicate", correlation_key: "import-124" }
338
+ * ],
339
+ * mode: "summary"
340
+ * }
341
+ */
342
+ export const CreateTransactionsOutputSchema = z.union([
343
+ // Dry-run mode: Strict schema for preview validation
344
+ z
345
+ .object({
346
+ dry_run: z.literal(true),
347
+ action: z.literal('create_transactions'),
348
+ validation: z.literal('passed'),
349
+ summary: z.object({
350
+ total_transactions: z.number(),
351
+ total_amount: z.number(),
352
+ accounts_affected: z.array(z.string()),
353
+ date_range: z
354
+ .object({
355
+ earliest: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
356
+ latest: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
357
+ })
358
+ .optional(),
359
+ categories_affected: z.array(z.string()),
360
+ }),
361
+ transactions_preview: z.array(CreateTransactionPreviewSchema),
362
+ note: z.string(),
363
+ })
364
+ .strict(), // Strict for dry-run to prevent malformed previews
365
+ // Execution mode: Allow passthrough for correlation metadata extension
366
+ z
367
+ .object({
368
+ success: z.boolean(),
369
+ server_knowledge: z.number().optional(),
370
+ summary: BulkOperationSummarySchema,
371
+ results: z.array(BulkResultSchema),
372
+ transactions: z.array(TransactionSchema).optional(),
373
+ duplicate_import_ids: z.array(z.string()).optional(),
374
+ message: z.string().optional(),
375
+ mode: z.enum(['full', 'summary', 'ids_only']).optional(),
376
+ })
377
+ .passthrough(), // Allow top-level metadata like batch_id, execution_id
378
+ ]);
379
+
380
+ export type CreateTransactionsOutput = z.infer<typeof CreateTransactionsOutputSchema>;
381
+
382
+ /**
383
+ * Single transaction update output.
384
+ * Returns updated transaction with new account balances.
385
+ *
386
+ * @see src/tools/transactionTools.ts:1336-1530 - update_transaction handler
387
+ *
388
+ * @example
389
+ * // Normal execution
390
+ * {
391
+ * transaction: { id: "txn-123", amount: -30000, ... },
392
+ * updated_balance: 1450000, // Raw milliunits: $1,450.00
393
+ * updated_cleared_balance: 950000 // Raw milliunits: $950.00
394
+ * }
395
+ *
396
+ * @example
397
+ * // Dry-run mode
398
+ * {
399
+ * dry_run: true,
400
+ * action: "update_transaction",
401
+ * request: { transaction_id: "txn-123", amount: -30.00 }
402
+ * }
403
+ */
404
+ export const UpdateTransactionOutputSchema = z.union([
405
+ z.object({
406
+ dry_run: z.literal(true),
407
+ action: z.literal('update_transaction'),
408
+ request: z.record(z.string(), z.unknown()),
409
+ }),
410
+ z.object({
411
+ transaction: TransactionWithBalanceSchema,
412
+ updated_balance: z.number(), // Raw YNAB milliunits
413
+ updated_cleared_balance: z.number(), // Raw YNAB milliunits
414
+ }),
415
+ ]);
416
+
417
+ export type UpdateTransactionOutput = z.infer<typeof UpdateTransactionOutputSchema>;
418
+
419
+ /**
420
+ * Bulk transaction update output.
421
+ * Returns summary, correlation results, and optional preview/full data.
422
+ * Dry-run mode shows before/after preview for changed fields.
423
+ *
424
+ * @see src/tools/transactionTools.ts:2057-2462 - update_transactions handler
425
+ *
426
+ * @example
427
+ * // Dry-run mode
428
+ * {
429
+ * dry_run: true,
430
+ * action: "update_transactions",
431
+ * validation: "passed",
432
+ * summary: {
433
+ * total_transactions: 50,
434
+ * accounts_affected: 3,
435
+ * fields_to_update: ["cleared", "category_id"]
436
+ * },
437
+ * transactions_preview: [
438
+ * {
439
+ * transaction_id: "txn-1",
440
+ * before: { cleared: "uncleared", category_id: "cat-1" },
441
+ * after: { cleared: "cleared", category_id: "cat-2" }
442
+ * }
443
+ * ],
444
+ * warnings: [
445
+ * { code: "LARGE_BATCH", count: 50, message: "Large batch detected" }
446
+ * ],
447
+ * note: "This is a dry run. No transactions were updated."
448
+ * }
449
+ *
450
+ * @example
451
+ * // Execution mode (summary)
452
+ * {
453
+ * success: true,
454
+ * summary: { total_requested: 50, updated: 48, failed: 2 },
455
+ * results: [
456
+ * { request_index: 0, status: "updated", transaction_id: "txn-1", correlation_key: "hash-abc123" }
457
+ * ],
458
+ * mode: "summary"
459
+ * }
460
+ */
461
+ export const UpdateTransactionsOutputSchema = z.union([
462
+ // Dry-run mode: Strict schema for preview validation
463
+ z
464
+ .object({
465
+ dry_run: z.literal(true),
466
+ action: z.literal('update_transactions'),
467
+ validation: z.literal('passed'),
468
+ summary: z.object({
469
+ total_transactions: z.number(),
470
+ accounts_affected: z.number(),
471
+ fields_to_update: z.array(z.string()),
472
+ }),
473
+ transactions_preview: z.array(DryRunPreviewItemSchema),
474
+ warnings: z.array(DryRunWarningSchema).optional(),
475
+ note: z.string(),
476
+ })
477
+ .strict(), // Strict for dry-run to prevent malformed previews
478
+ // Execution mode: Allow passthrough for correlation metadata extension
479
+ z
480
+ .object({
481
+ success: z.boolean(),
482
+ server_knowledge: z.number().optional(),
483
+ summary: BulkOperationSummarySchema,
484
+ results: z.array(BulkResultSchema),
485
+ transactions: z.array(TransactionSchema).optional(),
486
+ message: z.string().optional(),
487
+ mode: z.enum(['full', 'summary', 'ids_only']).optional(),
488
+ })
489
+ .passthrough(), // Allow top-level metadata like batch_id, execution_id
490
+ ]);
491
+
492
+ export type UpdateTransactionsOutput = z.infer<typeof UpdateTransactionsOutputSchema>;
493
+
494
+ /**
495
+ * Transaction deletion output.
496
+ * Returns deletion confirmation with updated account balances.
497
+ *
498
+ * @see src/tools/transactionTools.ts:1536-1634 - delete_transaction handler
499
+ *
500
+ * @example
501
+ * // Normal execution
502
+ * {
503
+ * message: "Transaction deleted successfully",
504
+ * transaction: { id: "txn-123", deleted: true },
505
+ * updated_balance: 175500,
506
+ * updated_cleared_balance: 125500
507
+ * }
508
+ *
509
+ * @example
510
+ * // Dry-run mode
511
+ * {
512
+ * dry_run: true,
513
+ * action: "delete_transaction",
514
+ * request: { transaction_id: "txn-123" }
515
+ * }
516
+ */
517
+ export const DeleteTransactionOutputSchema = z.union([
518
+ z.object({
519
+ dry_run: z.literal(true),
520
+ action: z.literal('delete_transaction'),
521
+ request: z.record(z.string(), z.unknown()),
522
+ }),
523
+ z.object({
524
+ message: z.string(),
525
+ transaction: z.object({
526
+ id: z.string(),
527
+ deleted: z.boolean(),
528
+ }),
529
+ updated_balance: z.number(), // Raw YNAB milliunits
530
+ updated_cleared_balance: z.number(), // Raw YNAB milliunits
531
+ }),
532
+ ]);
533
+
534
+ export type DeleteTransactionOutput = z.infer<typeof DeleteTransactionOutputSchema>;
535
+
536
+ /**
537
+ * Transaction preview schema for dry-run responses.
538
+ * Contains essential transaction fields before the transaction is created.
539
+ * Excludes server-generated fields like 'id' and balance information.
540
+ *
541
+ * @remarks
542
+ * This schema is used in dry-run mode to preview what a transaction will look like
543
+ * before it's actually created. It includes the fields that will be sent to the API
544
+ * but excludes fields that are generated by the server (id, balances, timestamps, etc.).
545
+ *
546
+ * Note: This is distinct from TransactionPreviewSchema in transactionOutputs.ts, which is
547
+ * used for large result set previews in list_transactions responses.
548
+ *
549
+ * @see CreateReceiptSplitTransactionOutputSchema - Used in dry-run branch for transaction preview
550
+ */
551
+ export const TransactionDryRunPreviewSchema = z.object({
552
+ account_id: z.string(),
553
+ date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
554
+ amount: z.number(),
555
+ memo: z.string().optional().nullable(),
556
+ cleared: z.enum(['cleared', 'uncleared', 'reconciled']).optional(),
557
+ approved: z.boolean().optional(),
558
+ flag_color: z.enum(['red', 'orange', 'yellow', 'green', 'blue', 'purple']).optional().nullable(),
559
+ payee_id: z.string().optional().nullable(),
560
+ payee_name: z.string().optional().nullable(),
561
+ category_id: z.string().optional().nullable(),
562
+ import_id: z.string().optional().nullable(),
563
+ });
564
+
565
+ export type TransactionDryRunPreview = z.infer<typeof TransactionDryRunPreviewSchema>;
566
+
567
+ /**
568
+ * Subtransaction preview schema for dry-run responses.
569
+ * Contains subtransaction fields before they are created by the server.
570
+ * Excludes server-generated fields like 'id', 'transaction_id', and 'deleted'.
571
+ *
572
+ * @remarks
573
+ * This schema is derived from SubtransactionSchema but omits fields that are
574
+ * generated by the server when the subtransaction is created.
575
+ *
576
+ * @see SubtransactionSchema - Full subtransaction schema with server-generated fields
577
+ * @see CreateReceiptSplitTransactionOutputSchema - Used in dry-run branch for subtransactions preview
578
+ */
579
+ export const SubtransactionPreviewSchema = SubtransactionSchema.omit({
580
+ id: true,
581
+ transaction_id: true,
582
+ deleted: true,
583
+ });
584
+
585
+ export type SubtransactionPreview = z.infer<typeof SubtransactionPreviewSchema>;
586
+
587
+ /**
588
+ * Receipt split transaction creation output.
589
+ * Returns created split transaction with itemized receipt breakdown.
590
+ *
591
+ * @see src/tools/transactionTools.ts:1160-1335 - create_receipt_split_transaction handler
592
+ *
593
+ * @example
594
+ * // Normal execution
595
+ * {
596
+ * transaction: {
597
+ * id: "txn-456",
598
+ * subtransactions: [
599
+ * { id: "sub-1", category_id: "cat-groceries", amount: -50000 },
600
+ * { id: "sub-2", category_id: "cat-tax", amount: -3500 }
601
+ * ]
602
+ * },
603
+ * receipt_summary: {
604
+ * subtotal: 50.00,
605
+ * tax: 3.50,
606
+ * total: 53.50,
607
+ * categories: [
608
+ * { category_id: "cat-groceries", items: [...], subtotal: 50.00, tax: 3.50, total: 53.50 }
609
+ * ]
610
+ * }
611
+ * }
612
+ *
613
+ * @example
614
+ * // Dry-run mode
615
+ * {
616
+ * dry_run: true,
617
+ * action: "create_receipt_split_transaction",
618
+ * transaction_preview: {
619
+ * account_id: "acct-1",
620
+ * date: "2025-11-18",
621
+ * amount: -53500,
622
+ * cleared: "cleared",
623
+ * approved: true
624
+ * },
625
+ * receipt_summary: { subtotal: 50.00, tax: 3.50, total: 53.50, categories: [...] },
626
+ * subtransactions: [
627
+ * { amount: -50000, category_id: "cat-groceries", memo: "Groceries" },
628
+ * { amount: -3500, category_id: "cat-tax", memo: "Tax" }
629
+ * ]
630
+ * }
631
+ */
632
+ export const CreateReceiptSplitTransactionOutputSchema = z.union([
633
+ z.object({
634
+ dry_run: z.literal(true),
635
+ action: z.literal('create_receipt_split_transaction'),
636
+ transaction_preview: TransactionDryRunPreviewSchema,
637
+ receipt_summary: ReceiptSummarySchema,
638
+ subtransactions: z.array(SubtransactionPreviewSchema),
639
+ }),
640
+ z.object({
641
+ transaction: TransactionWithBalanceSchema,
642
+ receipt_summary: ReceiptSummarySchema,
643
+ }),
644
+ ]);
645
+
646
+ export type CreateReceiptSplitTransactionOutput = z.infer<
647
+ typeof CreateReceiptSplitTransactionOutputSchema
648
+ >;
649
+
650
+ /**
651
+ * Create account dry-run request schema.
652
+ * Documents the planned account creation operation before execution.
653
+ *
654
+ * @see src/tools/accountTools.ts:218-233 - create_account dry-run response construction
655
+ */
656
+ export const CreateAccountDryRunRequestSchema = z.object({
657
+ budget_id: z.string(),
658
+ name: z.string(),
659
+ type: z.string(),
660
+ balance: z.number(),
661
+ });
662
+
663
+ export type CreateAccountDryRunRequest = z.infer<typeof CreateAccountDryRunRequestSchema>;
664
+
665
+ /**
666
+ * Account creation output.
667
+ * Returns created account entity.
668
+ *
669
+ * @see src/tools/accountTools.ts:196-283 - create_account handler
670
+ *
671
+ * @example
672
+ * // Normal execution
673
+ * {
674
+ * account: {
675
+ * id: "acct-789",
676
+ * name: "Savings Account",
677
+ * type: "savings",
678
+ * balance: 0,
679
+ * cleared_balance: 0
680
+ * }
681
+ * }
682
+ *
683
+ * @example
684
+ * // Dry-run mode
685
+ * {
686
+ * dry_run: true,
687
+ * action: "create_account",
688
+ * request: { budget_id: "budget-1", name: "Savings Account", type: "savings", balance: 0 }
689
+ * }
690
+ */
691
+ export const CreateAccountOutputSchema = z.union([
692
+ z.object({
693
+ dry_run: z.literal(true),
694
+ action: z.literal('create_account'),
695
+ request: CreateAccountDryRunRequestSchema,
696
+ }),
697
+ z.object({
698
+ account: AccountSchema,
699
+ }),
700
+ ]);
701
+
702
+ export type CreateAccountOutput = z.infer<typeof CreateAccountOutputSchema>;
703
+
704
+ /**
705
+ * Update category dry-run request schema.
706
+ * Documents the planned category update operation before execution.
707
+ *
708
+ * @see src/tools/categoryTools.ts:237-256 - update_category dry-run response construction
709
+ */
710
+ export const UpdateCategoryDryRunRequestSchema = z.object({
711
+ budget_id: z.string(),
712
+ category_id: z.string(),
713
+ budgeted: z.number(),
714
+ month: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
715
+ });
716
+
717
+ export type UpdateCategoryDryRunRequest = z.infer<typeof UpdateCategoryDryRunRequestSchema>;
718
+
719
+ /**
720
+ * Category budget update output.
721
+ * Returns updated category with month context.
722
+ *
723
+ * @see src/tools/categoryTools.ts:194-309 - update_category handler
724
+ *
725
+ * @example
726
+ * // Normal execution
727
+ * {
728
+ * category: {
729
+ * id: "cat-123",
730
+ * name: "Groceries",
731
+ * budgeted: 50000,
732
+ * activity: -35000,
733
+ * balance: 15000
734
+ * },
735
+ * updated_month: "2025-11-01"
736
+ * }
737
+ *
738
+ * @example
739
+ * // Dry-run mode
740
+ * {
741
+ * dry_run: true,
742
+ * action: "update_category",
743
+ * request: { budget_id: "budget-1", category_id: "cat-123", month: "2025-11-01", budgeted: 500.00 }
744
+ * }
745
+ */
746
+ export const UpdateCategoryOutputSchema = z.union([
747
+ z.object({
748
+ dry_run: z.literal(true),
749
+ action: z.literal('update_category'),
750
+ request: UpdateCategoryDryRunRequestSchema,
751
+ }),
752
+ z.object({
753
+ category: CategorySchema,
754
+ updated_month: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
755
+ }),
756
+ ]);
757
+
758
+ export type UpdateCategoryOutput = z.infer<typeof UpdateCategoryOutputSchema>;