@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,363 @@
1
+ /**
2
+ * Human-readable report formatting for reconciliation results
3
+ * Implements Phase 3 of dual-channel output improvements
4
+ */
5
+
6
+ import type {
7
+ ReconciliationAnalysis,
8
+ TransactionMatch,
9
+ BankTransaction,
10
+ YNABTransaction,
11
+ ReconciliationInsight,
12
+ BalanceInfo,
13
+ } from './types.js';
14
+ import type { LegacyReconciliationResult } from './executor.js';
15
+ import type { MoneyValue } from '../../utils/money.js';
16
+
17
+ /**
18
+ * Options for report formatting
19
+ */
20
+ export interface ReportFormatterOptions {
21
+ accountName?: string | undefined;
22
+ accountId?: string | undefined;
23
+ currencyCode?: string | undefined;
24
+ includeDetailedMatches?: boolean | undefined;
25
+ maxUnmatchedToShow?: number | undefined;
26
+ maxInsightsToShow?: number | undefined;
27
+ }
28
+
29
+ /**
30
+ * Format the main human-readable reconciliation report
31
+ */
32
+ export function formatHumanReadableReport(
33
+ analysis: ReconciliationAnalysis,
34
+ options: ReportFormatterOptions = {},
35
+ execution?: LegacyReconciliationResult,
36
+ ): string {
37
+ const accountLabel = options.accountName ?? 'Account';
38
+ const sections: string[] = [];
39
+
40
+ // Header
41
+ sections.push(formatHeader(accountLabel, analysis));
42
+
43
+ // Balance check section
44
+ sections.push(formatBalanceSection(analysis.balance_info, analysis.summary));
45
+
46
+ // Transaction analysis section
47
+ sections.push(formatTransactionAnalysisSection(analysis, options));
48
+
49
+ // Insights section (if any)
50
+ if (analysis.insights.length > 0) {
51
+ sections.push(formatInsightsSection(analysis.insights, options.maxInsightsToShow));
52
+ }
53
+
54
+ // Execution summary (if any)
55
+ if (execution) {
56
+ sections.push(formatExecutionSection(execution));
57
+ }
58
+
59
+ // Recommendations/Next steps
60
+ sections.push(formatRecommendationsSection(analysis, execution));
61
+
62
+ return sections.join('\n\n');
63
+ }
64
+
65
+ /**
66
+ * Format the report header
67
+ */
68
+ function formatHeader(accountName: string, analysis: ReconciliationAnalysis): string {
69
+ const lines: string[] = [];
70
+ lines.push(`📊 ${accountName} Reconciliation Report`);
71
+ lines.push('═'.repeat(60));
72
+ lines.push(`Statement Period: ${analysis.summary.statement_date_range}`);
73
+ return lines.join('\n');
74
+ }
75
+
76
+ /**
77
+ * Format the balance check section
78
+ */
79
+ function formatBalanceSection(
80
+ balanceInfo: BalanceInfo,
81
+ summary: ReconciliationAnalysis['summary'],
82
+ ): string {
83
+ const lines: string[] = [];
84
+ lines.push('BALANCE CHECK');
85
+ lines.push('═'.repeat(60));
86
+
87
+ // Current balances
88
+ lines.push(`✓ YNAB Cleared Balance: ${summary.current_cleared_balance.value_display}`);
89
+ lines.push(`✓ Statement Balance: ${summary.target_statement_balance.value_display}`);
90
+ lines.push('');
91
+
92
+ // Discrepancy status
93
+ const discrepancyMilli = balanceInfo.discrepancy.value_milliunits;
94
+ if (discrepancyMilli === 0) {
95
+ lines.push('✅ BALANCES MATCH PERFECTLY');
96
+ } else {
97
+ const direction = discrepancyMilli > 0 ? 'ynab_higher' : 'bank_higher';
98
+ const directionLabel =
99
+ direction === 'ynab_higher'
100
+ ? 'YNAB shows MORE than statement'
101
+ : 'Statement shows MORE than YNAB';
102
+
103
+ lines.push(`❌ DISCREPANCY: ${balanceInfo.discrepancy.value_display}`);
104
+ lines.push(` Direction: ${directionLabel}`);
105
+ }
106
+
107
+ return lines.join('\n');
108
+ }
109
+
110
+ /**
111
+ * Format the transaction analysis section
112
+ */
113
+ function formatTransactionAnalysisSection(
114
+ analysis: ReconciliationAnalysis,
115
+ options: ReportFormatterOptions,
116
+ ): string {
117
+ const lines: string[] = [];
118
+ lines.push('TRANSACTION ANALYSIS');
119
+ lines.push('═'.repeat(60));
120
+
121
+ const summary = analysis.summary;
122
+ lines.push(
123
+ `✓ Automatically matched: ${summary.auto_matched} of ${summary.bank_transactions_count} transactions`,
124
+ );
125
+ lines.push(`✓ Suggested matches: ${summary.suggested_matches}`);
126
+ lines.push(`✓ Unmatched bank: ${summary.unmatched_bank}`);
127
+ lines.push(`✓ Unmatched YNAB: ${summary.unmatched_ynab}`);
128
+
129
+ // Show unmatched bank transactions (if any)
130
+ if (analysis.unmatched_bank.length > 0) {
131
+ lines.push('');
132
+ lines.push('❌ UNMATCHED BANK TRANSACTIONS:');
133
+ const maxToShow = options.maxUnmatchedToShow ?? 5;
134
+ const toShow = analysis.unmatched_bank.slice(0, maxToShow);
135
+
136
+ for (const txn of toShow) {
137
+ lines.push(formatBankTransactionLine(txn));
138
+ }
139
+
140
+ if (analysis.unmatched_bank.length > maxToShow) {
141
+ lines.push(` ... and ${analysis.unmatched_bank.length - maxToShow} more`);
142
+ }
143
+ }
144
+
145
+ // Show suggested matches (if any)
146
+ if (analysis.suggested_matches.length > 0) {
147
+ lines.push('');
148
+ lines.push('💡 SUGGESTED MATCHES:');
149
+ const maxToShow = options.maxUnmatchedToShow ?? 3;
150
+ const toShow = analysis.suggested_matches.slice(0, maxToShow);
151
+
152
+ for (const match of toShow) {
153
+ lines.push(formatSuggestedMatchLine(match));
154
+ }
155
+
156
+ if (analysis.suggested_matches.length > maxToShow) {
157
+ lines.push(` ... and ${analysis.suggested_matches.length - maxToShow} more suggestions`);
158
+ }
159
+ }
160
+
161
+ return lines.join('\n');
162
+ }
163
+
164
+ /**
165
+ * Format a bank transaction line
166
+ */
167
+ function formatBankTransactionLine(txn: BankTransaction): string {
168
+ const amountStr = formatAmount(txn.amount);
169
+ return ` ${txn.date} - ${txn.payee.substring(0, 40).padEnd(40)} ${amountStr}`;
170
+ }
171
+
172
+ /**
173
+ * Format a suggested match line
174
+ */
175
+ function formatSuggestedMatchLine(match: TransactionMatch): string {
176
+ const bankTxn = match.bank_transaction;
177
+ const amountStr = formatAmount(bankTxn.amount);
178
+ const confidenceStr = `${match.confidence_score}%`;
179
+ return ` ${bankTxn.date} - ${bankTxn.payee.substring(0, 35).padEnd(35)} ${amountStr} (${confidenceStr} confidence)`;
180
+ }
181
+
182
+ /**
183
+ * Format an amount for display
184
+ */
185
+ function formatAmount(amount: number): string {
186
+ const sign = amount >= 0 ? '+' : '-';
187
+ const absAmount = Math.abs(amount);
188
+ return `${sign}$${absAmount.toFixed(2)}`.padStart(10);
189
+ }
190
+
191
+ /**
192
+ * Format the insights section
193
+ */
194
+ function formatInsightsSection(insights: ReconciliationInsight[], maxToShow: number = 3): string {
195
+ const lines: string[] = [];
196
+ lines.push('KEY INSIGHTS');
197
+ lines.push('═'.repeat(60));
198
+
199
+ const toShow = insights.slice(0, maxToShow);
200
+ for (const insight of toShow) {
201
+ const severityIcon = getSeverityIcon(insight.severity);
202
+ lines.push(`${severityIcon} ${insight.title}`);
203
+ lines.push(` ${insight.description}`);
204
+
205
+ // Show evidence summary if available
206
+ if (insight.evidence && Object.keys(insight.evidence).length > 0) {
207
+ const evidenceSummary = formatEvidenceSummary(insight.evidence);
208
+ if (evidenceSummary) {
209
+ lines.push(` Evidence: ${evidenceSummary}`);
210
+ }
211
+ }
212
+
213
+ lines.push('');
214
+ }
215
+
216
+ if (insights.length > maxToShow) {
217
+ lines.push(`... and ${insights.length - maxToShow} more insights (see structured output)`);
218
+ }
219
+
220
+ return lines.join('\n').trimEnd();
221
+ }
222
+
223
+ /**
224
+ * Get emoji icon for severity level
225
+ */
226
+ function getSeverityIcon(severity: string): string {
227
+ switch (severity) {
228
+ case 'critical':
229
+ return '🚨';
230
+ case 'warning':
231
+ return '⚠️';
232
+ case 'info':
233
+ return 'ℹ️';
234
+ default:
235
+ return '•';
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Format evidence summary from insight evidence object
241
+ */
242
+ function formatEvidenceSummary(evidence: Record<string, unknown>): string | null {
243
+ // Handle common evidence patterns
244
+ if ('transaction_count' in evidence) {
245
+ return `${evidence['transaction_count']} transactions`;
246
+ }
247
+ if ('amount' in evidence && typeof evidence['amount'] === 'object') {
248
+ const amount = evidence['amount'] as MoneyValue;
249
+ return amount.value_display;
250
+ }
251
+ if ('transaction_ids' in evidence && Array.isArray(evidence['transaction_ids'])) {
252
+ return `${evidence['transaction_ids'].length} transactions involved`;
253
+ }
254
+ return null;
255
+ }
256
+
257
+ /**
258
+ * Format the execution section
259
+ */
260
+ function formatExecutionSection(execution: LegacyReconciliationResult): string {
261
+ const lines: string[] = [];
262
+ lines.push('EXECUTION SUMMARY');
263
+ lines.push('═'.repeat(60));
264
+
265
+ const summary = execution.summary;
266
+ lines.push(`• Transactions created: ${summary.transactions_created}`);
267
+ lines.push(`• Transactions updated: ${summary.transactions_updated}`);
268
+ lines.push(`• Date adjustments: ${summary.dates_adjusted}`);
269
+
270
+ // Show top recommendations if any
271
+ if (execution.recommendations.length > 0) {
272
+ lines.push('');
273
+ lines.push('Recommendations:');
274
+ const maxRecs = 3;
275
+ const toShow = execution.recommendations.slice(0, maxRecs);
276
+ for (const rec of toShow) {
277
+ lines.push(` • ${rec}`);
278
+ }
279
+ if (execution.recommendations.length > maxRecs) {
280
+ lines.push(` ... and ${execution.recommendations.length - maxRecs} more`);
281
+ }
282
+ }
283
+
284
+ lines.push('');
285
+ if (summary.dry_run) {
286
+ lines.push('⚠️ Dry run only — no YNAB changes were applied.');
287
+ } else {
288
+ lines.push('✅ Changes applied to YNAB. Review structured output for action details.');
289
+ }
290
+
291
+ return lines.join('\n');
292
+ }
293
+
294
+ /**
295
+ * Format the recommendations/next steps section
296
+ */
297
+ function formatRecommendationsSection(
298
+ analysis: ReconciliationAnalysis,
299
+ execution?: LegacyReconciliationResult,
300
+ ): string {
301
+ const lines: string[] = [];
302
+ lines.push('RECOMMENDED ACTIONS');
303
+ lines.push('═'.repeat(60));
304
+
305
+ // If we have execution results, recommendations are already shown
306
+ if (execution && !execution.summary.dry_run) {
307
+ lines.push('All recommended actions have been applied.');
308
+ return lines.join('\n');
309
+ }
310
+
311
+ // Show next steps from analysis
312
+ if (analysis.next_steps.length > 0) {
313
+ for (const step of analysis.next_steps) {
314
+ lines.push(`• ${step}`);
315
+ }
316
+ } else {
317
+ lines.push('• No specific actions recommended.');
318
+ lines.push('• Review the structured output for detailed match information.');
319
+ }
320
+
321
+ return lines.join('\n');
322
+ }
323
+
324
+ /**
325
+ * Format a balance section (helper for backward compatibility)
326
+ */
327
+ export function formatBalanceInfo(balance: BalanceInfo): string {
328
+ const lines: string[] = [];
329
+ lines.push(`Current Cleared: ${balance.current_cleared.value_display}`);
330
+ lines.push(`Current Total: ${balance.current_total.value_display}`);
331
+ lines.push(`Target Statement: ${balance.target_statement.value_display}`);
332
+ lines.push(`Discrepancy: ${balance.discrepancy.value_display}`);
333
+ return lines.join('\n');
334
+ }
335
+
336
+ /**
337
+ * Format transaction list (helper for detailed reports)
338
+ */
339
+ export function formatTransactionList(
340
+ transactions: BankTransaction[] | YNABTransaction[],
341
+ maxItems: number = 10,
342
+ ): string {
343
+ const lines: string[] = [];
344
+ const toShow = transactions.slice(0, maxItems);
345
+
346
+ for (const txn of toShow) {
347
+ if ('payee' in txn) {
348
+ // Bank transaction
349
+ lines.push(formatBankTransactionLine(txn));
350
+ } else {
351
+ // YNAB transaction
352
+ const amount = txn.amount / 1000; // Convert milliunits to dollars
353
+ const payee = txn.payee_name ?? 'Unknown';
354
+ lines.push(` ${txn.date} - ${payee.substring(0, 40).padEnd(40)} ${formatAmount(amount)}`);
355
+ }
356
+ }
357
+
358
+ if (transactions.length > maxItems) {
359
+ lines.push(` ... and ${transactions.length - maxItems} more`);
360
+ }
361
+
362
+ return lines.join('\n');
363
+ }
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Type definitions for the reconciliation tool
3
+ * Based on the 2025-10-31 reconciliation redesign specification
4
+ */
5
+
6
+ import type { MoneyValue } from '../../utils/money.js';
7
+
8
+ /**
9
+ * Matching confidence levels
10
+ */
11
+ export type MatchConfidence = 'high' | 'medium' | 'low' | 'none';
12
+
13
+ /**
14
+ * Bank transaction parsed from CSV
15
+ */
16
+ export interface BankTransaction {
17
+ /** Generated UUID for tracking */
18
+ id: string;
19
+ /** Transaction date in YYYY-MM-DD format */
20
+ date: string;
21
+ /** Amount in dollars */
22
+ amount: number;
23
+ /** Payee/merchant name */
24
+ payee: string;
25
+ /** Optional memo/description */
26
+ memo?: string;
27
+ /** Original CSV row number for debugging */
28
+ original_csv_row: number;
29
+ }
30
+
31
+ /**
32
+ * YNAB transaction (simplified from API)
33
+ */
34
+ export interface YNABTransaction {
35
+ id: string;
36
+ date: string;
37
+ /** Amount in milliunits */
38
+ amount: number;
39
+ payee_name: string | null;
40
+ category_name: string | null;
41
+ cleared: 'cleared' | 'uncleared' | 'reconciled';
42
+ approved: boolean;
43
+ memo?: string | null;
44
+ }
45
+
46
+ /**
47
+ * Match candidate with confidence score
48
+ */
49
+ export interface MatchCandidate {
50
+ ynab_transaction: YNABTransaction;
51
+ confidence: number;
52
+ match_reason: string;
53
+ explanation: string;
54
+ }
55
+
56
+ /**
57
+ * Transaction match result
58
+ */
59
+ export interface TransactionMatch {
60
+ bank_transaction: BankTransaction;
61
+ /** Best matched YNAB transaction (if any) */
62
+ ynab_transaction?: YNABTransaction;
63
+ /** Alternative candidates for suggested matches */
64
+ candidates?: MatchCandidate[];
65
+ /** Confidence level */
66
+ confidence: MatchConfidence;
67
+ /** Confidence score 0-100 */
68
+ confidence_score: number;
69
+ /** Reason for the match */
70
+ match_reason: string;
71
+ /** Top confidence from candidates */
72
+ top_confidence?: number;
73
+ /** Action hint for user */
74
+ action_hint?: string;
75
+ /** Recommendation text */
76
+ recommendation?: string;
77
+ }
78
+
79
+ /**
80
+ * Balance information with structured monetary values
81
+ */
82
+ export interface BalanceInfo {
83
+ current_cleared: MoneyValue;
84
+ current_uncleared: MoneyValue;
85
+ current_total: MoneyValue;
86
+ target_statement: MoneyValue;
87
+ discrepancy: MoneyValue;
88
+ on_track: boolean;
89
+ }
90
+
91
+ /**
92
+ * Reconciliation summary statistics with structured monetary values
93
+ */
94
+ export interface ReconciliationSummary {
95
+ statement_date_range: string;
96
+ bank_transactions_count: number;
97
+ ynab_transactions_count: number;
98
+ auto_matched: number;
99
+ suggested_matches: number;
100
+ unmatched_bank: number;
101
+ unmatched_ynab: number;
102
+ current_cleared_balance: MoneyValue;
103
+ target_statement_balance: MoneyValue;
104
+ discrepancy: MoneyValue;
105
+ discrepancy_explanation: string;
106
+ }
107
+
108
+ /**
109
+ * Insight severity levels
110
+ */
111
+ export type InsightSeverity = 'info' | 'warning' | 'critical';
112
+
113
+ /**
114
+ * Insight types for reconciliation analysis
115
+ */
116
+ export type InsightKind = 'repeat_amount' | 'near_match' | 'anomaly';
117
+
118
+ /**
119
+ * Reconciliation insight - highlights important findings that help explain discrepancies
120
+ */
121
+ export interface ReconciliationInsight {
122
+ id: string;
123
+ type: InsightKind;
124
+ severity: InsightSeverity;
125
+ title: string;
126
+ description: string;
127
+ evidence?: Record<string, unknown>;
128
+ }
129
+
130
+ /**
131
+ * Analysis phase result
132
+ */
133
+ export interface ReconciliationAnalysis {
134
+ success: true;
135
+ phase: 'analysis';
136
+ summary: ReconciliationSummary;
137
+ auto_matches: TransactionMatch[];
138
+ suggested_matches: TransactionMatch[];
139
+ unmatched_bank: BankTransaction[];
140
+ unmatched_ynab: YNABTransaction[];
141
+ balance_info: BalanceInfo;
142
+ next_steps: string[];
143
+ insights: ReconciliationInsight[];
144
+ recommendations?: ActionableRecommendation[];
145
+ }
146
+
147
+ /**
148
+ * Reconciliation action types
149
+ */
150
+ export type ReconciliationActionType = 'match' | 'add' | 'unclear' | 'delete' | 'ignore';
151
+
152
+ /**
153
+ * Reconciliation action
154
+ */
155
+ export interface ReconciliationAction {
156
+ type: ReconciliationActionType;
157
+ bank_txn_id?: string;
158
+ ynab_txn_id?: string;
159
+ mark_cleared?: boolean;
160
+ create_as_cleared?: boolean;
161
+ reason?: string;
162
+ metadata?: Record<string, unknown>;
163
+ }
164
+
165
+ /**
166
+ * Matching algorithm configuration
167
+ */
168
+ export interface MatchingConfig {
169
+ /** Date tolerance in days */
170
+ dateToleranceDays: number;
171
+ /** Amount tolerance in cents */
172
+ amountToleranceCents: number;
173
+ /** Description similarity threshold (0-1) */
174
+ descriptionSimilarityThreshold: number;
175
+ /** Confidence threshold for auto-matching (0-100) */
176
+ autoMatchThreshold: number;
177
+ /** Confidence threshold for suggestions (0-100) */
178
+ suggestionThreshold: number;
179
+ }
180
+
181
+ /**
182
+ * Default matching configuration (not type-only for use in code)
183
+ */
184
+ export const DEFAULT_MATCHING_CONFIG = {
185
+ dateToleranceDays: 2,
186
+ amountToleranceCents: 1,
187
+ descriptionSimilarityThreshold: 0.8,
188
+ autoMatchThreshold: 90,
189
+ suggestionThreshold: 60,
190
+ };
191
+
192
+ /**
193
+ * Parsed CSV data from compareTransactions
194
+ */
195
+ export interface ParsedCSVData {
196
+ transactions: BankTransaction[];
197
+ format_detected: string;
198
+ delimiter: string;
199
+ total_rows: number;
200
+ valid_rows: number;
201
+ errors: string[];
202
+ }
203
+
204
+ /**
205
+ * Priority levels for actionable recommendations
206
+ */
207
+ export type RecommendationPriority = 'high' | 'medium' | 'low';
208
+
209
+ /**
210
+ * Base fields common to all recommendation types
211
+ */
212
+ export interface BaseRecommendation {
213
+ /** Unique identifier for this recommendation */
214
+ id: string;
215
+ /** Priority level for execution */
216
+ priority: RecommendationPriority;
217
+ /** Confidence score 0-1 (higher = more confident) */
218
+ confidence: number;
219
+ /** Human-readable message describing the recommendation */
220
+ message: string;
221
+ /** Explanation of why this recommendation was generated */
222
+ reason: string;
223
+ /** Estimated impact on reconciliation balance */
224
+ estimated_impact: MoneyValue;
225
+ /** YNAB account ID this recommendation applies to */
226
+ account_id: string;
227
+ /** Optional link to the insight that generated this recommendation */
228
+ source_insight_id?: string;
229
+ /** Additional metadata (version, timestamps, etc.) */
230
+ metadata?: Record<string, unknown>;
231
+ }
232
+
233
+ /**
234
+ * Recommendation to create a new YNAB transaction
235
+ */
236
+ export interface CreateTransactionRecommendation extends BaseRecommendation {
237
+ action_type: 'create_transaction';
238
+ parameters: {
239
+ account_id: string;
240
+ date: string;
241
+ amount: number;
242
+ payee_name: string;
243
+ memo?: string;
244
+ cleared: 'cleared' | 'uncleared';
245
+ approved: boolean;
246
+ category_id?: string;
247
+ };
248
+ }
249
+
250
+ /**
251
+ * Recommendation to update a transaction's cleared status
252
+ */
253
+ export interface UpdateClearedRecommendation extends BaseRecommendation {
254
+ action_type: 'update_cleared';
255
+ parameters: {
256
+ transaction_id: string;
257
+ cleared: 'cleared' | 'uncleared' | 'reconciled';
258
+ };
259
+ }
260
+
261
+ /**
262
+ * Recommendation to review potential duplicate transactions
263
+ */
264
+ export interface ReviewDuplicateRecommendation extends BaseRecommendation {
265
+ action_type: 'review_duplicate';
266
+ parameters: {
267
+ candidate_ids: string[];
268
+ bank_transaction?: BankTransaction;
269
+ suggested_match_id?: string;
270
+ };
271
+ }
272
+
273
+ /**
274
+ * Related transaction reference for manual review
275
+ */
276
+ export interface RelatedTransaction {
277
+ source: 'bank' | 'ynab';
278
+ id: string;
279
+ description: string;
280
+ }
281
+
282
+ /**
283
+ * Recommendation requiring manual investigation
284
+ */
285
+ export interface ManualReviewRecommendation extends BaseRecommendation {
286
+ action_type: 'manual_review';
287
+ parameters: {
288
+ issue_type: 'complex_match' | 'large_discrepancy' | 'unknown';
289
+ related_transactions?: RelatedTransaction[];
290
+ };
291
+ }
292
+
293
+ /**
294
+ * Union type of all possible recommendation types (discriminated by action_type)
295
+ */
296
+ export type ActionableRecommendation =
297
+ | CreateTransactionRecommendation
298
+ | UpdateClearedRecommendation
299
+ | ReviewDuplicateRecommendation
300
+ | ManualReviewRecommendation;
301
+
302
+ /**
303
+ * Context passed to recommendation engine for generating recommendations
304
+ */
305
+ export interface RecommendationContext {
306
+ /** Account ID for the recommendations */
307
+ account_id: string;
308
+ /** Budget ID (reserved for future category suggestions) */
309
+ budget_id: string;
310
+ /** The reconciliation analysis results */
311
+ analysis: ReconciliationAnalysis;
312
+ /** Matching configuration used during analysis */
313
+ matching_config: MatchingConfig;
314
+ }