@dizzlkheinz/ynab-mcpb 0.17.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.github/workflows/ci-tests.yml +4 -4
  2. package/.github/workflows/full-integration.yml +2 -2
  3. package/.github/workflows/publish.yml +1 -1
  4. package/.github/workflows/release.yml +2 -2
  5. package/CHANGELOG.md +10 -1
  6. package/CLAUDE.md +9 -6
  7. package/README.md +6 -1
  8. package/dist/bundle/index.cjs +52 -52
  9. package/dist/server/YNABMCPServer.d.ts +7 -2
  10. package/dist/server/YNABMCPServer.js +42 -11
  11. package/dist/server/cacheManager.js +6 -5
  12. package/dist/server/completions.d.ts +25 -0
  13. package/dist/server/completions.js +160 -0
  14. package/dist/server/config.d.ts +2 -2
  15. package/dist/server/errorHandler.js +1 -0
  16. package/dist/server/rateLimiter.js +3 -1
  17. package/dist/server/resources.d.ts +1 -0
  18. package/dist/server/resources.js +33 -16
  19. package/dist/server/securityMiddleware.d.ts +2 -1
  20. package/dist/server/securityMiddleware.js +1 -0
  21. package/dist/server/toolRegistry.d.ts +9 -0
  22. package/dist/server/toolRegistry.js +11 -0
  23. package/dist/tools/adapters.d.ts +3 -1
  24. package/dist/tools/adapters.js +1 -0
  25. package/dist/tools/reconciliation/executor.d.ts +2 -0
  26. package/dist/tools/reconciliation/executor.js +26 -1
  27. package/dist/tools/reconciliation/index.d.ts +3 -2
  28. package/dist/tools/reconciliation/index.js +4 -3
  29. package/docs/reference/API.md +68 -27
  30. package/package.json +2 -2
  31. package/src/__tests__/comprehensive.integration.test.ts +4 -4
  32. package/src/__tests__/performance.test.ts +1 -2
  33. package/src/__tests__/smoke.e2e.test.ts +70 -0
  34. package/src/__tests__/testUtils.ts +2 -113
  35. package/src/server/YNABMCPServer.ts +64 -10
  36. package/src/server/__tests__/completions.integration.test.ts +117 -0
  37. package/src/server/__tests__/completions.test.ts +319 -0
  38. package/src/server/__tests__/resources.template.test.ts +3 -3
  39. package/src/server/__tests__/resources.test.ts +3 -3
  40. package/src/server/__tests__/toolRegistration.test.ts +1 -1
  41. package/src/server/cacheManager.ts +7 -6
  42. package/src/server/completions.ts +279 -0
  43. package/src/server/errorHandler.ts +1 -0
  44. package/src/server/rateLimiter.ts +4 -1
  45. package/src/server/resources.ts +49 -13
  46. package/src/server/securityMiddleware.ts +1 -0
  47. package/src/server/toolRegistry.ts +42 -0
  48. package/src/tools/adapters.ts +22 -1
  49. package/src/tools/reconciliation/__tests__/executor.progress.test.ts +462 -0
  50. package/src/tools/reconciliation/executor.ts +55 -1
  51. package/src/tools/reconciliation/index.ts +7 -3
  52. package/vitest.config.ts +2 -0
  53. package/src/__tests__/delta.performance.test.ts +0 -80
  54. package/src/__tests__/workflows.e2e.test.ts +0 -1658
@@ -1,80 +0,0 @@
1
- import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest';
2
- import * as ynab from 'ynab';
3
- import { performance } from 'node:perf_hooks';
4
- import { CacheManager } from '../server/cacheManager.js';
5
- import { ServerKnowledgeStore } from '../server/serverKnowledgeStore.js';
6
- import { DeltaCache } from '../server/deltaCache.js';
7
- import { DeltaFetcher } from '../tools/deltaFetcher.js';
8
-
9
- const skipPerfFlag = (process.env['SKIP_PERFORMANCE_TESTS'] ?? 'true').toLowerCase().trim();
10
- const shouldSkipPerformance = ['true', '1', 'yes', 'y', 'on'].includes(skipPerfFlag);
11
- const describePerformance = shouldSkipPerformance ? describe.skip : describe;
12
-
13
- describePerformance('Delta performance characteristics', () => {
14
- let ynabAPI: ynab.API;
15
- let testBudgetId: string;
16
- let testAccountId: string;
17
- let deltaFetcher: DeltaFetcher;
18
-
19
- beforeAll(async () => {
20
- const accessToken = process.env['YNAB_ACCESS_TOKEN'];
21
- if (!accessToken) {
22
- throw new Error('YNAB_ACCESS_TOKEN is required to run performance tests.');
23
- }
24
- ynabAPI = new ynab.API(accessToken);
25
- const budgetsResponse = await ynabAPI.budgets.getBudgets();
26
- if (
27
- !budgetsResponse.data ||
28
- !Array.isArray(budgetsResponse.data.budgets) ||
29
- budgetsResponse.data.budgets.length === 0
30
- ) {
31
- throw new Error('No budgets available for performance tests.');
32
- }
33
- const budget = budgetsResponse.data.budgets[0];
34
- testBudgetId = budget.id;
35
-
36
- const accountsResponse = await ynabAPI.accounts.getAccounts(testBudgetId);
37
- const account = accountsResponse.data.accounts.find((acct) => !acct.closed);
38
- if (!account) {
39
- throw new Error('No open accounts available for performance tests.');
40
- }
41
- testAccountId = account.id;
42
- });
43
-
44
- beforeEach(() => {
45
- const cacheManager = new CacheManager();
46
- const knowledgeStore = new ServerKnowledgeStore();
47
- const deltaCache = new DeltaCache(cacheManager, knowledgeStore);
48
- deltaFetcher = new DeltaFetcher(ynabAPI, deltaCache);
49
- process.env['YNAB_MCP_ENABLE_DELTA'] = 'true';
50
- });
51
-
52
- afterEach(() => {
53
- delete process.env['YNAB_MCP_ENABLE_DELTA'];
54
- });
55
-
56
- const measure = async <T>(loader: () => Promise<T>) => {
57
- const start = performance.now();
58
- const result = await loader();
59
- const duration = performance.now() - start;
60
- return { result, duration };
61
- };
62
-
63
- it('reuses cache and avoids repeated full refreshes', async () => {
64
- const sinceDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
65
-
66
- const first = await measure(() =>
67
- deltaFetcher.fetchTransactionsByAccount(testBudgetId, testAccountId, sinceDate, {
68
- forceFullRefresh: true,
69
- }),
70
- );
71
-
72
- const second = await measure(() =>
73
- deltaFetcher.fetchTransactionsByAccount(testBudgetId, testAccountId, sinceDate),
74
- );
75
-
76
- expect(first.result.wasCached).toBe(false);
77
- expect(second.result.wasCached).toBe(true);
78
- expect(second.duration).toBeLessThan(first.duration * 0.8); // Cached should be at least 20% faster
79
- });
80
- });