@pcircle/footprint 1.1.1 → 1.2.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 (207) hide show
  1. package/README.md +165 -12
  2. package/SKILL.md +72 -15
  3. package/dist/src/analyzers/content-analyzer.d.ts +20 -0
  4. package/dist/src/analyzers/content-analyzer.d.ts.map +1 -0
  5. package/dist/src/analyzers/content-analyzer.js +169 -0
  6. package/dist/src/analyzers/content-analyzer.js.map +1 -0
  7. package/dist/src/index.d.ts +38 -0
  8. package/dist/src/index.d.ts.map +1 -0
  9. package/dist/src/index.js +243 -0
  10. package/dist/src/index.js.map +1 -0
  11. package/dist/src/lib/crypto/decrypt.d.ts.map +1 -0
  12. package/dist/{lib → src/lib}/crypto/decrypt.js +4 -0
  13. package/dist/src/lib/crypto/decrypt.js.map +1 -0
  14. package/dist/src/lib/crypto/encrypt.d.ts.map +1 -0
  15. package/dist/src/lib/crypto/encrypt.js.map +1 -0
  16. package/dist/{lib → src/lib}/crypto/index.d.ts +1 -1
  17. package/dist/src/lib/crypto/index.d.ts.map +1 -0
  18. package/dist/{lib → src/lib}/crypto/index.js +1 -1
  19. package/dist/src/lib/crypto/index.js.map +1 -0
  20. package/dist/{lib → src/lib}/crypto/key-derivation.d.ts +17 -3
  21. package/dist/src/lib/crypto/key-derivation.d.ts.map +1 -0
  22. package/dist/{lib → src/lib}/crypto/key-derivation.js +44 -3
  23. package/dist/src/lib/crypto/key-derivation.js.map +1 -0
  24. package/dist/src/lib/crypto/types.d.ts.map +1 -0
  25. package/dist/src/lib/crypto/types.js.map +1 -0
  26. package/dist/src/lib/errors/base-error.d.ts +15 -0
  27. package/dist/src/lib/errors/base-error.d.ts.map +1 -0
  28. package/dist/src/lib/errors/base-error.js +34 -0
  29. package/dist/src/lib/errors/base-error.js.map +1 -0
  30. package/dist/src/lib/errors/crypto-error.d.ts +29 -0
  31. package/dist/src/lib/errors/crypto-error.d.ts.map +1 -0
  32. package/dist/src/lib/errors/crypto-error.js +43 -0
  33. package/dist/src/lib/errors/crypto-error.js.map +1 -0
  34. package/dist/src/lib/errors/index.d.ts +26 -0
  35. package/dist/src/lib/errors/index.d.ts.map +1 -0
  36. package/dist/src/lib/errors/index.js +26 -0
  37. package/dist/src/lib/errors/index.js.map +1 -0
  38. package/dist/src/lib/errors/storage-error.d.ts +25 -0
  39. package/dist/src/lib/errors/storage-error.d.ts.map +1 -0
  40. package/dist/src/lib/errors/storage-error.js +38 -0
  41. package/dist/src/lib/errors/storage-error.js.map +1 -0
  42. package/dist/src/lib/errors/validation-error.d.ts +21 -0
  43. package/dist/src/lib/errors/validation-error.d.ts.map +1 -0
  44. package/dist/src/lib/errors/validation-error.js +29 -0
  45. package/dist/src/lib/errors/validation-error.js.map +1 -0
  46. package/dist/{lib → src/lib}/storage/database.d.ts +14 -2
  47. package/dist/src/lib/storage/database.d.ts.map +1 -0
  48. package/dist/{lib → src/lib}/storage/database.js +65 -29
  49. package/dist/src/lib/storage/database.js.map +1 -0
  50. package/dist/src/lib/storage/export.d.ts.map +1 -0
  51. package/dist/{lib → src/lib}/storage/export.js +16 -1
  52. package/dist/src/lib/storage/export.js.map +1 -0
  53. package/dist/{lib → src/lib}/storage/git.d.ts +1 -1
  54. package/dist/src/lib/storage/git.d.ts.map +1 -0
  55. package/dist/{lib → src/lib}/storage/git.js +5 -2
  56. package/dist/src/lib/storage/git.js.map +1 -0
  57. package/dist/{lib → src/lib}/storage/index.d.ts +1 -0
  58. package/dist/src/lib/storage/index.d.ts.map +1 -0
  59. package/dist/{lib → src/lib}/storage/index.js +1 -0
  60. package/dist/src/lib/storage/index.js.map +1 -0
  61. package/dist/src/lib/storage/salt-storage.d.ts +25 -0
  62. package/dist/src/lib/storage/salt-storage.d.ts.map +1 -0
  63. package/dist/src/lib/storage/salt-storage.js +66 -0
  64. package/dist/src/lib/storage/salt-storage.js.map +1 -0
  65. package/dist/src/lib/storage/schema.d.ts.map +1 -0
  66. package/dist/{lib → src/lib}/storage/schema.js +22 -1
  67. package/dist/src/lib/storage/schema.js.map +1 -0
  68. package/dist/src/lib/storage/types.d.ts.map +1 -0
  69. package/dist/src/lib/storage/types.js.map +1 -0
  70. package/dist/src/lib/tool-response.d.ts +84 -0
  71. package/dist/src/lib/tool-response.d.ts.map +1 -0
  72. package/dist/src/lib/tool-response.js +91 -0
  73. package/dist/src/lib/tool-response.js.map +1 -0
  74. package/dist/src/lib/tool-wrapper.d.ts +45 -0
  75. package/dist/src/lib/tool-wrapper.d.ts.map +1 -0
  76. package/dist/src/lib/tool-wrapper.js +73 -0
  77. package/dist/src/lib/tool-wrapper.js.map +1 -0
  78. package/dist/{test-helpers.d.ts → src/test-helpers.d.ts} +4 -4
  79. package/dist/src/test-helpers.d.ts.map +1 -0
  80. package/dist/{test-helpers.js → src/test-helpers.js} +2 -2
  81. package/dist/src/test-helpers.js.map +1 -0
  82. package/dist/src/tools/capture-footprint.d.ts +29 -0
  83. package/dist/src/tools/capture-footprint.d.ts.map +1 -0
  84. package/dist/src/tools/capture-footprint.js +94 -0
  85. package/dist/src/tools/capture-footprint.js.map +1 -0
  86. package/dist/src/tools/delete-footprints.d.ts +22 -0
  87. package/dist/src/tools/delete-footprints.d.ts.map +1 -0
  88. package/dist/src/tools/delete-footprints.js +33 -0
  89. package/dist/src/tools/delete-footprints.js.map +1 -0
  90. package/dist/src/tools/export-footprints.d.ts +33 -0
  91. package/dist/src/tools/export-footprints.d.ts.map +1 -0
  92. package/dist/src/tools/export-footprints.js +50 -0
  93. package/dist/src/tools/export-footprints.js.map +1 -0
  94. package/dist/src/tools/get-footprint.d.ts +51 -0
  95. package/dist/src/tools/get-footprint.d.ts.map +1 -0
  96. package/dist/src/tools/get-footprint.js +66 -0
  97. package/dist/src/tools/get-footprint.js.map +1 -0
  98. package/dist/src/tools/get-tag-stats.d.ts +30 -0
  99. package/dist/src/tools/get-tag-stats.d.ts.map +1 -0
  100. package/dist/src/tools/get-tag-stats.js +33 -0
  101. package/dist/src/tools/get-tag-stats.js.map +1 -0
  102. package/dist/src/tools/index.d.ts +16 -0
  103. package/dist/src/tools/index.d.ts.map +1 -0
  104. package/dist/src/tools/index.js +16 -0
  105. package/dist/src/tools/index.js.map +1 -0
  106. package/dist/src/tools/list-footprints.d.ts +57 -0
  107. package/dist/src/tools/list-footprints.d.ts.map +1 -0
  108. package/dist/src/tools/list-footprints.js +57 -0
  109. package/dist/src/tools/list-footprints.js.map +1 -0
  110. package/dist/src/tools/remove-tag.d.ts +22 -0
  111. package/dist/src/tools/remove-tag.d.ts.map +1 -0
  112. package/dist/src/tools/remove-tag.js +30 -0
  113. package/dist/src/tools/remove-tag.js.map +1 -0
  114. package/dist/src/tools/rename-tag.d.ts +24 -0
  115. package/dist/src/tools/rename-tag.d.ts.map +1 -0
  116. package/dist/src/tools/rename-tag.js +34 -0
  117. package/dist/src/tools/rename-tag.js.map +1 -0
  118. package/dist/src/tools/search-footprints.d.ts +60 -0
  119. package/dist/src/tools/search-footprints.d.ts.map +1 -0
  120. package/dist/src/tools/search-footprints.js +78 -0
  121. package/dist/src/tools/search-footprints.js.map +1 -0
  122. package/dist/src/tools/suggest-capture.d.ts +21 -0
  123. package/dist/src/tools/suggest-capture.d.ts.map +1 -0
  124. package/dist/src/tools/suggest-capture.js +37 -0
  125. package/dist/src/tools/suggest-capture.js.map +1 -0
  126. package/dist/src/tools/verify-footprint.d.ts +104 -0
  127. package/dist/src/tools/verify-footprint.d.ts.map +1 -0
  128. package/dist/src/tools/verify-footprint.js +102 -0
  129. package/dist/src/tools/verify-footprint.js.map +1 -0
  130. package/dist/{types.d.ts → src/types.d.ts} +1 -1
  131. package/dist/src/types.d.ts.map +1 -0
  132. package/dist/{lib/storage → src}/types.js.map +1 -1
  133. package/dist/src/ui/register.d.ts.map +1 -0
  134. package/dist/src/ui/register.js +94 -0
  135. package/dist/src/ui/register.js.map +1 -0
  136. package/dist/tests/error-handling.test.d.ts +2 -0
  137. package/dist/tests/error-handling.test.d.ts.map +1 -0
  138. package/dist/tests/error-handling.test.js +114 -0
  139. package/dist/tests/error-handling.test.js.map +1 -0
  140. package/dist/tests/fixtures.d.ts +87 -0
  141. package/dist/tests/fixtures.d.ts.map +1 -0
  142. package/dist/tests/fixtures.js +130 -0
  143. package/dist/tests/fixtures.js.map +1 -0
  144. package/dist/tests/integration.test.d.ts +2 -0
  145. package/dist/tests/integration.test.d.ts.map +1 -0
  146. package/dist/tests/integration.test.js +115 -0
  147. package/dist/tests/integration.test.js.map +1 -0
  148. package/dist/tests/resources.test.d.ts +2 -0
  149. package/dist/tests/resources.test.d.ts.map +1 -0
  150. package/dist/tests/resources.test.js +73 -0
  151. package/dist/tests/resources.test.js.map +1 -0
  152. package/dist/tests/setup.d.ts +8 -0
  153. package/dist/tests/setup.d.ts.map +1 -0
  154. package/dist/tests/setup.js +8 -0
  155. package/dist/tests/setup.js.map +1 -0
  156. package/dist/tests/tools.test.d.ts +2 -0
  157. package/dist/tests/tools.test.d.ts.map +1 -0
  158. package/dist/tests/tools.test.js +224 -0
  159. package/dist/tests/tools.test.js.map +1 -0
  160. package/dist/ui/dashboard.html +1 -1
  161. package/dist/ui/detail.html +1 -1
  162. package/dist/ui/export.html +1 -1
  163. package/dist/ui-tmp/ui/export.html +1 -1
  164. package/package.json +8 -8
  165. package/dist/index.d.ts +0 -19
  166. package/dist/index.d.ts.map +0 -1
  167. package/dist/index.js +0 -694
  168. package/dist/index.js.map +0 -1
  169. package/dist/lib/crypto/decrypt.d.ts.map +0 -1
  170. package/dist/lib/crypto/decrypt.js.map +0 -1
  171. package/dist/lib/crypto/encrypt.d.ts.map +0 -1
  172. package/dist/lib/crypto/encrypt.js.map +0 -1
  173. package/dist/lib/crypto/index.d.ts.map +0 -1
  174. package/dist/lib/crypto/index.js.map +0 -1
  175. package/dist/lib/crypto/key-derivation.d.ts.map +0 -1
  176. package/dist/lib/crypto/key-derivation.js.map +0 -1
  177. package/dist/lib/crypto/types.d.ts.map +0 -1
  178. package/dist/lib/crypto/types.js.map +0 -1
  179. package/dist/lib/storage/database.d.ts.map +0 -1
  180. package/dist/lib/storage/database.js.map +0 -1
  181. package/dist/lib/storage/export.d.ts.map +0 -1
  182. package/dist/lib/storage/export.js.map +0 -1
  183. package/dist/lib/storage/git.d.ts.map +0 -1
  184. package/dist/lib/storage/git.js.map +0 -1
  185. package/dist/lib/storage/index.d.ts.map +0 -1
  186. package/dist/lib/storage/index.js.map +0 -1
  187. package/dist/lib/storage/schema.d.ts.map +0 -1
  188. package/dist/lib/storage/schema.js.map +0 -1
  189. package/dist/lib/storage/types.d.ts.map +0 -1
  190. package/dist/test-helpers.d.ts.map +0 -1
  191. package/dist/test-helpers.js.map +0 -1
  192. package/dist/types.d.ts.map +0 -1
  193. package/dist/types.js.map +0 -1
  194. package/dist/ui/register.d.ts.map +0 -1
  195. package/dist/ui/register.js +0 -154
  196. package/dist/ui/register.js.map +0 -1
  197. /package/dist/{lib → src/lib}/crypto/decrypt.d.ts +0 -0
  198. /package/dist/{lib → src/lib}/crypto/encrypt.d.ts +0 -0
  199. /package/dist/{lib → src/lib}/crypto/encrypt.js +0 -0
  200. /package/dist/{lib → src/lib}/crypto/types.d.ts +0 -0
  201. /package/dist/{lib → src/lib}/crypto/types.js +0 -0
  202. /package/dist/{lib → src/lib}/storage/export.d.ts +0 -0
  203. /package/dist/{lib → src/lib}/storage/schema.d.ts +0 -0
  204. /package/dist/{lib → src/lib}/storage/types.d.ts +0 -0
  205. /package/dist/{lib → src/lib}/storage/types.js +0 -0
  206. /package/dist/{types.js → src/types.js} +0 -0
  207. /package/dist/{ui → src/ui}/register.d.ts +0 -0
@@ -0,0 +1,114 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { FootprintServer, FootprintTestHelpers } from '../src/index.js';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ describe('Error Handling & Edge Cases', () => {
6
+ let server;
7
+ let helpers;
8
+ const testDbPath = path.join(process.cwd(), `test-edge-cases-${Date.now()}-${Math.random().toString(36).substring(7)}.db`);
9
+ const testPassword = 'edge-case-password';
10
+ beforeEach(() => {
11
+ if (fs.existsSync(testDbPath)) {
12
+ fs.unlinkSync(testDbPath);
13
+ }
14
+ const config = {
15
+ dbPath: testDbPath,
16
+ password: testPassword
17
+ };
18
+ server = new FootprintServer(config);
19
+ helpers = new FootprintTestHelpers(server);
20
+ });
21
+ afterEach(() => {
22
+ if (fs.existsSync(testDbPath)) {
23
+ fs.unlinkSync(testDbPath);
24
+ }
25
+ });
26
+ describe('Input Validation', () => {
27
+ it('should reject empty conversation content', async () => {
28
+ await expect(helpers.callTool('capture-footprint', {
29
+ conversationId: 'conv-1',
30
+ llmProvider: 'Claude',
31
+ content: '',
32
+ messageCount: 0
33
+ })).rejects.toThrow();
34
+ });
35
+ it('should reject negative message count', async () => {
36
+ await expect(helpers.callTool('capture-footprint', {
37
+ conversationId: 'conv-1',
38
+ llmProvider: 'Claude',
39
+ content: 'test',
40
+ messageCount: -1
41
+ })).rejects.toThrow();
42
+ });
43
+ it('should reject invalid pagination parameters', async () => {
44
+ await expect(helpers.callTool('list-footprints', { limit: -1 })).rejects.toThrow();
45
+ await expect(helpers.callTool('list-footprints', { offset: -5 })).rejects.toThrow();
46
+ });
47
+ });
48
+ describe('Large Content Handling', () => {
49
+ it('should handle large conversation content (>1MB)', async () => {
50
+ const largeContent = 'x'.repeat(2 * 1024 * 1024); // 2MB
51
+ const result = await helpers.callTool('capture-footprint', {
52
+ conversationId: 'large-conv',
53
+ llmProvider: 'Claude',
54
+ content: largeContent,
55
+ messageCount: 100
56
+ });
57
+ expect(result.structuredContent.success).toBe(true);
58
+ // Verify retrieval
59
+ const retrieved = await helpers.callTool('get-footprint', {
60
+ id: result.structuredContent.id
61
+ });
62
+ expect(retrieved.structuredContent.content).toBe(largeContent);
63
+ });
64
+ });
65
+ describe('Special Characters', () => {
66
+ it('should handle UTF-8, emoji, and special characters', async () => {
67
+ const specialContent = '你好 🔐 测试 \n\t Special: <>&"\'';
68
+ const result = await helpers.callTool('capture-footprint', {
69
+ conversationId: 'special-conv',
70
+ llmProvider: 'Claude Sonnet 4.5',
71
+ content: specialContent,
72
+ messageCount: 1,
73
+ tags: 'emoji-✨,中文-测试'
74
+ });
75
+ const retrieved = await helpers.callTool('get-footprint', {
76
+ id: result.structuredContent.id
77
+ });
78
+ expect(retrieved.structuredContent.content).toBe(specialContent);
79
+ expect(retrieved.structuredContent.tags).toBe('emoji-✨,中文-测试');
80
+ });
81
+ });
82
+ describe('Database Errors', () => {
83
+ it('should handle database corruption gracefully', async () => {
84
+ // Corrupt database by writing garbage
85
+ fs.writeFileSync(testDbPath, 'CORRUPTED_DATA');
86
+ // Also remove WAL files if they exist (WAL mode creates these)
87
+ const walPath = `${testDbPath}-wal`;
88
+ const shmPath = `${testDbPath}-shm`;
89
+ if (fs.existsSync(walPath))
90
+ fs.unlinkSync(walPath);
91
+ if (fs.existsSync(shmPath))
92
+ fs.unlinkSync(shmPath);
93
+ // Create new server instance (should fail gracefully)
94
+ expect(() => {
95
+ new FootprintServer({
96
+ dbPath: testDbPath,
97
+ password: testPassword
98
+ });
99
+ }).toThrow();
100
+ });
101
+ });
102
+ describe('Empty Database', () => {
103
+ it('should handle empty database correctly', async () => {
104
+ const result = await helpers.callTool('list-footprints', {});
105
+ expect(result.structuredContent.total).toBe(0);
106
+ expect(result.structuredContent.evidences).toEqual([]);
107
+ });
108
+ it('should handle export of empty database', async () => {
109
+ const result = await helpers.callTool('export-footprints', {});
110
+ expect(result.structuredContent.evidenceCount).toBe(0);
111
+ });
112
+ });
113
+ });
114
+ //# sourceMappingURL=error-handling.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handling.test.js","sourceRoot":"","sources":["../../tests/error-handling.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Test fixtures and utilities for Footprint MCP Server tests
3
+ * Provides shared setup, teardown, and test data generation
4
+ */
5
+ import { FootprintServer, FootprintTestHelpers } from "../src/index.js";
6
+ /**
7
+ * Test environment setup result
8
+ */
9
+ export interface TestEnvironment {
10
+ server: FootprintServer;
11
+ helpers: FootprintTestHelpers;
12
+ testDbPath: string;
13
+ tempDir: string;
14
+ testPassword: string;
15
+ cleanup: () => void;
16
+ }
17
+ /**
18
+ * Create a test environment with temporary database
19
+ *
20
+ * @param password - Optional custom password (default: 'test-password-123')
21
+ * @returns Test environment with server, helpers, and cleanup function
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const env = createTestEnvironment();
26
+ * // ... use env.server, env.helpers
27
+ * env.cleanup(); // Clean up when done
28
+ * ```
29
+ */
30
+ export declare function createTestEnvironment(password?: string): TestEnvironment;
31
+ /**
32
+ * Sample conversation content for testing
33
+ */
34
+ export declare const SAMPLE_CONVERSATION: {
35
+ basic: string;
36
+ withIP: string;
37
+ withLegal: string;
38
+ withBusiness: string;
39
+ withResearch: string;
40
+ withCompliance: string;
41
+ casual: string;
42
+ multiKeyword: string;
43
+ large: string;
44
+ withSpecialChars: string;
45
+ };
46
+ /**
47
+ * Sample evidence parameters for testing capture-footprint
48
+ */
49
+ export declare function createSampleEvidence(overrides?: {
50
+ conversationId?: string;
51
+ llmProvider?: string;
52
+ content?: string;
53
+ messageCount?: number;
54
+ tags?: string;
55
+ }): {
56
+ conversationId: string;
57
+ llmProvider: string;
58
+ content: string;
59
+ messageCount: number;
60
+ tags: string;
61
+ };
62
+ /**
63
+ * Create multiple sample evidences for batch testing
64
+ *
65
+ * @param count - Number of evidences to create
66
+ * @returns Array of evidence parameters
67
+ */
68
+ export declare function createMultipleSampleEvidences(count: number): {
69
+ conversationId: string;
70
+ llmProvider: string;
71
+ content: string;
72
+ messageCount: number;
73
+ tags: string;
74
+ }[];
75
+ /**
76
+ * Wait for a condition to be true (useful for async operations)
77
+ *
78
+ * @param condition - Function that returns true when condition is met
79
+ * @param timeout - Maximum time to wait in milliseconds
80
+ * @param interval - Check interval in milliseconds
81
+ */
82
+ export declare function waitFor(condition: () => boolean | Promise<boolean>, timeout?: number, interval?: number): Promise<void>;
83
+ /**
84
+ * Generate a random test database name
85
+ */
86
+ export declare function generateTestDbName(prefix?: string): string;
87
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../tests/fixtures.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAMxE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,GAAE,MAA4B,GACrC,eAAe,CA4CjB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;CAgB/B,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;;;;;EAQA;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM;;;;;;IAQ1D;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAC3C,OAAO,GAAE,MAAa,EACtB,QAAQ,GAAE,MAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,MAAe,GAAG,MAAM,CAIlE"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Test fixtures and utilities for Footprint MCP Server tests
3
+ * Provides shared setup, teardown, and test data generation
4
+ */
5
+ import { FootprintServer, FootprintTestHelpers } from "../src/index.js";
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ import { tmpdir } from "node:os";
9
+ /**
10
+ * Create a test environment with temporary database
11
+ *
12
+ * @param password - Optional custom password (default: 'test-password-123')
13
+ * @returns Test environment with server, helpers, and cleanup function
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const env = createTestEnvironment();
18
+ * // ... use env.server, env.helpers
19
+ * env.cleanup(); // Clean up when done
20
+ * ```
21
+ */
22
+ export function createTestEnvironment(password = "test-password-123") {
23
+ // Create unique temporary directory for each test
24
+ const tempDir = fs.mkdtempSync(path.join(tmpdir(), "evidence-mcp-test-"));
25
+ const testDbPath = path.join(tempDir, "test-evidence.db");
26
+ // Clean up any existing test database
27
+ if (fs.existsSync(testDbPath)) {
28
+ fs.unlinkSync(testDbPath);
29
+ }
30
+ const config = {
31
+ dbPath: testDbPath,
32
+ password,
33
+ };
34
+ const server = new FootprintServer(config);
35
+ const helpers = new FootprintTestHelpers(server);
36
+ const cleanup = () => {
37
+ try {
38
+ if (server) {
39
+ // Close any database connections if the server has them
40
+ }
41
+ }
42
+ catch (error) {
43
+ // Ignore close errors
44
+ }
45
+ try {
46
+ if (tempDir && fs.existsSync(tempDir)) {
47
+ fs.rmSync(tempDir, { recursive: true, force: true });
48
+ }
49
+ }
50
+ catch (error) {
51
+ // Ignore cleanup errors
52
+ }
53
+ };
54
+ return {
55
+ server,
56
+ helpers,
57
+ testDbPath,
58
+ tempDir,
59
+ testPassword: password,
60
+ cleanup,
61
+ };
62
+ }
63
+ /**
64
+ * Sample conversation content for testing
65
+ */
66
+ export const SAMPLE_CONVERSATION = {
67
+ basic: "This is a test conversation about a project milestone.",
68
+ withIP: "We discussed the new algorithm for patent filing and proprietary technology.",
69
+ withLegal: "The contract terms and license agreement were reviewed by our legal team.",
70
+ withBusiness: "Strategic decision on the roadmap and approval of the budget.",
71
+ withResearch: "Our research findings and experiment data show promising results.",
72
+ withCompliance: "Audit requirements and documentation for compliance with regulations.",
73
+ casual: "Hey, how are you doing? The weather is nice today.",
74
+ multiKeyword: "Contract agreement for proprietary algorithm research with compliance requirements.",
75
+ large: "A".repeat(1024 * 1024 + 100), // >1MB content
76
+ withSpecialChars: "Test with UTF-8: 你好 🎉 and emoji 🚀",
77
+ };
78
+ /**
79
+ * Sample evidence parameters for testing capture-footprint
80
+ */
81
+ export function createSampleEvidence(overrides) {
82
+ return {
83
+ conversationId: overrides?.conversationId || "test-conversation-001",
84
+ llmProvider: overrides?.llmProvider || "Claude Sonnet 4.5",
85
+ content: overrides?.content || SAMPLE_CONVERSATION.basic,
86
+ messageCount: overrides?.messageCount || 10,
87
+ tags: overrides?.tags || "test,milestone",
88
+ };
89
+ }
90
+ /**
91
+ * Create multiple sample evidences for batch testing
92
+ *
93
+ * @param count - Number of evidences to create
94
+ * @returns Array of evidence parameters
95
+ */
96
+ export function createMultipleSampleEvidences(count) {
97
+ return Array.from({ length: count }, (_, i) => ({
98
+ conversationId: `test-conversation-${String(i + 1).padStart(3, "0")}`,
99
+ llmProvider: i % 2 === 0 ? "Claude Sonnet 4.5" : "GPT-4",
100
+ content: `Test conversation content ${i + 1}`,
101
+ messageCount: (i + 1) * 5,
102
+ tags: i % 2 === 0 ? "test,even" : "test,odd",
103
+ }));
104
+ }
105
+ /**
106
+ * Wait for a condition to be true (useful for async operations)
107
+ *
108
+ * @param condition - Function that returns true when condition is met
109
+ * @param timeout - Maximum time to wait in milliseconds
110
+ * @param interval - Check interval in milliseconds
111
+ */
112
+ export async function waitFor(condition, timeout = 5000, interval = 100) {
113
+ const startTime = Date.now();
114
+ while (Date.now() - startTime < timeout) {
115
+ if (await condition()) {
116
+ return;
117
+ }
118
+ await new Promise((resolve) => setTimeout(resolve, interval));
119
+ }
120
+ throw new Error(`Timeout waiting for condition after ${timeout}ms`);
121
+ }
122
+ /**
123
+ * Generate a random test database name
124
+ */
125
+ export function generateTestDbName(prefix = "test") {
126
+ const timestamp = Date.now();
127
+ const random = Math.random().toString(36).substring(7);
128
+ return `${prefix}-${timestamp}-${random}.db`;
129
+ }
130
+ //# sourceMappingURL=fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../tests/fixtures.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../tests/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,115 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { FootprintServer, FootprintTestHelpers } from "../src/index.js";
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ describe("TraceGuard MCP Server Integration", () => {
6
+ let server;
7
+ let helpers;
8
+ let testDbPath;
9
+ const testPassword = "integration-test-password";
10
+ beforeEach(() => {
11
+ // Use unique database path for each test to avoid conflicts
12
+ testDbPath = path.join(process.cwd(), `test-evidence-${Date.now()}-${Math.random().toString(36).substring(7)}.db`);
13
+ if (fs.existsSync(testDbPath)) {
14
+ fs.unlinkSync(testDbPath);
15
+ }
16
+ const config = {
17
+ dbPath: testDbPath,
18
+ password: testPassword,
19
+ };
20
+ server = new FootprintServer(config);
21
+ helpers = new FootprintTestHelpers(server);
22
+ });
23
+ afterEach(() => {
24
+ if (fs.existsSync(testDbPath)) {
25
+ fs.unlinkSync(testDbPath);
26
+ }
27
+ // Clean up exported files
28
+ const exports = fs
29
+ .readdirSync(".")
30
+ .filter((f) => f.startsWith("evidence-export-"));
31
+ exports.forEach((f) => fs.unlinkSync(f));
32
+ });
33
+ it("should complete full evidence lifecycle: capture → list → get → export", async () => {
34
+ // 1. Capture evidence
35
+ const captureResult = await helpers.callTool("capture-footprint", {
36
+ conversationId: "test-conv-001",
37
+ llmProvider: "Claude Sonnet 4.5",
38
+ content: "User: Hello\nAssistant: Hi! How can I help?",
39
+ messageCount: 2,
40
+ tags: "test,integration",
41
+ });
42
+ expect(captureResult.structuredContent).toMatchObject({
43
+ success: true,
44
+ id: expect.any(String),
45
+ });
46
+ const evidenceId = captureResult.structuredContent.id;
47
+ // 2. List evidences
48
+ const listResult = await helpers.callTool("list-footprints", {});
49
+ expect(listResult.structuredContent.total).toBe(1);
50
+ expect(listResult.structuredContent.evidences[0]).toMatchObject({
51
+ id: evidenceId,
52
+ conversationId: "test-conv-001",
53
+ llmProvider: "Claude Sonnet 4.5",
54
+ messageCount: 2,
55
+ });
56
+ // 3. Get evidence (decrypt)
57
+ const getResult = await helpers.callTool("get-footprint", {
58
+ id: evidenceId,
59
+ });
60
+ expect(getResult.structuredContent).toMatchObject({
61
+ id: evidenceId,
62
+ content: "User: Hello\nAssistant: Hi! How can I help?",
63
+ messageCount: 2,
64
+ });
65
+ // 4. Export evidences
66
+ const exportResult = await helpers.callTool("export-footprints", {
67
+ evidenceIds: [evidenceId],
68
+ includeGitInfo: true,
69
+ });
70
+ expect(exportResult.structuredContent).toMatchObject({
71
+ success: true,
72
+ evidenceCount: 1,
73
+ filename: expect.stringMatching(/^evidence-export-/),
74
+ checksum: expect.stringMatching(/^[0-9a-f]{64}$/),
75
+ });
76
+ // Verify ZIP file created
77
+ expect(fs.existsSync(exportResult.structuredContent.filename)).toBe(true);
78
+ });
79
+ it("should handle multiple evidences correctly", async () => {
80
+ // Capture 3 evidences
81
+ const ids = [];
82
+ for (let i = 1; i <= 3; i++) {
83
+ const result = await helpers.callTool("capture-footprint", {
84
+ conversationId: `conv-${i}`,
85
+ llmProvider: "Claude Sonnet 4.5",
86
+ content: `Conversation ${i} content`,
87
+ messageCount: i,
88
+ });
89
+ ids.push(result.structuredContent.id);
90
+ }
91
+ // List with pagination
92
+ const page1 = await helpers.callTool("list-footprints", {
93
+ limit: 2,
94
+ offset: 0,
95
+ });
96
+ expect(page1.structuredContent.total).toBe(2);
97
+ const page2 = await helpers.callTool("list-footprints", {
98
+ limit: 2,
99
+ offset: 2,
100
+ });
101
+ expect(page2.structuredContent.total).toBe(1);
102
+ // Export subset
103
+ const exportResult = await helpers.callTool("export-footprints", {
104
+ evidenceIds: [ids[0], ids[2]],
105
+ });
106
+ expect(exportResult.structuredContent.evidenceCount).toBe(2);
107
+ });
108
+ it("should handle errors gracefully", async () => {
109
+ // Try to get non-existent evidence
110
+ await expect(helpers.callTool("get-footprint", { id: "nonexistent-id" })).rejects.toThrow("Evidence not found");
111
+ // Try to export non-existent evidence
112
+ await expect(helpers.callTool("export-footprints", { evidenceIds: ["bad-id"] })).rejects.toThrow("Evidence IDs not found");
113
+ });
114
+ });
115
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../tests/integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAExE,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,IAAI,MAAuB,CAAC;IAC5B,IAAI,OAA6B,CAAC;IAClC,IAAI,UAAkB,CAAC;IACvB,MAAM,YAAY,GAAG,2BAA2B,CAAC;IAEjD,UAAU,CAAC,GAAG,EAAE;QACd,4DAA4D;QAC5D,UAAU,GAAG,IAAI,CAAC,IAAI,CACpB,OAAO,CAAC,GAAG,EAAE,EACb,iBAAiB,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAC5E,CAAC;QAEF,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,MAAM,GAAiB;YAC3B,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,YAAY;SACvB,CAAC;QAEF,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,GAAG,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QAED,0BAA0B;QAC1B,MAAM,OAAO,GAAG,EAAE;aACf,WAAW,CAAC,GAAG,CAAC;aAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,sBAAsB;QACtB,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE;YAChE,cAAc,EAAE,eAAe;YAC/B,WAAW,EAAE,mBAAmB;YAChC,OAAO,EAAE,6CAA6C;YACtD,YAAY,EAAE,CAAC;YACf,IAAI,EAAE,kBAAkB;SACzB,CAAC,CAAC;QAEH,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,aAAa,CAAC;YACpD,OAAO,EAAE,IAAI;YACb,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;SACvB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,aAAa,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAEtD,oBAAoB;QACpB,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAEjE,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAE,UAAU,CAAC,iBAAyB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;YACvE,EAAE,EAAE,UAAU;YACd,cAAc,EAAE,eAAe;YAC/B,WAAW,EAAE,mBAAmB;YAChC,YAAY,EAAE,CAAC;SAChB,CAAC,CAAC;QAEH,4BAA4B;QAC5B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE;YACxD,EAAE,EAAE,UAAU;SACf,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,aAAa,CAAC;YAChD,EAAE,EAAE,UAAU;YACd,OAAO,EAAE,6CAA6C;YACtD,YAAY,EAAE,CAAC;SAChB,CAAC,CAAC;QAEH,sBAAsB;QACtB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE;YAC/D,WAAW,EAAE,CAAC,UAAU,CAAC;YACzB,cAAc,EAAE,IAAI;SACrB,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,aAAa,CAAC;YACnD,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC,mBAAmB,CAAC;YACpD,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC,gBAAgB,CAAC;SAClD,CAAC,CAAC;QAEH,0BAA0B;QAC1B,MAAM,CACJ,EAAE,CAAC,UAAU,CAAE,YAAY,CAAC,iBAAyB,CAAC,QAAQ,CAAC,CAChE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,sBAAsB;QACtB,MAAM,GAAG,GAAG,EAAE,CAAC;QAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE;gBACzD,cAAc,EAAE,QAAQ,CAAC,EAAE;gBAC3B,WAAW,EAAE,mBAAmB;gBAChC,OAAO,EAAE,gBAAgB,CAAC,UAAU;gBACpC,YAAY,EAAE,CAAC;aAChB,CAAC,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACxC,CAAC;QAED,uBAAuB;QACvB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,iBAAiB,EAAE;YACtD,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;SACV,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,iBAAiB,EAAE;YACtD,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,CAAC;SACV,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE9C,gBAAgB;QAChB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE;YAC/D,WAAW,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;SAC9B,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,mCAAmC;QACnC,MAAM,MAAM,CACV,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAC5D,CAAC,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAExC,sCAAsC;QACtC,MAAM,MAAM,CACV,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CACnE,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resources.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.test.d.ts","sourceRoot":"","sources":["../../tests/resources.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,73 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { FootprintServer, FootprintTestHelpers } from '../src/index.js';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ describe('MCP Resources', () => {
6
+ let server;
7
+ let helpers;
8
+ const testDbPath = path.join(process.cwd(), 'test-resources.db');
9
+ const testPassword = 'test-password-123';
10
+ beforeEach(() => {
11
+ // Clean up any existing test database
12
+ if (fs.existsSync(testDbPath)) {
13
+ fs.unlinkSync(testDbPath);
14
+ }
15
+ const config = {
16
+ dbPath: testDbPath,
17
+ password: testPassword
18
+ };
19
+ server = new FootprintServer(config);
20
+ helpers = new FootprintTestHelpers(server);
21
+ });
22
+ afterEach(() => {
23
+ // Clean up test database
24
+ if (fs.existsSync(testDbPath)) {
25
+ fs.unlinkSync(testDbPath);
26
+ }
27
+ });
28
+ describe('Resource Registration', () => {
29
+ it('should register evidence resource with template', async () => {
30
+ const resources = await helpers.getResources();
31
+ expect(resources).toBeDefined();
32
+ expect(Array.isArray(resources)).toBe(true);
33
+ const evidenceResource = resources.find(r => r.name === 'evidence');
34
+ expect(evidenceResource).toBeDefined();
35
+ expect(evidenceResource?.uriTemplate).toBe('evidence://{id}');
36
+ expect(evidenceResource?.description).toContain('encrypted footprint record');
37
+ expect(evidenceResource?.mimeType).toBe('text/plain');
38
+ });
39
+ it('should read evidence resource with valid ID', async () => {
40
+ // First create evidence using capture-footprint tool
41
+ const result = await helpers.executeTool('capture-footprint', {
42
+ conversationId: 'test-resource-evidence',
43
+ llmProvider: 'Claude Sonnet 4.5',
44
+ content: JSON.stringify({
45
+ method: 'GET',
46
+ url: 'https://api.example.com/data',
47
+ headers: { 'Authorization': 'Bearer token' }
48
+ }),
49
+ messageCount: 1,
50
+ tags: 'resource-test'
51
+ });
52
+ expect(result.success).toBe(true);
53
+ expect(result.id).toBeDefined();
54
+ // Read through resource using the returned ID
55
+ const evidenceId = result.id;
56
+ const resourceContent = await helpers.readResource(`evidence://${evidenceId}`);
57
+ expect(resourceContent).toBeDefined();
58
+ expect(resourceContent.contents).toBeDefined();
59
+ expect(resourceContent.contents[0].uri).toBe(`evidence://${evidenceId}`);
60
+ expect(resourceContent.contents[0].mimeType).toBe('text/plain');
61
+ expect(resourceContent.contents[0].text).toContain('method');
62
+ expect(resourceContent.contents[0].text).toContain('GET');
63
+ expect(resourceContent.contents[0].text).toContain('https://api.example.com/data');
64
+ });
65
+ it('should return error for non-existent evidence ID', async () => {
66
+ await expect(helpers.readResource('evidence://non-existent-id')).rejects.toThrow('Evidence with ID non-existent-id not found');
67
+ });
68
+ it('should return error for invalid URI format', async () => {
69
+ await expect(helpers.readResource('invalid://format')).rejects.toThrow('Unknown resource');
70
+ });
71
+ });
72
+ });
73
+ //# sourceMappingURL=resources.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.test.js","sourceRoot":"","sources":["../../tests/resources.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Test setup for MCP server tests
3
+ *
4
+ * This file will be populated with test utilities and setup code
5
+ * in subsequent tasks (7.2 and 7.3).
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../tests/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Test setup for MCP server tests
3
+ *
4
+ * This file will be populated with test utilities and setup code
5
+ * in subsequent tasks (7.2 and 7.3).
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../tests/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.test.d.ts","sourceRoot":"","sources":["../../tests/tools.test.ts"],"names":[],"mappings":""}