@folterung/project-memory 0.1.14 → 0.1.16
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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/packages/cli/coverage/lcov-report/chunking/chunker.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/chunking/hash.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/chunking/index.html +1 -1
- package/packages/cli/coverage/lcov-report/chunking/types.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/config/index.html +5 -5
- package/packages/cli/coverage/lcov-report/config/load.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/config/types.ts.html +7 -4
- package/packages/cli/coverage/lcov-report/embedding/index.html +15 -15
- package/packages/cli/coverage/lcov-report/embedding/stub.ts.html +56 -8
- package/packages/cli/coverage/lcov-report/index.html +17 -17
- package/packages/cli/coverage/lcov-report/qdrant/index.html +1 -1
- package/packages/cli/coverage/lcov-report/qdrant/upsert.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/scope/allowlist.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/scope/ignore.ts.html +1 -1
- package/packages/cli/coverage/lcov-report/scope/index.html +1 -1
- package/packages/cli/coverage/lcov.info +24 -5
- package/packages/cli/coverage/tmp/{coverage-31303-1770081858145-0.json → coverage-88905-1770086028547-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31304-1770081858192-0.json → coverage-88906-1770086028593-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31305-1770081858190-0.json → coverage-88907-1770086028592-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31306-1770081858189-0.json → coverage-88908-1770086028592-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31307-1770081858198-0.json → coverage-88909-1770086028598-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31308-1770081858189-0.json → coverage-88910-1770086028593-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31309-1770081858191-0.json → coverage-88911-1770086028594-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31310-1770081858245-0.json → coverage-88912-1770086028648-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31311-1770081858213-0.json → coverage-88913-1770086028615-0.json} +1 -1
- package/packages/cli/coverage/tmp/{coverage-31312-1770081858208-0.json → coverage-88914-1770086028612-0.json} +1 -1
- package/packages/cli/dist/commands/down.js +27 -0
- package/packages/cli/dist/commands/down.js.map +1 -1
- package/packages/cli/dist/commands/scaffold.js +8 -1
- package/packages/cli/dist/commands/scaffold.js.map +1 -1
- package/packages/cli/dist/config/types.d.ts +1 -0
- package/packages/cli/dist/config/types.js +1 -0
- package/packages/cli/dist/config/types.js.map +1 -1
- package/packages/cli/dist/embedding/stub.d.ts +5 -0
- package/packages/cli/dist/embedding/stub.js +11 -0
- package/packages/cli/dist/embedding/stub.js.map +1 -1
- package/packages/cli/dist/phase1/pipeline.js +2 -2
- package/packages/cli/dist/phase1/pipeline.js.map +1 -1
- package/packages/cli/dist/phase2/deep-index.js +2 -2
- package/packages/cli/dist/phase2/deep-index.js.map +1 -1
- package/packages/cli/src/commands/down.ts +23 -0
- package/packages/cli/src/commands/scaffold.ts +8 -1
- package/packages/cli/src/config/types.ts +1 -0
- package/packages/cli/src/embedding/stub.ts +16 -0
- package/packages/cli/src/phase1/pipeline.ts +4 -2
- package/packages/cli/src/phase2/deep-index.ts +2 -2
- package/packages/mcp-server/dist/index.js +84 -0
- package/packages/mcp-server/dist/index.js.map +1 -1
- package/packages/mcp-server/src/index.ts +114 -0
- package/packages/server/coverage/lcov-report/index.html +1 -1
- package/packages/server/coverage/lcov-report/stub.ts.html +1 -1
- package/packages/server/coverage/tmp/{coverage-31403-1770081859010-0.json → coverage-88999-1770086029452-0.json} +1 -1
- package/packages/server/coverage/tmp/{coverage-31404-1770081859045-0.json → coverage-89000-1770086029487-0.json} +1 -1
- package/packages/server/dist/api/search.js +1 -1
- package/packages/server/dist/api/search.js.map +1 -1
- package/packages/server/dist/api/store.d.ts +11 -0
- package/packages/server/dist/api/store.js +60 -0
- package/packages/server/dist/api/store.js.map +1 -0
- package/packages/server/dist/index.js +2 -0
- package/packages/server/dist/index.js.map +1 -1
- package/packages/server/src/api/search.ts +1 -1
- package/packages/server/src/api/store.ts +81 -0
- package/packages/server/src/index.ts +2 -0
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* Log only to stderr so stdout is not corrupted (MCP uses stdin/stdout for JSON-RPC).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { spawnSync } from "node:child_process";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
8
10
|
import { appendFileSync, writeFileSync } from "fs";
|
|
9
11
|
import { tmpdir } from "os";
|
|
10
12
|
import { basename, join } from "path";
|
|
@@ -148,6 +150,56 @@ async function callExplain(
|
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
|
|
153
|
+
interface StoreBody {
|
|
154
|
+
content: string;
|
|
155
|
+
title?: string;
|
|
156
|
+
path?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function callStore(
|
|
160
|
+
baseUrl: string,
|
|
161
|
+
body: StoreBody
|
|
162
|
+
): Promise<{ id: string; message: string } | { error: string }> {
|
|
163
|
+
try {
|
|
164
|
+
const res = await fetch(`${baseUrl}/store`, {
|
|
165
|
+
method: "POST",
|
|
166
|
+
headers: { "Content-Type": "application/json" },
|
|
167
|
+
body: JSON.stringify(body),
|
|
168
|
+
});
|
|
169
|
+
const data = (await res.json()) as { id?: string; message?: string; error?: string };
|
|
170
|
+
if (!res.ok) {
|
|
171
|
+
return { error: (data as { message?: string }).message ?? `Store failed: ${res.status}` };
|
|
172
|
+
}
|
|
173
|
+
return { id: data.id ?? "", message: data.message ?? "Stored." };
|
|
174
|
+
} catch (err) {
|
|
175
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
176
|
+
return { error: message };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const REFRESH_TIMEOUT_MS = 300_000;
|
|
181
|
+
|
|
182
|
+
function getProjectCwd(): string {
|
|
183
|
+
return process.env.MEM_CWD ?? process.cwd();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function runMemUpdate(cwd: string): { ok: boolean; stdout: string; stderr: string; error?: string } {
|
|
187
|
+
const cliPath = join(cwd, "node_modules", "@folterung", "project-memory", "packages", "cli", "bin", "mem.js");
|
|
188
|
+
const useNode = existsSync(cliPath);
|
|
189
|
+
const result = spawnSync(
|
|
190
|
+
useNode ? process.execPath : "mem",
|
|
191
|
+
useNode ? [cliPath, "update"] : ["update"],
|
|
192
|
+
{ cwd, encoding: "utf8", timeout: REFRESH_TIMEOUT_MS }
|
|
193
|
+
);
|
|
194
|
+
const errorMsg = result.error?.message;
|
|
195
|
+
return {
|
|
196
|
+
ok: result.status === 0,
|
|
197
|
+
stdout: result.stdout ?? "",
|
|
198
|
+
stderr: result.stderr ?? "",
|
|
199
|
+
error: errorMsg,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
151
203
|
async function main(): Promise<void> {
|
|
152
204
|
ensureLogFileExists();
|
|
153
205
|
const baseUrl = getBaseUrl();
|
|
@@ -225,6 +277,68 @@ async function main(): Promise<void> {
|
|
|
225
277
|
}
|
|
226
278
|
);
|
|
227
279
|
|
|
280
|
+
server.registerTool(
|
|
281
|
+
"refresh_project_memory_index",
|
|
282
|
+
{
|
|
283
|
+
description:
|
|
284
|
+
"Re-run the project memory index (Phase 1: file tree, module summaries, entrypoints). Use when the codebase has changed and you want the index updated so search and context stay accurate. Runs 'mem update' in the project.",
|
|
285
|
+
inputSchema: z.object({}),
|
|
286
|
+
},
|
|
287
|
+
async () => {
|
|
288
|
+
logAsked("refresh_project_memory_index", {});
|
|
289
|
+
const cwd = getProjectCwd();
|
|
290
|
+
const { ok, stdout, stderr, error } = runMemUpdate(cwd);
|
|
291
|
+
const summary = ok
|
|
292
|
+
? "Project memory index updated successfully."
|
|
293
|
+
: "Project memory index update failed.";
|
|
294
|
+
const detail = [error, stdout, stderr].filter(Boolean).join("\n") || "(no output)";
|
|
295
|
+
const responseText = `${summary}\n\n${detail}`.slice(0, 4000);
|
|
296
|
+
logReturned("refresh_project_memory_index", responseText);
|
|
297
|
+
return { content: [{ type: "text" as const, text: responseText }] };
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
server.registerTool(
|
|
302
|
+
"store_project_memory",
|
|
303
|
+
{
|
|
304
|
+
description:
|
|
305
|
+
"Store a summary, note, or finding in project memory so it can be found by future search. Use after research when you have learned something useful that would help answer future questions. Each call adds a new point (idempotent by content, not by call).",
|
|
306
|
+
inputSchema: z.object({
|
|
307
|
+
content: z
|
|
308
|
+
.string()
|
|
309
|
+
.describe(
|
|
310
|
+
"The main text to store: summary, finding, or explanation that provides significant context for future questions."
|
|
311
|
+
),
|
|
312
|
+
title: z
|
|
313
|
+
.string()
|
|
314
|
+
.optional()
|
|
315
|
+
.describe("Short label for this note (e.g. 'Sync scripts overview', 'Auth flow summary')."),
|
|
316
|
+
path: z
|
|
317
|
+
.string()
|
|
318
|
+
.optional()
|
|
319
|
+
.describe("File or path this note relates to (e.g. src/scripts/sync_worker.js)."),
|
|
320
|
+
}),
|
|
321
|
+
},
|
|
322
|
+
async ({ content, title, path }) => {
|
|
323
|
+
const args = { content: content.slice(0, 200) + (content.length > 200 ? "…" : ""), title, path };
|
|
324
|
+
logAsked("store_project_memory", args);
|
|
325
|
+
const trimmed = (content ?? "").trim();
|
|
326
|
+
if (!trimmed) {
|
|
327
|
+
const msg = "content is required and must be non-empty.";
|
|
328
|
+
logReturned("store_project_memory", msg);
|
|
329
|
+
return { content: [{ type: "text" as const, text: msg }] };
|
|
330
|
+
}
|
|
331
|
+
const result = await callStore(getBaseUrl(), { content: trimmed, title, path });
|
|
332
|
+
if ("error" in result) {
|
|
333
|
+
logReturned("store_project_memory", result.error);
|
|
334
|
+
return { content: [{ type: "text" as const, text: result.error }] };
|
|
335
|
+
}
|
|
336
|
+
const responseText = `${result.message} (id: ${result.id})`;
|
|
337
|
+
logReturned("store_project_memory", responseText);
|
|
338
|
+
return { content: [{ type: "text" as const, text: responseText }] };
|
|
339
|
+
}
|
|
340
|
+
);
|
|
341
|
+
|
|
228
342
|
const transport = new StdioServerTransport();
|
|
229
343
|
await server.connect(transport);
|
|
230
344
|
const logFile = getLogFilePath();
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
102
102
|
Code coverage generated by
|
|
103
103
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
104
|
-
at 2026-02-
|
|
104
|
+
at 2026-02-03T02:33:49.502Z
|
|
105
105
|
</div>
|
|
106
106
|
<script src="prettify.js"></script>
|
|
107
107
|
<script>
|
|
@@ -169,7 +169,7 @@ export function getVectorSize(): number {
|
|
|
169
169
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
170
170
|
Code coverage generated by
|
|
171
171
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
172
|
-
at 2026-02-
|
|
172
|
+
at 2026-02-03T02:33:49.502Z
|
|
173
173
|
</div>
|
|
174
174
|
<script src="prettify.js"></script>
|
|
175
175
|
<script>
|