local-agent-memory 0.0.0-stage → 1.0.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 (43) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +108 -2
  3. package/dist/cli/commands/hook.d.ts +1 -0
  4. package/dist/cli/commands/hook.js +66 -0
  5. package/dist/cli/commands/init.d.ts +5 -0
  6. package/dist/cli/commands/init.js +158 -0
  7. package/dist/cli/commands/record.d.ts +3 -0
  8. package/dist/cli/commands/record.js +58 -0
  9. package/dist/cli/commands/reindex.d.ts +1 -0
  10. package/dist/cli/commands/reindex.js +41 -0
  11. package/dist/cli/commands/status.d.ts +1 -0
  12. package/dist/cli/commands/status.js +88 -0
  13. package/dist/cli/commands/sync.d.ts +8 -0
  14. package/dist/cli/commands/sync.js +134 -0
  15. package/dist/cli/commands/template.d.ts +1 -0
  16. package/dist/cli/commands/template.js +116 -0
  17. package/dist/cli/index.d.ts +2 -0
  18. package/dist/cli/index.js +140 -0
  19. package/dist/cli/mcp.d.ts +2 -0
  20. package/dist/cli/mcp.js +13 -0
  21. package/dist/core/embeddings.d.ts +14 -0
  22. package/dist/core/embeddings.js +127 -0
  23. package/dist/core/parser.d.ts +25 -0
  24. package/dist/core/parser.js +151 -0
  25. package/dist/core/search.d.ts +19 -0
  26. package/dist/core/search.js +100 -0
  27. package/dist/core/sync.d.ts +22 -0
  28. package/dist/core/sync.js +159 -0
  29. package/dist/db/project.d.ts +12 -0
  30. package/dist/db/project.js +113 -0
  31. package/dist/db/registry.d.ts +9 -0
  32. package/dist/db/registry.js +92 -0
  33. package/dist/mcp/middleware.d.ts +1 -0
  34. package/dist/mcp/middleware.js +46 -0
  35. package/dist/mcp/server.d.ts +2 -0
  36. package/dist/mcp/server.js +102 -0
  37. package/dist/mcp/tools.d.ts +2 -0
  38. package/dist/mcp/tools.js +244 -0
  39. package/dist/mcp/utils.d.ts +5 -0
  40. package/dist/mcp/utils.js +82 -0
  41. package/dist/setup/initGlobal.d.ts +5 -0
  42. package/dist/setup/initGlobal.js +167 -0
  43. package/package.json +72 -6
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.syncMiddleware = syncMiddleware;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const sync_1 = require("../cli/commands/sync");
40
+ async function syncMiddleware(cwd = process.cwd()) {
41
+ const memoryDir = path.join(cwd, ".memory");
42
+ if (!fs.existsSync(memoryDir)) {
43
+ throw new Error("Project not initialized. Run memory init first.");
44
+ }
45
+ await (0, sync_1.doSyncProject)(cwd);
46
+ }
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function setupMCPServer(): Promise<McpServer>;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.setupMCPServer = setupMCPServer;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
40
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
41
+ const tools_1 = require("./tools");
42
+ const utils_1 = require("./utils");
43
+ async function setupMCPServer() {
44
+ const { cwd } = await (0, utils_1.resolveCwd)();
45
+ const memoryDir = path.join(cwd, ".memory");
46
+ if (!fs.existsSync(memoryDir)) {
47
+ fs.mkdirSync(memoryDir, { recursive: true });
48
+ }
49
+ const logFile = path.join(memoryDir, "mcp-debug.log");
50
+ const log = (msg) => {
51
+ fs.appendFileSync(logFile, `[${new Date().toISOString()}] ${msg}\n`);
52
+ };
53
+ log("Starting MCP Server");
54
+ const server = new mcp_js_1.McpServer({
55
+ name: "local-agent-memory",
56
+ version: "1.0.0",
57
+ });
58
+ server.resource("agent-guidelines", "memory://agent-guidelines", { description: "Agent guidelines and memory core rules" }, async (uri) => {
59
+ const { cwd: resolvedCwd } = await (0, utils_1.resolveCwd)();
60
+ const corePath = path.join(resolvedCwd, ".memory", "core.md");
61
+ const text = fs.existsSync(corePath)
62
+ ? fs.readFileSync(corePath, "utf8")
63
+ : "No core memory found.";
64
+ return {
65
+ contents: [
66
+ {
67
+ uri: uri.href,
68
+ text,
69
+ mimeType: "text/markdown",
70
+ },
71
+ ],
72
+ };
73
+ });
74
+ server.prompt("agent-guidelines", "Get the agent guidelines and memory core rules", async () => {
75
+ const { cwd: resolvedCwd } = await (0, utils_1.resolveCwd)();
76
+ const corePath = path.join(resolvedCwd, ".memory", "core.md");
77
+ const text = fs.existsSync(corePath)
78
+ ? fs.readFileSync(corePath, "utf8")
79
+ : "No core memory found.";
80
+ return {
81
+ messages: [
82
+ {
83
+ role: "user",
84
+ content: {
85
+ type: "text",
86
+ text: `Here are the core rules for this project:\n\n${text}`,
87
+ },
88
+ },
89
+ ],
90
+ };
91
+ });
92
+ (0, tools_1.registerTools)(server);
93
+ const transport = new stdio_js_1.StdioServerTransport();
94
+ transport.onerror = (err) => {
95
+ log(`Transport error: ${err}`);
96
+ };
97
+ await server.connect(transport);
98
+ log("MCP Server connected via stdio");
99
+ // Opcionalmente podemos exponer log para ser usado por tools si se lo pasamos,
100
+ // pero el servidor ya está funcionando y registrando arranque y errores.
101
+ return server;
102
+ }
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerTools(server: McpServer): void;
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerTools = registerTools;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const zod_1 = require("zod");
40
+ const search_1 = require("../core/search");
41
+ const project_1 = require("../db/project");
42
+ const middleware_1 = require("./middleware");
43
+ const utils_1 = require("./utils");
44
+ function registerTools(server) {
45
+ // @ts-expect-error - Bypass TS2589
46
+ server.tool("get_project_context", "Obtiene el contexto del proyecto actual leyendo el archivo core.md y listando decisiones recientes.", {
47
+ projectRoot: zod_1.z
48
+ .string()
49
+ .optional()
50
+ .describe("Ruta absoluta del proyecto (usar si MCP es global)"),
51
+ }, async (args) => {
52
+ const { cwd, fallbackUsed } = await (0, utils_1.resolveCwd)(args.projectRoot, server);
53
+ await (0, middleware_1.syncMiddleware)(cwd);
54
+ const memoryDir = path.join(cwd, ".memory");
55
+ const corePath = path.join(memoryDir, "core.md");
56
+ let coreContent = "No core.md found.";
57
+ if (fs.existsSync(corePath)) {
58
+ coreContent = fs.readFileSync(corePath, "utf8");
59
+ }
60
+ const decisionsDir = path.join(memoryDir, "decisions");
61
+ let decisionsList = [];
62
+ if (fs.existsSync(decisionsDir)) {
63
+ const files = fs
64
+ .readdirSync(decisionsDir)
65
+ .filter((f) => f.endsWith(".md"))
66
+ .sort()
67
+ .reverse()
68
+ .slice(0, 5);
69
+ decisionsList = files.map((f) => `- ${f}`);
70
+ }
71
+ return {
72
+ content: [
73
+ {
74
+ type: "text",
75
+ text: `${fallbackUsed ? `[Warning: Used fallback project root at ${cwd}]\n\n` : ""}## Core Rules\n${coreContent}\n\n## Recent Decisions\n${decisionsList.join("\n")}`,
76
+ },
77
+ ],
78
+ };
79
+ });
80
+ // @ts-expect-error - Bypass TS2589
81
+ server.tool("search_memory", "Busca en la memoria usando búsqueda híbrida (semántica y léxica).", {
82
+ query: zod_1.z.string().describe("La consulta a buscar"),
83
+ filter: zod_1.z.string().optional().describe("Filtro por ruta de archivo"),
84
+ limit: zod_1.z.number().optional().describe("Límite de resultados"),
85
+ projectRoot: zod_1.z
86
+ .string()
87
+ .optional()
88
+ .describe("Ruta absoluta del proyecto (usar si MCP es global)"),
89
+ }, async (args) => {
90
+ const { cwd, fallbackUsed } = await (0, utils_1.resolveCwd)(args.projectRoot, server);
91
+ await (0, middleware_1.syncMiddleware)(cwd);
92
+ const dbPath = (0, project_1.getLocalDbPath)(cwd);
93
+ const db = (0, project_1.initLocalDb)(dbPath);
94
+ try {
95
+ const results = await (0, search_1.hybridSearch)(args.query, args.limit || 10, db, args.filter);
96
+ let textResults = results
97
+ .map((r) => `[${r.path}:${r.startLine}-${r.endLine}] ${r.breadcrumbs}\n${r.text}`)
98
+ .join("\n\n---\n\n");
99
+ // Truncar para cumplir con límite de tokens (DR-05: ~1500 tokens por retorno, aprox 6000 caracteres)
100
+ if (textResults.length > 6000) {
101
+ textResults = `${textResults.slice(0, 6000)}\n\n...[Truncated due to token limits]`;
102
+ }
103
+ return {
104
+ content: [
105
+ {
106
+ type: "text",
107
+ text: (fallbackUsed
108
+ ? `[Warning: Used fallback project root at ${cwd}]\n\n`
109
+ : "") + (textResults || "No results found."),
110
+ },
111
+ ],
112
+ };
113
+ }
114
+ finally {
115
+ db.close();
116
+ }
117
+ });
118
+ server.tool("log_decision", "Registra una nueva decisión arquitectónica (ADR).", {
119
+ title: zod_1.z.string().describe("Título corto de la decisión"),
120
+ status: zod_1.z.string().describe("Estado (ej. Aceptado, Rechazado)"),
121
+ context: zod_1.z.string().describe("Contexto del problema"),
122
+ decision: zod_1.z.string().describe("La decisión tomada"),
123
+ consequences: zod_1.z.string().describe("Consecuencias de la decisión"),
124
+ alternatives_considered: zod_1.z
125
+ .string()
126
+ .optional()
127
+ .describe("Alternativas consideradas"),
128
+ projectRoot: zod_1.z
129
+ .string()
130
+ .optional()
131
+ .describe("Ruta absoluta del proyecto (usar si MCP es global)"),
132
+ }, async (args) => {
133
+ // Create slug
134
+ const date = new Date().toISOString().split("T")[0];
135
+ const slug = args.title
136
+ .toLowerCase()
137
+ .replace(/[^a-z0-9]+/g, "-")
138
+ .replace(/(^-|-$)/g, "");
139
+ const filename = `${date}-${slug}.md`;
140
+ const { cwd, fallbackUsed } = await (0, utils_1.resolveCwd)(args.projectRoot, server);
141
+ const memoryDir = path.join(cwd, ".memory");
142
+ const decisionsDir = path.join(memoryDir, "decisions");
143
+ if (!fs.existsSync(decisionsDir)) {
144
+ fs.mkdirSync(decisionsDir, { recursive: true });
145
+ }
146
+ const filePath = path.join(decisionsDir, filename);
147
+ let content = `---
148
+ title: ${args.title}
149
+ status: ${args.status}
150
+ date: ${date}
151
+ ---
152
+
153
+ # ${args.title}
154
+
155
+ ## Context
156
+ ${args.context}
157
+
158
+ ## Decision
159
+ ${args.decision}
160
+
161
+ ## Consequences
162
+ ${args.consequences}
163
+ `;
164
+ if (args.alternatives_considered) {
165
+ content += `\n## Alternatives Considered\n${args.alternatives_considered}\n`;
166
+ }
167
+ fs.writeFileSync(filePath, content);
168
+ // Sincronizar después de escribir
169
+ await (0, middleware_1.syncMiddleware)(cwd);
170
+ return {
171
+ content: [
172
+ {
173
+ type: "text",
174
+ text: `${fallbackUsed ? `[Warning: Used fallback project root at ${cwd}]\n\n` : ""}Decision logged successfully at ${path.join(".memory", "decisions", filename)}`,
175
+ },
176
+ ],
177
+ };
178
+ });
179
+ server.tool("update_core_rules", "Añade contenido a las reglas core (core.md).", {
180
+ changes_to_append: zod_1.z
181
+ .string()
182
+ .describe("Contenido a añadir al final del archivo core.md"),
183
+ projectRoot: zod_1.z
184
+ .string()
185
+ .optional()
186
+ .describe("Ruta absoluta del proyecto (usar si MCP es global)"),
187
+ }, async (args) => {
188
+ const { cwd, fallbackUsed } = await (0, utils_1.resolveCwd)(args.projectRoot, server);
189
+ const memoryDir = path.join(cwd, ".memory");
190
+ const corePath = path.join(memoryDir, "core.md");
191
+ if (!fs.existsSync(memoryDir)) {
192
+ fs.mkdirSync(memoryDir, { recursive: true });
193
+ }
194
+ fs.appendFileSync(corePath, `\n${args.changes_to_append}\n`);
195
+ // Sincronizar después de escribir
196
+ await (0, middleware_1.syncMiddleware)(cwd);
197
+ return {
198
+ content: [
199
+ {
200
+ type: "text",
201
+ text: `${fallbackUsed ? `[Warning: Used fallback project root at ${cwd}]\n\n` : ""}Core rules updated successfully.`,
202
+ },
203
+ ],
204
+ };
205
+ });
206
+ server.tool("end_session", "Finaliza una tarea o sesión, sintetizando qué se modificó y qué acuerdos se tomaron, guardándolo en el ledger de la memoria.", {
207
+ summary: zod_1.z
208
+ .string()
209
+ .describe("Resumen de lo que se modificó y qué acuerdos se tomaron en la sesión"),
210
+ projectRoot: zod_1.z
211
+ .string()
212
+ .optional()
213
+ .describe("Ruta absoluta del proyecto (usar si MCP es global)"),
214
+ }, async (args) => {
215
+ const { cwd, fallbackUsed } = await (0, utils_1.resolveCwd)(args.projectRoot, server);
216
+ const memoryDir = path.join(cwd, ".memory");
217
+ const ledgerDir = path.join(memoryDir, "ledger");
218
+ const dateObj = new Date();
219
+ const year = dateObj.getFullYear();
220
+ const month = String(dateObj.getMonth() + 1).padStart(2, "0");
221
+ const day = String(dateObj.getDate()).padStart(2, "0");
222
+ const hours = String(dateObj.getHours()).padStart(2, "0");
223
+ const minutes = String(dateObj.getMinutes()).padStart(2, "0");
224
+ const seconds = String(dateObj.getSeconds()).padStart(2, "0");
225
+ const filename = `${year}-${month}-${day}-${hours}-${minutes}-${seconds}-session.md`;
226
+ const summariesPath = path.join(ledgerDir, filename);
227
+ if (!fs.existsSync(ledgerDir)) {
228
+ fs.mkdirSync(ledgerDir, { recursive: true });
229
+ }
230
+ const date = dateObj.toISOString();
231
+ const content = `\n## Session ended at ${date}\n\n${args.summary}\n\n---\n`;
232
+ fs.writeFileSync(summariesPath, content);
233
+ // Sincronizar después de escribir
234
+ await (0, middleware_1.syncMiddleware)(cwd);
235
+ return {
236
+ content: [
237
+ {
238
+ type: "text",
239
+ text: `${fallbackUsed ? `[Warning: Used fallback project root at ${cwd}]\n\n` : ""}Session summary flushed successfully to .memory/ledger/${filename}`,
240
+ },
241
+ ],
242
+ };
243
+ });
244
+ }
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function resolveCwd(argsPath?: string, server?: McpServer): Promise<{
3
+ cwd: string;
4
+ fallbackUsed: boolean;
5
+ }>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveCwd = resolveCwd;
37
+ const fs = __importStar(require("node:fs"));
38
+ const path = __importStar(require("node:path"));
39
+ const registry_1 = require("../db/registry");
40
+ async function resolveCwd(argsPath, server) {
41
+ if (argsPath && fs.existsSync(argsPath)) {
42
+ return { cwd: argsPath, fallbackUsed: false };
43
+ }
44
+ if (server && server.server) {
45
+ try {
46
+ const result = await server.server.request({ method: "roots/list" }, require("zod").any());
47
+ const roots = result?.roots;
48
+ if (roots && Array.isArray(roots)) {
49
+ for (const root of roots) {
50
+ let rootPath = root.uri.replace(/^file:\/\//i, "");
51
+ if (process.platform === "win32" && rootPath.startsWith("/")) {
52
+ rootPath = rootPath.slice(1);
53
+ }
54
+ rootPath = decodeURIComponent(rootPath);
55
+ if (fs.existsSync(path.join(rootPath, ".memory"))) {
56
+ return { cwd: rootPath, fallbackUsed: false };
57
+ }
58
+ }
59
+ }
60
+ }
61
+ catch (_e) {
62
+ // Ignore errors if client doesn't support roots/list
63
+ }
64
+ }
65
+ const current = process.cwd();
66
+ if (fs.existsSync(path.join(current, ".memory"))) {
67
+ return { cwd: current, fallbackUsed: false };
68
+ }
69
+ try {
70
+ const registryResult = await (0, registry_1.getProjectRootFromRegistry)(current);
71
+ if (registryResult && fs.existsSync(registryResult.path)) {
72
+ return {
73
+ cwd: registryResult.path,
74
+ fallbackUsed: registryResult.fallback,
75
+ };
76
+ }
77
+ }
78
+ catch (_err) {
79
+ // Ignore db errors on fallback
80
+ }
81
+ return { cwd: current, fallbackUsed: false };
82
+ }
@@ -0,0 +1,5 @@
1
+ export declare const getLocalMemoryDir: () => string;
2
+ export declare const getModelsDir: () => string;
3
+ export declare const getBinDir: () => string;
4
+ export declare function downloadFile(url: string, dest: string, retries?: number): Promise<void>;
5
+ export declare function initGlobalEnv(): Promise<void>;
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.getBinDir = exports.getModelsDir = exports.getLocalMemoryDir = void 0;
40
+ exports.downloadFile = downloadFile;
41
+ exports.initGlobalEnv = initGlobalEnv;
42
+ const node_child_process_1 = require("node:child_process");
43
+ const node_fs_1 = __importDefault(require("node:fs"));
44
+ const node_https_1 = __importDefault(require("node:https"));
45
+ const node_os_1 = __importDefault(require("node:os"));
46
+ const node_path_1 = __importDefault(require("node:path"));
47
+ const transformers_1 = require("@xenova/transformers");
48
+ const tar = __importStar(require("tar"));
49
+ const getLocalMemoryDir = () => node_path_1.default.join(node_os_1.default.homedir(), ".local_memory");
50
+ exports.getLocalMemoryDir = getLocalMemoryDir;
51
+ const getModelsDir = () => node_path_1.default.join((0, exports.getLocalMemoryDir)(), "models");
52
+ exports.getModelsDir = getModelsDir;
53
+ const getBinDir = () => node_path_1.default.join((0, exports.getLocalMemoryDir)(), "bin");
54
+ exports.getBinDir = getBinDir;
55
+ async function downloadFile(url, dest, retries = 3) {
56
+ for (let i = 0; i < retries; i++) {
57
+ try {
58
+ await new Promise((resolve, reject) => {
59
+ const file = node_fs_1.default.createWriteStream(dest);
60
+ node_https_1.default
61
+ .get(url, (response) => {
62
+ if (response.statusCode === 301 || response.statusCode === 302) {
63
+ // handle redirect
64
+ if (!response.headers.location) {
65
+ reject(new Error("Redirect with no location"));
66
+ return;
67
+ }
68
+ downloadFile(response.headers.location, dest, retries)
69
+ .then(resolve)
70
+ .catch(reject);
71
+ return;
72
+ }
73
+ if (response.statusCode !== 200) {
74
+ reject(new Error(`Failed to download, status code: ${response.statusCode}`));
75
+ return;
76
+ }
77
+ response.pipe(file);
78
+ file.on("finish", () => {
79
+ file.close();
80
+ resolve();
81
+ });
82
+ })
83
+ .on("error", (err) => {
84
+ node_fs_1.default.unlink(dest, () => { });
85
+ reject(err);
86
+ });
87
+ });
88
+ return; // Success
89
+ }
90
+ catch (error) {
91
+ if (i === retries - 1) {
92
+ throw error;
93
+ }
94
+ // Wait before retry
95
+ await new Promise((resolve) => setTimeout(resolve, 1000));
96
+ }
97
+ }
98
+ }
99
+ function getSqliteVecUrl() {
100
+ const platform = node_os_1.default.platform();
101
+ const arch = node_os_1.default.arch();
102
+ const version = "0.1.8";
103
+ const baseUrl = `https://github.com/asg017/sqlite-vec/releases/download/v${version}`;
104
+ if (platform === "win32") {
105
+ return `${baseUrl}/sqlite-vec-${version}-loadable-windows-x86_64.tar.gz`;
106
+ }
107
+ else if (platform === "darwin") {
108
+ if (arch === "arm64")
109
+ return `${baseUrl}/sqlite-vec-${version}-loadable-macos-aarch64.tar.gz`;
110
+ return `${baseUrl}/sqlite-vec-${version}-loadable-macos-x86_64.tar.gz`;
111
+ }
112
+ else {
113
+ // linux
114
+ if (arch === "arm64")
115
+ return `${baseUrl}/sqlite-vec-${version}-loadable-linux-aarch64.tar.gz`;
116
+ return `${baseUrl}/sqlite-vec-${version}-loadable-linux-x86_64.tar.gz`;
117
+ }
118
+ }
119
+ async function initGlobalEnv() {
120
+ const modelsDir = (0, exports.getModelsDir)();
121
+ const binDir = (0, exports.getBinDir)();
122
+ if (!node_fs_1.default.existsSync(modelsDir)) {
123
+ node_fs_1.default.mkdirSync(modelsDir, { recursive: true });
124
+ }
125
+ if (!node_fs_1.default.existsSync(binDir)) {
126
+ node_fs_1.default.mkdirSync(binDir, { recursive: true });
127
+ }
128
+ // Configure xenova transformers cache
129
+ transformers_1.env.cacheDir = modelsDir;
130
+ // Download ONNX model (all-MiniLM-L6-v2) if not present
131
+ try {
132
+ await (0, transformers_1.pipeline)("feature-extraction", "Xenova/all-MiniLM-L6-v2", {
133
+ quantized: true,
134
+ });
135
+ }
136
+ catch (error) {
137
+ console.error("Error downloading ONNX model:", error);
138
+ throw error;
139
+ }
140
+ // Download sqlite-vec
141
+ const vecUrl = getSqliteVecUrl();
142
+ const vecFlag = node_path_1.default.join(binDir, ".sqlite-vec-downloaded");
143
+ if (!node_fs_1.default.existsSync(vecFlag)) {
144
+ try {
145
+ const tempDest = node_path_1.default.join(binDir, vecUrl.endsWith(".zip") ? "temp.zip" : "temp.tar.gz");
146
+ await downloadFile(vecUrl, tempDest, 3);
147
+ // Extract
148
+ /* istanbul ignore if */
149
+ if (vecUrl.endsWith(".zip")) {
150
+ // simple powershell unzip for win32 without external deps since tar might not handle zip well always
151
+ (0, node_child_process_1.execSync)(`powershell -command "Expand-Archive -Force '${tempDest}' '${binDir}'"`);
152
+ }
153
+ else {
154
+ await tar.x({
155
+ file: tempDest,
156
+ cwd: binDir,
157
+ });
158
+ }
159
+ node_fs_1.default.unlinkSync(tempDest);
160
+ node_fs_1.default.writeFileSync(vecFlag, new Date().toISOString());
161
+ }
162
+ catch (error) {
163
+ console.error("Error downloading sqlite-vec extension:", error);
164
+ throw error;
165
+ }
166
+ }
167
+ }