@dizzlkheinz/ynab-mcpb 0.18.2 → 0.18.4

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 (34) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/bundle/index.cjs +40 -40
  3. package/dist/tools/reconcileAdapter.js +3 -0
  4. package/dist/tools/reconciliation/analyzer.js +72 -7
  5. package/dist/tools/reconciliation/reportFormatter.js +26 -2
  6. package/dist/tools/reconciliation/types.d.ts +3 -0
  7. package/dist/tools/transactionSchemas.d.ts +309 -0
  8. package/dist/tools/transactionSchemas.js +215 -0
  9. package/dist/tools/transactionTools.d.ts +3 -281
  10. package/dist/tools/transactionTools.js +36 -568
  11. package/dist/tools/transactionUtils.d.ts +31 -0
  12. package/dist/tools/transactionUtils.js +349 -0
  13. package/docs/plans/2025-12-25-transaction-tools-refactor-design.md +211 -0
  14. package/docs/plans/2025-12-25-transaction-tools-refactor.md +905 -0
  15. package/package.json +4 -2
  16. package/scripts/run-all-tests.js +196 -0
  17. package/src/tools/__tests__/transactionSchemas.test.ts +1188 -0
  18. package/src/tools/__tests__/transactionTools.test.ts +83 -0
  19. package/src/tools/__tests__/transactionUtils.test.ts +989 -0
  20. package/src/tools/reconcileAdapter.ts +6 -0
  21. package/src/tools/reconciliation/__tests__/adapter.causes.test.ts +22 -8
  22. package/src/tools/reconciliation/__tests__/adapter.test.ts +3 -0
  23. package/src/tools/reconciliation/__tests__/analyzer.test.ts +65 -0
  24. package/src/tools/reconciliation/__tests__/recommendationEngine.test.ts +3 -0
  25. package/src/tools/reconciliation/__tests__/reportFormatter.test.ts +4 -1
  26. package/src/tools/reconciliation/__tests__/scenarios/adapterCurrency.scenario.test.ts +3 -0
  27. package/src/tools/reconciliation/__tests__/scenarios/extremes.scenario.test.ts +5 -1
  28. package/src/tools/reconciliation/__tests__/schemaUrl.test.ts +22 -8
  29. package/src/tools/reconciliation/analyzer.ts +127 -11
  30. package/src/tools/reconciliation/reportFormatter.ts +39 -2
  31. package/src/tools/reconciliation/types.ts +6 -0
  32. package/src/tools/transactionSchemas.ts +453 -0
  33. package/src/tools/transactionTools.ts +152 -835
  34. package/src/tools/transactionUtils.ts +536 -0
@@ -2107,6 +2107,89 @@ describe('transactionTools', () => {
2107
2107
  expect(collapsedSub.memo).toContain('Cheap Item');
2108
2108
  expect(collapsedSub.amount).toBe(25); // dry_run returns dollars
2109
2109
  });
2110
+
2111
+ it('should truncate single very long item name in itemized mode', async () => {
2112
+ // Create a name that's way longer than 150 chars
2113
+ const veryLongName = 'A'.repeat(200);
2114
+ const params = {
2115
+ budget_id: 'budget-123',
2116
+ account_id: 'account-456',
2117
+ payee_name: 'Store',
2118
+ date: '2025-10-13',
2119
+ receipt_tax: 1.0,
2120
+ receipt_total: 11.0,
2121
+ categories: [
2122
+ {
2123
+ category_id: 'category-groceries',
2124
+ category_name: 'Groceries',
2125
+ items: [{ name: veryLongName, amount: 10.0 }],
2126
+ },
2127
+ ],
2128
+ receipt_subtotal: 10.0,
2129
+ dry_run: true,
2130
+ } as const;
2131
+
2132
+ const result = await handleCreateReceiptSplitTransaction(mockYnabAPI, params);
2133
+ const parsed = JSON.parse(result.content[0].text);
2134
+
2135
+ // Should have 2 subtransactions: 1 itemized + 1 tax
2136
+ // (only 1 item, so no collapse, but name gets truncated)
2137
+ expect(parsed.subtransactions).toHaveLength(2);
2138
+
2139
+ const itemMemo = parsed.subtransactions[0].memo;
2140
+ // Memo should be truncated to exactly 150 chars
2141
+ expect(itemMemo.length).toBeLessThanOrEqual(150);
2142
+ // Should contain truncation indicator
2143
+ expect(itemMemo).toContain('...');
2144
+ // Should start with part of the original name
2145
+ expect(itemMemo.startsWith('AAA')).toBe(true);
2146
+ });
2147
+
2148
+ it('should truncate very long item name in collapsed mode while preserving amount', async () => {
2149
+ // Create a name that's way longer than 150 chars
2150
+ const veryLongName = 'B'.repeat(200);
2151
+ const params = {
2152
+ budget_id: 'budget-123',
2153
+ account_id: 'account-456',
2154
+ payee_name: 'Store',
2155
+ date: '2025-10-13',
2156
+ receipt_tax: 1.0,
2157
+ receipt_total: 61.0,
2158
+ categories: [
2159
+ {
2160
+ category_id: 'category-groceries',
2161
+ category_name: 'Groceries',
2162
+ items: [
2163
+ { name: veryLongName, amount: 10.0 }, // This one has very long name
2164
+ { name: 'Item2', amount: 10.0 },
2165
+ { name: 'Item3', amount: 10.0 },
2166
+ { name: 'Item4', amount: 10.0 },
2167
+ { name: 'Item5', amount: 10.0 },
2168
+ { name: 'Item6', amount: 10.0 },
2169
+ ],
2170
+ },
2171
+ ],
2172
+ receipt_subtotal: 60.0,
2173
+ dry_run: true,
2174
+ } as const;
2175
+
2176
+ const result = await handleCreateReceiptSplitTransaction(mockYnabAPI, params);
2177
+ const parsed = JSON.parse(result.content[0].text);
2178
+
2179
+ // 6 items -> collapse mode, long item first creates its own subtransaction
2180
+ // that gets truncated
2181
+ expect(parsed.subtransactions.length).toBeGreaterThanOrEqual(2);
2182
+
2183
+ // First subtransaction should be the truncated long item
2184
+ const firstMemo = parsed.subtransactions[0].memo;
2185
+ expect(firstMemo.length).toBeLessThanOrEqual(150);
2186
+ // In collapsed mode, should preserve the amount
2187
+ expect(firstMemo).toContain('$10.00');
2188
+ // Should contain truncation indicator
2189
+ expect(firstMemo).toContain('...');
2190
+ // Should start with part of the original name
2191
+ expect(firstMemo.startsWith('BBB')).toBe(true);
2192
+ });
2110
2193
  });
2111
2194
  });
2112
2195
  });