@vheins/local-memory-mcp 0.4.8 → 0.4.11

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 (164) hide show
  1. package/dist/capabilities.d.ts +7 -7
  2. package/dist/capabilities.d.ts.map +1 -1
  3. package/dist/capabilities.js +7 -7
  4. package/dist/capabilities.js.map +1 -1
  5. package/dist/completion.d.ts +25 -0
  6. package/dist/completion.d.ts.map +1 -0
  7. package/dist/completion.js +127 -0
  8. package/dist/completion.js.map +1 -0
  9. package/dist/mcp/client.d.ts.map +1 -1
  10. package/dist/mcp/client.js +8 -1
  11. package/dist/mcp/client.js.map +1 -1
  12. package/dist/mcp/elicitation.d.ts +24 -0
  13. package/dist/mcp/elicitation.d.ts.map +1 -0
  14. package/dist/mcp/elicitation.js +13 -0
  15. package/dist/mcp/elicitation.js.map +1 -0
  16. package/dist/mcp/sampling.d.ts +69 -0
  17. package/dist/mcp/sampling.d.ts.map +1 -0
  18. package/dist/mcp/sampling.js +13 -0
  19. package/dist/mcp/sampling.js.map +1 -0
  20. package/dist/mcp/session.d.ts +28 -0
  21. package/dist/mcp/session.d.ts.map +1 -0
  22. package/dist/mcp/session.js +106 -0
  23. package/dist/mcp/session.js.map +1 -0
  24. package/dist/prompts/registry.d.ts +55 -0
  25. package/dist/prompts/registry.d.ts.map +1 -1
  26. package/dist/prompts/registry.js +455 -7
  27. package/dist/prompts/registry.js.map +1 -1
  28. package/dist/resources/index.d.ts +55 -4
  29. package/dist/resources/index.d.ts.map +1 -1
  30. package/dist/resources/index.js +222 -52
  31. package/dist/resources/index.js.map +1 -1
  32. package/dist/router.d.ts +11 -1
  33. package/dist/router.d.ts.map +1 -1
  34. package/dist/router.js +151 -34
  35. package/dist/router.js.map +1 -1
  36. package/dist/server.js +212 -13
  37. package/dist/server.js.map +1 -1
  38. package/dist/tests/client.test.d.ts +2 -0
  39. package/dist/tests/client.test.d.ts.map +1 -0
  40. package/dist/tests/client.test.js +130 -0
  41. package/dist/tests/client.test.js.map +1 -0
  42. package/dist/tests/dashboard.test.d.ts +2 -0
  43. package/dist/tests/dashboard.test.d.ts.map +1 -0
  44. package/dist/tests/dashboard.test.js +370 -0
  45. package/dist/tests/dashboard.test.js.map +1 -0
  46. package/dist/tests/e2e.test.d.ts +2 -0
  47. package/dist/tests/e2e.test.d.ts.map +1 -0
  48. package/dist/tests/e2e.test.js +250 -0
  49. package/dist/tests/e2e.test.js.map +1 -0
  50. package/dist/tests/index.test.d.ts +2 -0
  51. package/dist/tests/index.test.d.ts.map +1 -0
  52. package/dist/tests/index.test.js +185 -0
  53. package/dist/tests/index.test.js.map +1 -0
  54. package/dist/tests/logger.test.d.ts +2 -0
  55. package/dist/tests/logger.test.d.ts.map +1 -0
  56. package/dist/tests/logger.test.js +104 -0
  57. package/dist/tests/logger.test.js.map +1 -0
  58. package/dist/tests/memory.bulk.test.d.ts +2 -0
  59. package/dist/tests/memory.bulk.test.d.ts.map +1 -0
  60. package/dist/tests/memory.bulk.test.js +52 -0
  61. package/dist/tests/memory.bulk.test.js.map +1 -0
  62. package/dist/tests/memory.search.test.d.ts +2 -0
  63. package/dist/tests/memory.search.test.d.ts.map +1 -0
  64. package/dist/tests/memory.search.test.js +181 -0
  65. package/dist/tests/memory.search.test.js.map +1 -0
  66. package/dist/tests/normalize.test.d.ts +2 -0
  67. package/dist/tests/normalize.test.d.ts.map +1 -0
  68. package/dist/tests/normalize.test.js +181 -0
  69. package/dist/tests/normalize.test.js.map +1 -0
  70. package/dist/tests/query-expander.test.d.ts +2 -0
  71. package/dist/tests/query-expander.test.d.ts.map +1 -0
  72. package/dist/tests/query-expander.test.js +33 -0
  73. package/dist/tests/query-expander.test.js.map +1 -0
  74. package/dist/tests/router.test.d.ts +2 -0
  75. package/dist/tests/router.test.d.ts.map +1 -0
  76. package/dist/tests/router.test.js +470 -0
  77. package/dist/tests/router.test.js.map +1 -0
  78. package/dist/tests/sqlite.test.d.ts +2 -0
  79. package/dist/tests/sqlite.test.d.ts.map +1 -0
  80. package/dist/tests/sqlite.test.js +367 -0
  81. package/dist/tests/sqlite.test.js.map +1 -0
  82. package/dist/tests/tasks-search.test.d.ts +2 -0
  83. package/dist/tests/tasks-search.test.d.ts.map +1 -0
  84. package/dist/tests/tasks-search.test.js +154 -0
  85. package/dist/tests/tasks-search.test.js.map +1 -0
  86. package/dist/tests/tasks-transition.test.d.ts +2 -0
  87. package/dist/tests/tasks-transition.test.d.ts.map +1 -0
  88. package/dist/tests/tasks-transition.test.js +174 -0
  89. package/dist/tests/tasks-transition.test.js.map +1 -0
  90. package/dist/tests/tasks.bulk.test.d.ts +2 -0
  91. package/dist/tests/tasks.bulk.test.d.ts.map +1 -0
  92. package/dist/tests/tasks.bulk.test.js +254 -0
  93. package/dist/tests/tasks.bulk.test.js.map +1 -0
  94. package/dist/tests/tasks.e2e.test.d.ts +2 -0
  95. package/dist/tests/tasks.e2e.test.d.ts.map +1 -0
  96. package/dist/tests/tasks.e2e.test.js +289 -0
  97. package/dist/tests/tasks.e2e.test.js.map +1 -0
  98. package/dist/tests/tasks.pending-limit-refined.test.d.ts +2 -0
  99. package/dist/tests/tasks.pending-limit-refined.test.d.ts.map +1 -0
  100. package/dist/tests/tasks.pending-limit-refined.test.js +72 -0
  101. package/dist/tests/tasks.pending-limit-refined.test.js.map +1 -0
  102. package/dist/tests/v2-features.test.d.ts +2 -0
  103. package/dist/tests/v2-features.test.d.ts.map +1 -0
  104. package/dist/tests/v2-features.test.js +209 -0
  105. package/dist/tests/v2-features.test.js.map +1 -0
  106. package/dist/tools/memory.bulk-delete.d.ts +1 -7
  107. package/dist/tools/memory.bulk-delete.d.ts.map +1 -1
  108. package/dist/tools/memory.bulk-delete.js +30 -8
  109. package/dist/tools/memory.bulk-delete.js.map +1 -1
  110. package/dist/tools/memory.delete.d.ts.map +1 -1
  111. package/dist/tools/memory.delete.js +18 -1
  112. package/dist/tools/memory.delete.js.map +1 -1
  113. package/dist/tools/memory.recap.d.ts.map +1 -1
  114. package/dist/tools/memory.recap.js +24 -1
  115. package/dist/tools/memory.recap.js.map +1 -1
  116. package/dist/tools/memory.search.d.ts.map +1 -1
  117. package/dist/tools/memory.search.js +16 -1
  118. package/dist/tools/memory.search.js.map +1 -1
  119. package/dist/tools/memory.store.d.ts.map +1 -1
  120. package/dist/tools/memory.store.js +31 -1
  121. package/dist/tools/memory.store.js.map +1 -1
  122. package/dist/tools/memory.summarize.d.ts.map +1 -1
  123. package/dist/tools/memory.summarize.js +19 -1
  124. package/dist/tools/memory.summarize.js.map +1 -1
  125. package/dist/tools/memory.synthesize.d.ts +14 -0
  126. package/dist/tools/memory.synthesize.d.ts.map +1 -0
  127. package/dist/tools/memory.synthesize.js +228 -0
  128. package/dist/tools/memory.synthesize.js.map +1 -0
  129. package/dist/tools/memory.update.d.ts.map +1 -1
  130. package/dist/tools/memory.update.js +19 -1
  131. package/dist/tools/memory.update.js.map +1 -1
  132. package/dist/tools/schemas.d.ts +1750 -263
  133. package/dist/tools/schemas.d.ts.map +1 -1
  134. package/dist/tools/schemas.js +482 -14
  135. package/dist/tools/schemas.js.map +1 -1
  136. package/dist/tools/task.bulk-manage.d.ts +1 -7
  137. package/dist/tools/task.bulk-manage.d.ts.map +1 -1
  138. package/dist/tools/task.bulk-manage.js +60 -15
  139. package/dist/tools/task.bulk-manage.js.map +1 -1
  140. package/dist/tools/task.manage.d.ts +12 -28
  141. package/dist/tools/task.manage.d.ts.map +1 -1
  142. package/dist/tools/task.manage.js +198 -31
  143. package/dist/tools/task.manage.js.map +1 -1
  144. package/dist/utils/completion.d.ts +2 -0
  145. package/dist/utils/completion.d.ts.map +1 -0
  146. package/dist/utils/completion.js +28 -0
  147. package/dist/utils/completion.js.map +1 -0
  148. package/dist/utils/logger.d.ts +18 -0
  149. package/dist/utils/logger.d.ts.map +1 -1
  150. package/dist/utils/logger.js +101 -29
  151. package/dist/utils/logger.js.map +1 -1
  152. package/dist/utils/mcp-response.d.ts +50 -0
  153. package/dist/utils/mcp-response.d.ts.map +1 -1
  154. package/dist/utils/mcp-response.js +54 -7
  155. package/dist/utils/mcp-response.js.map +1 -1
  156. package/dist/utils/normalize.d.ts +5 -0
  157. package/dist/utils/normalize.d.ts.map +1 -1
  158. package/dist/utils/normalize.js +11 -0
  159. package/dist/utils/normalize.js.map +1 -1
  160. package/dist/utils/pagination.d.ts +6 -0
  161. package/dist/utils/pagination.d.ts.map +1 -0
  162. package/dist/utils/pagination.js +32 -0
  163. package/dist/utils/pagination.js.map +1 -0
  164. package/package.json +1 -1
@@ -0,0 +1,250 @@
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
+ import { createRouter } from "../router.js";
3
+ import { SQLiteStore } from "../storage/sqlite.js";
4
+ import { RealVectorStore } from "../storage/vectors.js";
5
+ // Global configuration for heavy AI tests
6
+ vi.setConfig({ testTimeout: 90000 });
7
+ describe("MCP Local Memory - High-Complexity E2E Scenarios", () => {
8
+ let db;
9
+ let vectors;
10
+ let router;
11
+ const REPO = "enterprise-app-v2";
12
+ beforeEach(() => {
13
+ db = new SQLiteStore(":memory:");
14
+ vectors = new RealVectorStore(db);
15
+ router = createRouter(db, vectors);
16
+ });
17
+ /**
18
+ * SCENARIO 1: Semantic Precision & Ranking
19
+ * Test if the system can distinguish between closely related topics.
20
+ */
21
+ it("should maintain high precision ranking among related but distinct technical concepts", async () => {
22
+ const memories = [
23
+ { title: "Primary Database", content: "We use SQLite for local persistence to ensure local-first capability." },
24
+ { title: "Cache Layer", content: "Redis is used for session management and fast lookups." },
25
+ { title: "Database Migration", content: "Run 'npm run migrate' to update the SQLite schema safely." },
26
+ { title: "Backup Policy", content: "Hourly snapshots of the .db file are stored in the backups folder." },
27
+ { title: "External API Integration", content: "The system connects to Postgres only for reporting services." }
28
+ ];
29
+ for (const m of memories) {
30
+ await router("tools/call", {
31
+ name: "memory-store",
32
+ arguments: {
33
+ type: "decision",
34
+ title: m.title,
35
+ content: m.content,
36
+ importance: 4,
37
+ scope: { repo: REPO },
38
+ agent: "test-agent",
39
+ model: "test-model"
40
+ }
41
+ });
42
+ }
43
+ // QUERY: "How do I update the database?"
44
+ // EXPECT: "Database Migration" should be Top Match, not "Primary Database"
45
+ const searchRes = await router("tools/call", {
46
+ name: "memory-search",
47
+ arguments: { query: "How do I update the database schema?", repo: REPO }
48
+ });
49
+ const textOutput = searchRes.content[0].text;
50
+ expect(textOutput).toContain("Database Migration");
51
+ // Validate JSON ordering
52
+ const results = searchRes.data.results;
53
+ expect(results[0].title).toBe("Database Migration");
54
+ expect(results.length).toBeGreaterThan(1); // Should find related db facts too but lower
55
+ });
56
+ /**
57
+ * SCENARIO 2: The Correction & Learning Loop
58
+ * Agent makes a mistake -> Stores it -> Learns -> Replaces it with a pattern.
59
+ */
60
+ it("should guide the agent away from past mistakes using supersedes and status", async () => {
61
+ // 1. Store a mistake
62
+ const mistakeRes = await router("tools/call", {
63
+ name: "memory-store",
64
+ arguments: {
65
+ type: "mistake",
66
+ title: "Large File Upload Failure",
67
+ content: "Don't use fs.readFileSync for large files, it causes OOM errors.",
68
+ importance: 5,
69
+ scope: { repo: REPO },
70
+ agent: "test-agent",
71
+ model: "test-model"
72
+ }
73
+ });
74
+ const mistakeId = mistakeRes.data.id;
75
+ // 2. Store the correct pattern that replaces the mistake
76
+ await router("tools/call", {
77
+ name: "memory-store",
78
+ arguments: {
79
+ type: "pattern",
80
+ title: "Streaming File Upload",
81
+ content: "Always use streams (fs.createReadStream) for files > 10MB.",
82
+ importance: 5,
83
+ scope: { repo: REPO },
84
+ agent: "test-agent",
85
+ model: "test-model",
86
+ supersedes: mistakeId
87
+ }
88
+ });
89
+ // 3. Search for "file upload"
90
+ const searchRes = await router("tools/call", {
91
+ name: "memory-search",
92
+ arguments: { query: "How to handle file uploads?", repo: REPO }
93
+ });
94
+ // EXPECT: Mistake is archived and NOT in search results by default
95
+ expect(searchRes.content[0].text).toContain("Streaming File Upload");
96
+ expect(searchRes.content[0].text).not.toContain("Large File Upload Failure");
97
+ const results = searchRes.data.results;
98
+ expect(results.some((r) => r.id === mistakeId)).toBe(false);
99
+ // 4. Audit: Verify we can still find the mistake if we EXPLICITLY ask for archived
100
+ const auditRes = await router("tools/call", {
101
+ name: "memory-search",
102
+ arguments: { query: "file upload", repo: REPO, include_archived: true }
103
+ });
104
+ expect(auditRes.data.results.some((r) => r.id === mistakeId)).toBe(true);
105
+ });
106
+ /**
107
+ * SCENARIO 3: Workspace-Aware Context Nuance
108
+ * Boost based on folder depth and language extensions.
109
+ */
110
+ it("should provide relevant boost when working in deep subdirectories", async () => {
111
+ // Memory A: Global
112
+ await router("tools/call", {
113
+ name: "memory-store",
114
+ arguments: {
115
+ type: "code_fact",
116
+ title: "Global Logging",
117
+ content: "Use logger.info for all modules.",
118
+ importance: 2,
119
+ scope: { repo: REPO },
120
+ agent: "test-agent",
121
+ model: "test-model"
122
+ }
123
+ });
124
+ // Memory B: Auth Specific
125
+ await router("tools/call", {
126
+ name: "memory-store",
127
+ arguments: {
128
+ type: "code_fact",
129
+ title: "Auth Security Audit",
130
+ content: "Auth module requires PII masking in logs.",
131
+ importance: 5,
132
+ scope: { repo: REPO, folder: "src/auth" },
133
+ agent: "test-agent",
134
+ model: "test-model"
135
+ }
136
+ });
137
+ // Working in a deep auth file
138
+ const searchRes = await router("tools/call", {
139
+ name: "memory-search",
140
+ arguments: {
141
+ query: "How to log data?",
142
+ repo: REPO,
143
+ current_file_path: "src/auth/services/ldap/provider.ts"
144
+ }
145
+ });
146
+ // EXPECT: Auth Specific memory should be the Top Match despite the query being generic "log"
147
+ expect(searchRes.content[0].text).toContain("Auth Security Audit");
148
+ });
149
+ /**
150
+ * SCENARIO 4: Bulk Operations & Pagination Integrity
151
+ */
152
+ it("should handle large volumes of memories and maintain pagination integrity", async () => {
153
+ // Store 15 memories about different microservices
154
+ for (let i = 1; i <= 15; i++) {
155
+ await router("tools/call", {
156
+ name: "memory-store",
157
+ arguments: {
158
+ type: "code_fact",
159
+ title: `Service ${i} Specs`,
160
+ content: `Documentation for microservice number ${i} in our mesh network.`,
161
+ importance: 3,
162
+ scope: { repo: "cloud-infra" },
163
+ agent: "test-agent",
164
+ model: "test-model"
165
+ }
166
+ });
167
+ }
168
+ // Call memory-recap (which uses pagination)
169
+ const recapRes = await router("tools/call", {
170
+ name: "memory-recap",
171
+ arguments: { repo: "cloud-infra", limit: 5, offset: 0 }
172
+ });
173
+ // Based on memory-recap implementation
174
+ expect(recapRes.content[0].text).toContain("cloud-infra");
175
+ // Check Resource Pagination via URI
176
+ const resourceRes = await router("resources/read", {
177
+ uri: "memory://index?repo=cloud-infra"
178
+ });
179
+ const entries = JSON.parse(resourceRes.contents[0].text);
180
+ expect(entries.length).toBeLessThanOrEqual(20); // Default limit in resource.read is 20
181
+ });
182
+ /**
183
+ * SCENARIO 5: Semantic Conflict Denial (Deep Overlap)
184
+ */
185
+ it("should strictly deny near-duplicate decisions to prevent prompt bloat", async () => {
186
+ const originalContent = "We use TailwindCSS for styling all components.";
187
+ await router("tools/call", {
188
+ name: "memory-store",
189
+ arguments: {
190
+ type: "decision",
191
+ title: "Styling Standard",
192
+ content: originalContent,
193
+ importance: 3,
194
+ scope: { repo: REPO },
195
+ agent: "test-agent",
196
+ model: "test-model"
197
+ }
198
+ });
199
+ // Try to store almost the same thing with a different title
200
+ const duplicateRes = await router("tools/call", {
201
+ name: "memory-store",
202
+ arguments: {
203
+ type: "decision",
204
+ title: "CSS Rule",
205
+ content: "Use Tailwind CSS for styling our UI components.", // Subtly different but semantically identical
206
+ importance: 3,
207
+ scope: { repo: REPO },
208
+ agent: "test-agent",
209
+ model: "test-model"
210
+ }
211
+ });
212
+ expect(duplicateRes.content[0].text).toContain("conflict");
213
+ expect(duplicateRes.content[0].text).toContain("Hint:");
214
+ expect(duplicateRes.content[0].text).toContain("memory-delete");
215
+ expect(db.getTotalCount(REPO)).toBe(1); // Should still be 1
216
+ });
217
+ /**
218
+ * SCENARIO 6: Cross-Project Knowledge Sharing (Tech-Stack Affinity)
219
+ * Repository A has Filament knowledge. Repository B (new) should access it via tags.
220
+ */
221
+ it("should share knowledge across projects using tech-stack affinity tags", async () => {
222
+ // 1. Store Filament best practice in Repo A
223
+ await router("tools/call", {
224
+ name: "memory-store",
225
+ arguments: {
226
+ type: "pattern",
227
+ title: "Filament Custom Action",
228
+ content: "Always use ->requiresConfirmation() for destructive actions in Filament.",
229
+ importance: 5,
230
+ scope: { repo: "project-a" },
231
+ agent: "test-agent",
232
+ model: "test-model",
233
+ tags: ["filament", "laravel"]
234
+ }
235
+ });
236
+ // 2. Search in Repo B (which is empty) with "filament" tag
237
+ const searchRes = await router("tools/call", {
238
+ name: "memory-search",
239
+ arguments: {
240
+ query: "how to make safe actions?",
241
+ repo: "project-b",
242
+ current_tags: ["filament"]
243
+ }
244
+ });
245
+ // EXPECT: Should find the "Filament Custom Action" from Project A
246
+ expect(searchRes.content[0].text).toContain("Filament Custom Action");
247
+ expect(searchRes.data.results[0].scope.repo).toBe("project-a");
248
+ });
249
+ });
250
+ //# sourceMappingURL=e2e.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2e.test.js","sourceRoot":"","sources":["../../src/tests/e2e.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/tests/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,185 @@
1
+ // Feature: memory-mcp-optimization, Property 19: memory://index filter repo
2
+ import { describe, it, expect } from "vitest";
3
+ import * as fc from "fast-check";
4
+ import { SQLiteStore } from "../storage/sqlite.js";
5
+ import { readResource, listResourceTemplates, listResources } from "../resources/index.js";
6
+ import { createSessionContext, updateSessionRoots } from "../mcp/session.js";
7
+ function makeEntry(id, repo) {
8
+ return {
9
+ id,
10
+ type: "code_fact",
11
+ title: `Memory ${id}`,
12
+ content: `Content for memory ${id} in repo ${repo}`,
13
+ importance: 3,
14
+ agent: "test-agent",
15
+ role: "unknown",
16
+ model: "test-model",
17
+ scope: { repo },
18
+ created_at: new Date().toISOString(),
19
+ updated_at: new Date().toISOString(),
20
+ completed_at: null,
21
+ hit_count: 0,
22
+ recall_count: 0,
23
+ last_used_at: null,
24
+ expires_at: null,
25
+ supersedes: null,
26
+ status: "active",
27
+ tags: [],
28
+ metadata: {},
29
+ is_global: false,
30
+ };
31
+ }
32
+ describe("readResource memory://index", () => {
33
+ it("returns recent entries when no repo filter", () => {
34
+ const db = new SQLiteStore(":memory:");
35
+ db.insert(makeEntry("id-1", "repo-a"));
36
+ db.insert(makeEntry("id-2", "repo-b"));
37
+ const result = readResource("memory://index", db);
38
+ const entries = JSON.parse(result.contents[0].text);
39
+ expect(entries.length).toBeGreaterThan(0);
40
+ db.close();
41
+ });
42
+ it("returns only entries for the specified repo when ?repo=X is given", () => {
43
+ const db = new SQLiteStore(":memory:");
44
+ db.insert(makeEntry("id-a1", "repo-alpha"));
45
+ db.insert(makeEntry("id-a2", "repo-alpha"));
46
+ db.insert(makeEntry("id-b1", "repo-beta"));
47
+ const result = readResource("memory://index?repo=repo-alpha", db);
48
+ const entries = JSON.parse(result.contents[0].text);
49
+ expect(entries.length).toBeGreaterThan(0);
50
+ for (const entry of entries) {
51
+ expect(entry.scope.repo).toBe("repo-alpha");
52
+ }
53
+ db.close();
54
+ });
55
+ it("returns empty array when repo has no entries", () => {
56
+ const db = new SQLiteStore(":memory:");
57
+ db.insert(makeEntry("id-1", "repo-a"));
58
+ const result = readResource("memory://index?repo=nonexistent", db);
59
+ const entries = JSON.parse(result.contents[0].text);
60
+ expect(entries).toEqual([]);
61
+ db.close();
62
+ });
63
+ /**
64
+ * Property 19: memory://index dengan filter repo mengembalikan subset yang benar
65
+ * Validates: Requirements 19.1, 19.3
66
+ */
67
+ it("Property 19: all returned entries have repo === queried repo", () => {
68
+ fc.assert(fc.property(
69
+ // Generate 2-4 distinct repo names
70
+ fc.uniqueArray(fc.stringMatching(/^[a-z][a-z0-9-]{2,8}$/), { minLength: 2, maxLength: 4 }),
71
+ // Generate 1-5 memories per repo
72
+ fc.integer({ min: 1, max: 5 }), (repos, memoriesPerRepo) => {
73
+ const db = new SQLiteStore(":memory:");
74
+ // Insert memories for each repo
75
+ let counter = 0;
76
+ for (const repo of repos) {
77
+ for (let i = 0; i < memoriesPerRepo; i++) {
78
+ db.insert(makeEntry(`id-${counter++}`, repo));
79
+ }
80
+ }
81
+ // Query with the first repo as filter
82
+ const targetRepo = repos[0];
83
+ const result = readResource(`memory://index?repo=${targetRepo}`, db);
84
+ const entries = JSON.parse(result.contents[0].text);
85
+ // All returned entries must belong to targetRepo
86
+ const allMatch = entries.every((e) => e.scope.repo === targetRepo);
87
+ db.close();
88
+ return allMatch;
89
+ }), { numRuns: 100 });
90
+ });
91
+ it("Property 19 (no filter): returns entries from all repos", () => {
92
+ fc.assert(fc.property(fc.uniqueArray(fc.stringMatching(/^[a-z][a-z0-9-]{2,8}$/), { minLength: 2, maxLength: 3 }), (repos) => {
93
+ const db = new SQLiteStore(":memory:");
94
+ for (const repo of repos) {
95
+ db.insert(makeEntry(`id-${repo}`, repo));
96
+ }
97
+ const result = readResource("memory://index", db);
98
+ const entries = JSON.parse(result.contents[0].text);
99
+ // Without filter, should return entries (listRecent returns id/type/repo)
100
+ expect(entries.length).toBeGreaterThan(0);
101
+ db.close();
102
+ return true;
103
+ }), { numRuns: 100 });
104
+ });
105
+ });
106
+ describe("MCP resource templates and session resources", () => {
107
+ it("supports resource list pagination with nextCursor", () => {
108
+ const session = createSessionContext();
109
+ const firstPage = listResources(session, { limit: 2 });
110
+ const secondPage = listResources(session, { limit: 2, cursor: firstPage.nextCursor });
111
+ expect(firstPage.resources).toHaveLength(2);
112
+ expect(firstPage.nextCursor).toBeTruthy();
113
+ expect(secondPage.resources).toHaveLength(1);
114
+ });
115
+ it("supports resource template pagination with nextCursor", () => {
116
+ const firstPage = listResourceTemplates({ limit: 2 });
117
+ const secondPage = listResourceTemplates({ limit: 2, cursor: firstPage.nextCursor });
118
+ const secondTemplates = secondPage.resourceTemplates;
119
+ expect(firstPage.resourceTemplates).toHaveLength(2);
120
+ expect(firstPage.nextCursor).toBeTruthy();
121
+ expect(secondTemplates.length).toBeGreaterThan(0);
122
+ });
123
+ it("rejects invalid cursors for resources/list with MCP invalid params error", () => {
124
+ const session = createSessionContext();
125
+ expect(() => listResources(session, { cursor: "%%%not-base64%%%" })).toThrowError(/Invalid cursor/);
126
+ try {
127
+ listResources(session, { cursor: "%%%not-base64%%%" });
128
+ }
129
+ catch (error) {
130
+ expect(error.code).toBe(-32602);
131
+ }
132
+ });
133
+ it("rejects invalid cursors for resources/templates/list with MCP invalid params error", () => {
134
+ expect(() => listResourceTemplates({ cursor: "%%%not-base64%%%" })).toThrowError(/Invalid cursor/);
135
+ try {
136
+ listResourceTemplates({ cursor: "%%%not-base64%%%" });
137
+ }
138
+ catch (error) {
139
+ expect(error.code).toBe(-32602);
140
+ }
141
+ });
142
+ it("lists parameterized resources via resources/templates/list", () => {
143
+ const result = listResourceTemplates();
144
+ const templates = result.resourceTemplates.map((entry) => entry.uriTemplate);
145
+ expect(templates).toContain("memory://index?repo={repo}");
146
+ expect(templates).toContain("tasks://current?repo={repo}");
147
+ expect(templates).toContain("memory://search/{base64_query}?repo={repo}");
148
+ });
149
+ it("returns active session roots as a concrete resource", () => {
150
+ const db = new SQLiteStore(":memory:");
151
+ const session = createSessionContext();
152
+ updateSessionRoots(session, [
153
+ { uri: "file:///workspace/project-a", name: "project-a" },
154
+ { uri: "file:///workspace/project-b" },
155
+ ]);
156
+ const result = readResource("session://roots", db, session);
157
+ const payload = JSON.parse(result.contents[0].text);
158
+ expect(payload.roots).toHaveLength(2);
159
+ expect(payload.roots[0].name).toBe("project-a");
160
+ db.close();
161
+ });
162
+ it("adds annotations and size metadata to concrete resource content", () => {
163
+ const db = new SQLiteStore(":memory:");
164
+ const result = readResource("memory://summary/repo-a", db);
165
+ const content = result.contents[0];
166
+ expect(content.annotations.priority).toBeGreaterThan(0.5);
167
+ expect(content.size).toBeGreaterThan(0);
168
+ db.close();
169
+ });
170
+ it("throws MCP resource not found error code for unknown resources", () => {
171
+ const db = new SQLiteStore(":memory:");
172
+ expect(() => readResource("memory://missing/resource", db)).toThrowError(/Unknown resource URI/);
173
+ try {
174
+ readResource("memory://missing/resource", db);
175
+ }
176
+ catch (error) {
177
+ expect(error.code).toBe(-32002);
178
+ expect(error.data.uri).toBe("memory://missing/resource");
179
+ }
180
+ finally {
181
+ db.close();
182
+ }
183
+ });
184
+ });
185
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/tests/index.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logger.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../../src/tests/logger.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ // Feature: memory-mcp-optimization
2
+ // Property 20: StructuredLogger output adalah JSON valid dengan field wajib
3
+ // Validates: Requirements 21.1, 21.2
4
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
5
+ import * as fc from "fast-check";
6
+ describe("Property 20: StructuredLogger output adalah JSON valid dengan field wajib", () => {
7
+ let stderrOutput = [];
8
+ let stderrSpy;
9
+ beforeEach(() => {
10
+ stderrOutput = [];
11
+ stderrSpy = vi.spyOn(process.stderr, "write").mockImplementation((chunk) => {
12
+ stderrOutput.push(typeof chunk === "string" ? chunk : chunk.toString());
13
+ return true;
14
+ });
15
+ // Reset LOG_LEVEL to ensure all levels are logged
16
+ process.env.LOG_LEVEL = "debug";
17
+ });
18
+ afterEach(() => {
19
+ stderrSpy.mockRestore();
20
+ delete process.env.LOG_LEVEL;
21
+ });
22
+ it("each log call produces valid JSON output with required fields", async () => {
23
+ // Re-import logger after setting LOG_LEVEL
24
+ const { logger } = await import("../utils/logger.js?t=" + Date.now());
25
+ fc.assert(fc.property(fc.oneof(fc.constant("debug"), fc.constant("info"), fc.constant("warning"), fc.constant("error")), fc.string({ minLength: 1, maxLength: 100 }), (level, message) => {
26
+ stderrOutput = [];
27
+ logger[level](message);
28
+ expect(stderrOutput.length).toBeGreaterThanOrEqual(1);
29
+ const lastOutput = stderrOutput[stderrOutput.length - 1];
30
+ // Must be text with timestamp, level, and message
31
+ expect(lastOutput).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z \[.*?\] /);
32
+ // Extract parts
33
+ const match = lastOutput.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z) \[\s*(.*?)\s*\] ([\s\S]*)$/);
34
+ expect(match).not.toBeNull();
35
+ if (match) {
36
+ const [, timestamp, parsedLevel, messageWithCtx] = match;
37
+ // level must match
38
+ expect(parsedLevel.toLowerCase()).toBe(level);
39
+ // message must start with the original message
40
+ expect(messageWithCtx.startsWith(message)).toBe(true);
41
+ // timestamp must be ISO 8601
42
+ const ts = new Date(timestamp);
43
+ expect(isNaN(ts.getTime())).toBe(false);
44
+ }
45
+ }), { numRuns: 100 });
46
+ });
47
+ it("log output with context includes context field", async () => {
48
+ const { logger } = await import("../utils/logger.js?t=" + Date.now() + "ctx");
49
+ stderrOutput = [];
50
+ logger.info("test message", { key: "value", count: 42 });
51
+ expect(stderrOutput.length).toBeGreaterThanOrEqual(1);
52
+ const lastOutput = stderrOutput[stderrOutput.length - 1];
53
+ expect(lastOutput).toContain('{"key":"value","count":42}');
54
+ });
55
+ it("log output without context does not include context field", async () => {
56
+ const { logger } = await import("../utils/logger.js?t=" + Date.now() + "noctx");
57
+ stderrOutput = [];
58
+ logger.info("no context message");
59
+ expect(stderrOutput.length).toBeGreaterThanOrEqual(1);
60
+ const lastOutput = stderrOutput[stderrOutput.length - 1];
61
+ expect(lastOutput.trim()).not.toMatch(/\{.*\}/);
62
+ });
63
+ it("all four log levels produce valid JSON with correct level field", async () => {
64
+ const { logger } = await import("../utils/logger.js?t=" + Date.now() + "levels");
65
+ const levels = ["debug", "info", "warning", "error"];
66
+ for (const level of levels) {
67
+ stderrOutput = [];
68
+ if (level === "warning") {
69
+ logger.warning(`test ${level} message`);
70
+ }
71
+ else {
72
+ logger[level](`test ${level} message`);
73
+ }
74
+ expect(stderrOutput.length).toBeGreaterThanOrEqual(1);
75
+ const lastOutput = stderrOutput[stderrOutput.length - 1];
76
+ expect(lastOutput).toMatch(new RegExp(`\\[\\s*${level.toUpperCase()}\\s*\\]`));
77
+ expect(lastOutput).toContain(`test ${level} message`);
78
+ }
79
+ });
80
+ it("warn alias normalizes to warning", async () => {
81
+ const { logger } = await import("../utils/logger.js?t=" + Date.now() + "warnalias");
82
+ stderrOutput = [];
83
+ logger.warn("legacy warning");
84
+ expect(stderrOutput.length).toBeGreaterThanOrEqual(1);
85
+ const lastOutput = stderrOutput[stderrOutput.length - 1];
86
+ expect(lastOutput).toMatch(/\[\s*WARNING\s*\]/);
87
+ });
88
+ it("emits structured payloads to registered log sinks", async () => {
89
+ const module = await import("../utils/logger.js?t=" + Date.now() + "sink");
90
+ const sink = vi.fn();
91
+ module.addLogSink(sink);
92
+ module.logger.notice("[Server] Configuration updated", { source: "test" });
93
+ expect(sink).toHaveBeenCalledWith({
94
+ level: "notice",
95
+ logger: "server",
96
+ data: {
97
+ message: "[Server] Configuration updated",
98
+ source: "test",
99
+ },
100
+ });
101
+ module.clearLogSinks();
102
+ });
103
+ });
104
+ //# sourceMappingURL=logger.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.test.js","sourceRoot":"","sources":["../../src/tests/logger.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=memory.bulk.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.bulk.test.d.ts","sourceRoot":"","sources":["../../src/tests/memory.bulk.test.ts"],"names":[],"mappings":""}