@lotargo/memory_plugin 1.1.5 → 1.1.6

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.
@@ -1,244 +1,244 @@
1
- const { readFile, writeFile, mkdir } = await import("fs/promises");
2
- const { existsSync } = await import("fs");
3
- const { join, basename } = await import("path");
4
- const { homedir } = await import("os");
5
-
6
- const CONFIG_DIR = process.env.OPENCODE_CONFIG_DIR || join(homedir(), ".config", "opencode");
7
- const MEMORY_DIR = join(CONFIG_DIR, "memory");
8
- const GLOBAL_KEY = "global";
9
-
10
- async function ensureDir() {
11
- if (!existsSync(MEMORY_DIR)) await mkdir(MEMORY_DIR, { recursive: true });
12
- }
13
-
14
- function projectName(worktree, directory) {
15
- const dir = worktree || directory;
16
- return dir ? basename(dir) : "default";
17
- }
18
-
19
- function scopeKey(scope, worktree, directory) {
20
- return scope === "global" ? GLOBAL_KEY : projectName(worktree, directory);
21
- }
22
-
23
- function memoryPath(key) {
24
- return join(MEMORY_DIR, `${key.replace(/[^a-zA-Z0-9_-]/g, "_")}.md`);
25
- }
26
-
27
- async function readMemory(key) {
28
- const fp = memoryPath(key);
29
- if (!existsSync(fp)) return [];
30
- const content = await readFile(fp, "utf-8");
31
- return content.split("\n").filter((l) => l.startsWith("- ["));
32
- }
33
-
34
- async function readMemoryRaw(key) {
35
- return (await readMemory(key)).map((e) => e.slice(2));
36
- }
37
-
38
- async function writeMemory(key, entries) {
39
- const header = `# ${key === GLOBAL_KEY ? "Global Memory" : `Memory: ${key}`}\n\n`;
40
- await writeFile(memoryPath(key), header + entries.join("\n") + "\n");
41
- }
42
-
43
- function today() {
44
- const d = new Date();
45
- const date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
46
- const time = `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
47
- return `${date} ${time}`;
48
- }
49
-
50
- async function notify(client, message, variant = "success") {
51
- if (!client?.tui?.showToast) {
52
- await client?.app?.log({
53
- body: { service: "memory-plugin", level: "warn", message: "client.tui.showToast not available" },
54
- });
55
- return;
56
- }
57
- const payload = { message, variant, duration: 3000 };
58
- try {
59
- await client.tui.showToast({ body: payload });
60
- } catch (err1) {
61
- try {
62
- await client.tui.showToast(payload);
63
- } catch (err2) {
64
- await client?.app?.log({
65
- body: {
66
- service: "memory-plugin",
67
- level: "error",
68
- message: "showToast failed",
69
- extra: { shape1: String(err1), shape2: String(err2) },
70
- },
71
- });
72
- }
73
- }
74
- }
75
-
76
- const MEMORY_INSTRUCTION =
77
- "Use `remember` only for important, durable facts about the user and project.\n" +
78
- "Save high-signal things like: name, language, role/goals, constraints, tech\n" +
79
- "stack preferences, architecture decisions, project conventions.\n" +
80
- "DO NOT save: transient details, one-off statements, full conversation turns,\n" +
81
- "or anything unlikely to be useful in future sessions.\n" +
82
- "When saving, translate the fact into English and keep it concise.\n" +
83
- "Use `scope: \"global\"` for personal facts, `scope: \"project\"` for project-specific facts.";
84
-
85
- function buildMemoryContext(globalFacts, projectFacts, projectKey) {
86
- const parts = [MEMORY_INSTRUCTION];
87
- if (globalFacts.length) {
88
- parts.push("## Global\n" + globalFacts.map((f, i) => `${i + 1}. ${f}`).join("\n"));
89
- }
90
- if (projectFacts.length) {
91
- parts.push(`## Project: ${projectKey}\n` + projectFacts.map((f, i) => `${i + 1}. ${f}`).join("\n"));
92
- }
93
- return `<MEMORY>\n${parts.join("\n\n")}\n</MEMORY>`;
94
- }
95
-
96
- const MCP_SERVERS = [
97
- { id: "context7", desc: "Документация библиотек и фреймворков (Context7)" },
98
- { id: "supabase", desc: "БД Supabase — SQL, миграции, edge functions" },
99
- { id: "stitch", desc: "UI дизайн — генерация и редактирование экранов" },
100
- { id: "neon", desc: "БД Neon — PostgreSQL, схемы, миграции" },
101
- { id: "linear", desc: "Linear — задачи, проекты, документы" },
102
- { id: "grep", desc: "Поиск примеров кода на GitHub" },
103
- { id: "skills-anthropic", desc: "Скиллы Anthropic — дизайн, доки, MCP, PDF/PPTX/XLSX" },
104
- { id: "skills-vercel", desc: "Скиллы mattpocock — engineering workflow (grill, tdd, triage, architecture)" },
105
- { id: "playwright", desc: "Браузерные тесты — навигация, скриншоты, клики" },
106
- { id: "github", desc: "GitHub API — PRs, issues, репозитории" },
107
- ];
108
-
109
- export const MemoryPlugin = async ({ directory, worktree, client }) => {
110
- await ensureDir();
111
- const projectKey = projectName(worktree, directory);
112
-
113
- return {
114
- "experimental.chat.messages.transform": async (_input, output) => {
115
- if (!output.messages?.length) return;
116
- const firstUser = output.messages.find((m) => m?.info?.role === "user");
117
- if (!firstUser?.parts?.length) return;
118
-
119
- if (firstUser.parts.some((p) => p.type === "text" && p.text.includes("<MEMORY>"))) return;
120
-
121
- const [globalFacts, projectFacts] = await Promise.all([
122
- readMemoryRaw(GLOBAL_KEY),
123
- readMemoryRaw(projectKey),
124
- ]);
125
-
126
- const context = buildMemoryContext(globalFacts, projectFacts, projectKey);
127
- const ref = firstUser.parts[0];
128
- firstUser.parts.unshift({ ...ref, type: "text", text: context });
129
- },
130
-
131
- tool: {
132
- "list-mcp-tools": {
133
- description: "Показать список всех подключённых MCP серверов и их назначение",
134
- args: {},
135
- async execute() {
136
- const lines = MCP_SERVERS.map((s) => ` ${s.id.padEnd(20)} ${s.desc}`);
137
- return "Доступные MCP серверы:\n" + lines.join("\n");
138
- },
139
- },
140
- "mcp-reminder": {
141
- description: "Напомнить какие MCP инструменты подходят для текущей задачи. Вызови когда сомневаешься что выбрать.",
142
- args: {
143
- task: {
144
- type: "string",
145
- description: "Описание того что собираешься делать (опционально)",
146
- },
147
- },
148
- async execute({ task }) {
149
- if (task) {
150
- return `Для задачи "${task}" рекомендую посмотреть список через list-mcp-tools. Основные сценарии:\n- Работа с кодом → skills-vercel (grill, tdd, review), github\n- UI/дизайн → stitch, skills-anthropic (frontend-design, webapp-testing)\n- База данных → supabase, neon\n- Документы → skills-anthropic (docx, pdf, pptx, xlsx)\n- Поиск примеров → grep`;
151
- }
152
- return "Вызови list-mcp-tools чтобы увидеть все доступные MCP серверы";
153
- },
154
- },
155
- "remember": {
156
- description: "Save an important, durable fact to memory. Only use for high-signal information (name, goals, constraints, tech preferences, project conventions). Translate the fact into English before saving. scope: 'project' (default) or 'global'",
157
- args: {
158
- fact: { type: "string", description: "The fact to remember, written in English" },
159
- scope: {
160
- type: "string",
161
- description: "'project' (default) or 'global'",
162
- default: "project",
163
- },
164
- },
165
- async execute({ fact, scope }, { worktree, directory }) {
166
- const key = scopeKey(scope || "project", worktree, directory);
167
- const entries = await readMemory(key);
168
- const factNormalized = fact.toLowerCase().trim();
169
- if (entries.some((e) => {
170
- const idx = e.indexOf("] ");
171
- return idx !== -1 && e.slice(idx + 2).toLowerCase().trim() === factNormalized;
172
- })) {
173
- return "Already saved";
174
- }
175
- entries.push(`- [${today()}] ${fact}`);
176
- await writeMemory(key, entries);
177
- await notify(client, "Memory updated");
178
- return "Memory updated";
179
- },
180
- },
181
- "recall": {
182
- description: "Показать запомненные факты (scope: project | global | all, по умолчанию все)",
183
- args: {
184
- scope: {
185
- type: "string",
186
- description: "project, global или all (по умолчанию)",
187
- default: "all",
188
- },
189
- },
190
- async execute({ scope }, { worktree, directory }) {
191
- const project = projectName(worktree, directory);
192
- const results = [];
193
- if (scope !== "project") {
194
- const global = await readMemoryRaw(GLOBAL_KEY);
195
- if (global.length) {
196
- results.push("--- Global ---");
197
- global.forEach((e, i) => results.push(`${i + 1}. ${e}`));
198
- }
199
- }
200
- if (scope !== "global") {
201
- const local = await readMemoryRaw(project);
202
- if (local.length) {
203
- if (results.length) results.push("");
204
- results.push(`--- ${project} ---`);
205
- local.forEach((e, i) => results.push(`${i + 1}. ${e}`));
206
- }
207
- }
208
- return results.length ? results.join("\n") : "Memory is empty.";
209
- },
210
- },
211
- "forget": {
212
- description: "Удалить факт по номеру (см. recall) или тексту",
213
- args: {
214
- query: { type: "string", description: "Номер факта или текст для поиска" },
215
- scope: {
216
- type: "string",
217
- description: "project (по умолчанию) или global",
218
- default: "project",
219
- },
220
- },
221
- async execute({ query, scope }, { worktree, directory }) {
222
- const key = scopeKey(scope || "project", worktree, directory);
223
- const entries = await readMemory(key);
224
- const num = parseInt(query, 10);
225
- let removed;
226
- if (!isNaN(num) && num > 0 && num <= entries.length) {
227
- removed = entries.splice(num - 1, 1);
228
- } else {
229
- const filtered = entries.filter((e) => !e.toLowerCase().includes(query.toLowerCase()));
230
- removed = entries.filter((e) => e.toLowerCase().includes(query.toLowerCase()));
231
- entries.length = 0;
232
- entries.push(...filtered);
233
- }
234
- await writeMemory(key, entries);
235
- const result = removed.length ? "Memory updated" : "Not found.";
236
- if (removed.length) await notify(client, "Memory updated");
237
- return result;
238
- },
239
- },
240
- },
241
- };
242
- };
243
-
244
- export default MemoryPlugin;
1
+ const { readFile, writeFile, mkdir } = await import("fs/promises");
2
+ const { existsSync } = await import("fs");
3
+ const { join, basename } = await import("path");
4
+ const { homedir } = await import("os");
5
+
6
+ const CONFIG_DIR = process.env.OPENCODE_CONFIG_DIR || join(homedir(), ".config", "opencode");
7
+ const MEMORY_DIR = join(CONFIG_DIR, "memory");
8
+ const GLOBAL_KEY = "global";
9
+
10
+ async function ensureDir() {
11
+ if (!existsSync(MEMORY_DIR)) await mkdir(MEMORY_DIR, { recursive: true });
12
+ }
13
+
14
+ function projectName(worktree, directory) {
15
+ const dir = worktree || directory;
16
+ return dir ? basename(dir) : "default";
17
+ }
18
+
19
+ function scopeKey(scope, worktree, directory) {
20
+ return scope === "global" ? GLOBAL_KEY : projectName(worktree, directory);
21
+ }
22
+
23
+ function memoryPath(key) {
24
+ return join(MEMORY_DIR, `${key.replace(/[^a-zA-Z0-9_-]/g, "_")}.md`);
25
+ }
26
+
27
+ async function readMemory(key) {
28
+ const fp = memoryPath(key);
29
+ if (!existsSync(fp)) return [];
30
+ const content = await readFile(fp, "utf-8");
31
+ return content.split("\n").filter((l) => l.startsWith("- ["));
32
+ }
33
+
34
+ async function readMemoryRaw(key) {
35
+ return (await readMemory(key)).map((e) => e.slice(2));
36
+ }
37
+
38
+ async function writeMemory(key, entries) {
39
+ const header = `# ${key === GLOBAL_KEY ? "Global Memory" : `Memory: ${key}`}\n\n`;
40
+ await writeFile(memoryPath(key), header + entries.join("\n") + "\n");
41
+ }
42
+
43
+ function today() {
44
+ const d = new Date();
45
+ const date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
46
+ const time = `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
47
+ return `${date} ${time}`;
48
+ }
49
+
50
+ async function notify(client, message, variant = "success") {
51
+ if (!client?.tui?.showToast) {
52
+ await client?.app?.log({
53
+ body: { service: "memory-plugin", level: "warn", message: "client.tui.showToast not available" },
54
+ });
55
+ return;
56
+ }
57
+ const payload = { message, variant, duration: 3000 };
58
+ try {
59
+ await client.tui.showToast({ body: payload });
60
+ } catch (err1) {
61
+ try {
62
+ await client.tui.showToast(payload);
63
+ } catch (err2) {
64
+ await client?.app?.log({
65
+ body: {
66
+ service: "memory-plugin",
67
+ level: "error",
68
+ message: "showToast failed",
69
+ extra: { shape1: String(err1), shape2: String(err2) },
70
+ },
71
+ });
72
+ }
73
+ }
74
+ }
75
+
76
+ const MEMORY_INSTRUCTION =
77
+ "Use `remember` only for important, durable facts about the user and project.\n" +
78
+ "Save high-signal things like: name, language, role/goals, constraints, tech\n" +
79
+ "stack preferences, architecture decisions, project conventions.\n" +
80
+ "DO NOT save: transient details, one-off statements, full conversation turns,\n" +
81
+ "or anything unlikely to be useful in future sessions.\n" +
82
+ "When saving, translate the fact into English and keep it concise.\n" +
83
+ "Use `scope: \"global\"` for personal facts, `scope: \"project\"` for project-specific facts.";
84
+
85
+ function buildMemoryContext(globalFacts, projectFacts, projectKey) {
86
+ const parts = [MEMORY_INSTRUCTION];
87
+ if (globalFacts.length) {
88
+ parts.push("## Global\n" + globalFacts.map((f, i) => `${i + 1}. ${f}`).join("\n"));
89
+ }
90
+ if (projectFacts.length) {
91
+ parts.push(`## Project: ${projectKey}\n` + projectFacts.map((f, i) => `${i + 1}. ${f}`).join("\n"));
92
+ }
93
+ return `<MEMORY>\n${parts.join("\n\n")}\n</MEMORY>`;
94
+ }
95
+
96
+ const MCP_SERVERS = [
97
+ { id: "context7", desc: "Документация библиотек и фреймворков (Context7)" },
98
+ { id: "supabase", desc: "БД Supabase — SQL, миграции, edge functions" },
99
+ { id: "stitch", desc: "UI дизайн — генерация и редактирование экранов" },
100
+ { id: "neon", desc: "БД Neon — PostgreSQL, схемы, миграции" },
101
+ { id: "linear", desc: "Linear — задачи, проекты, документы" },
102
+ { id: "grep", desc: "Поиск примеров кода на GitHub" },
103
+ { id: "skills-anthropic", desc: "Скиллы Anthropic — дизайн, доки, MCP, PDF/PPTX/XLSX" },
104
+ { id: "skills-vercel", desc: "Скиллы mattpocock — engineering workflow (grill, tdd, triage, architecture)" },
105
+ { id: "playwright", desc: "Браузерные тесты — навигация, скриншоты, клики" },
106
+ { id: "github", desc: "GitHub API — PRs, issues, репозитории" },
107
+ ];
108
+
109
+ export const MemoryPlugin = async ({ directory, worktree, client }) => {
110
+ await ensureDir();
111
+ const projectKey = projectName(worktree, directory);
112
+
113
+ return {
114
+ "experimental.chat.messages.transform": async (_input, output) => {
115
+ if (!output.messages?.length) return;
116
+ const firstUser = output.messages.find((m) => m?.info?.role === "user");
117
+ if (!firstUser?.parts?.length) return;
118
+
119
+ if (firstUser.parts.some((p) => p.type === "text" && p.text.includes("<MEMORY>"))) return;
120
+
121
+ const [globalFacts, projectFacts] = await Promise.all([
122
+ readMemoryRaw(GLOBAL_KEY),
123
+ readMemoryRaw(projectKey),
124
+ ]);
125
+
126
+ const context = buildMemoryContext(globalFacts, projectFacts, projectKey);
127
+ const ref = firstUser.parts[0];
128
+ firstUser.parts.unshift({ ...ref, type: "text", text: context });
129
+ },
130
+
131
+ tool: {
132
+ "list-mcp-tools": {
133
+ description: "Показать список всех подключённых MCP серверов и их назначение",
134
+ args: {},
135
+ async execute() {
136
+ const lines = MCP_SERVERS.map((s) => ` ${s.id.padEnd(20)} ${s.desc}`);
137
+ return "Доступные MCP серверы:\n" + lines.join("\n");
138
+ },
139
+ },
140
+ "mcp-reminder": {
141
+ description: "Напомнить какие MCP инструменты подходят для текущей задачи. Вызови когда сомневаешься что выбрать.",
142
+ args: {
143
+ task: {
144
+ type: "string",
145
+ description: "Описание того что собираешься делать (опционально)",
146
+ },
147
+ },
148
+ async execute({ task }) {
149
+ if (task) {
150
+ return `Для задачи "${task}" рекомендую посмотреть список через list-mcp-tools. Основные сценарии:\n- Работа с кодом → skills-vercel (grill, tdd, review), github\n- UI/дизайн → stitch, skills-anthropic (frontend-design, webapp-testing)\n- База данных → supabase, neon\n- Документы → skills-anthropic (docx, pdf, pptx, xlsx)\n- Поиск примеров → grep`;
151
+ }
152
+ return "Вызови list-mcp-tools чтобы увидеть все доступные MCP серверы";
153
+ },
154
+ },
155
+ "remember": {
156
+ description: "Save an important, durable fact to memory. Only use for high-signal information (name, goals, constraints, tech preferences, project conventions). Translate the fact into English before saving. scope: 'project' (default) or 'global'",
157
+ args: {
158
+ fact: { type: "string", description: "The fact to remember, written in English" },
159
+ scope: {
160
+ type: "string",
161
+ description: "'project' (default) or 'global'",
162
+ default: "project",
163
+ },
164
+ },
165
+ async execute({ fact, scope }, { worktree, directory }) {
166
+ const key = scopeKey(scope || "project", worktree, directory);
167
+ const entries = await readMemory(key);
168
+ const factNormalized = fact.toLowerCase().trim();
169
+ if (entries.some((e) => {
170
+ const idx = e.indexOf("] ");
171
+ return idx !== -1 && e.slice(idx + 2).toLowerCase().trim() === factNormalized;
172
+ })) {
173
+ return "Already saved";
174
+ }
175
+ entries.push(`- [${today()}] ${fact}`);
176
+ await writeMemory(key, entries);
177
+ await notify(client, "Memory updated");
178
+ return "Memory updated";
179
+ },
180
+ },
181
+ "recall": {
182
+ description: "Показать запомненные факты (scope: project | global | all, по умолчанию все)",
183
+ args: {
184
+ scope: {
185
+ type: "string",
186
+ description: "project, global или all (по умолчанию)",
187
+ default: "all",
188
+ },
189
+ },
190
+ async execute({ scope }, { worktree, directory }) {
191
+ const project = projectName(worktree, directory);
192
+ const results = [];
193
+ if (scope !== "project") {
194
+ const global = await readMemoryRaw(GLOBAL_KEY);
195
+ if (global.length) {
196
+ results.push("--- Global ---");
197
+ global.forEach((e, i) => results.push(`${i + 1}. ${e}`));
198
+ }
199
+ }
200
+ if (scope !== "global") {
201
+ const local = await readMemoryRaw(project);
202
+ if (local.length) {
203
+ if (results.length) results.push("");
204
+ results.push(`--- ${project} ---`);
205
+ local.forEach((e, i) => results.push(`${i + 1}. ${e}`));
206
+ }
207
+ }
208
+ return results.length ? results.join("\n") : "Memory is empty.";
209
+ },
210
+ },
211
+ "forget": {
212
+ description: "Удалить факт по номеру (см. recall) или тексту",
213
+ args: {
214
+ query: { type: "string", description: "Номер факта или текст для поиска" },
215
+ scope: {
216
+ type: "string",
217
+ description: "project (по умолчанию) или global",
218
+ default: "project",
219
+ },
220
+ },
221
+ async execute({ query, scope }, { worktree, directory }) {
222
+ const key = scopeKey(scope || "project", worktree, directory);
223
+ const entries = await readMemory(key);
224
+ const num = parseInt(query, 10);
225
+ let removed;
226
+ if (!isNaN(num) && num > 0 && num <= entries.length) {
227
+ removed = entries.splice(num - 1, 1);
228
+ } else {
229
+ const filtered = entries.filter((e) => !e.toLowerCase().includes(query.toLowerCase()));
230
+ removed = entries.filter((e) => e.toLowerCase().includes(query.toLowerCase()));
231
+ entries.length = 0;
232
+ entries.push(...filtered);
233
+ }
234
+ await writeMemory(key, entries);
235
+ const result = removed.length ? "Memory updated" : "Not found.";
236
+ if (removed.length) await notify(client, "Memory updated");
237
+ return result;
238
+ },
239
+ },
240
+ },
241
+ };
242
+ };
243
+
244
+ export default MemoryPlugin;
package/package.json CHANGED
@@ -1,54 +1,58 @@
1
- {
2
- "name": "@lotargo/memory_plugin",
3
- "version": "1.1.5",
4
- "description": "Persistent memory agent for coding AI tools — remembers user preferences and project context across sessions. Works with Antigravity, OpenCode, Claude Code, and Codex.",
5
- "type": "module",
6
- "main": "opencode-plugin/index.js",
7
- "scripts": {
8
- "preinstall": "node mcp-server/preinstall.js || true"
9
- },
10
- "bin": {
11
- "memory_plugin": "mcp-server/index.js",
12
- "memory-agent": "mcp-server/index.js",
13
- "memory-cli": "mcp-server/cli.js"
14
- },
15
- "files": [
16
- "opencode-plugin",
17
- "mcp-server/admin",
18
- "mcp-server/benchmarks",
19
- "mcp-server/config",
20
- "mcp-server/db",
21
- "mcp-server/graph",
22
- "mcp-server/ingest",
23
- "mcp-server/ml",
24
- "mcp-server/retrieval",
25
- "mcp-server/storage",
26
- "mcp-server/cli.js",
27
- "mcp-server/index.js",
28
- "mcp-server/memory.js",
29
- "mcp-server/setup.js",
30
- "mcp-server/preinstall.js",
31
- "skills"
32
- ],
33
- "keywords": [
34
- "opencode",
35
- "claude-code",
36
- "codex",
37
- "antigravity",
38
- "plugin",
39
- "memory",
40
- "mcp",
41
- "ai",
42
- "context"
43
- ],
44
- "license": "MIT",
45
- "repository": {
46
- "type": "git",
47
- "url": "https://github.com/Lotargo/memory_pugin.git"
48
- },
49
- "dependencies": {
50
- "@modelcontextprotocol/sdk": "^1.29.0",
51
- "@xenova/transformers": "^2.17.2",
52
- "zod": "^4.1.0"
53
- }
54
- }
1
+ {
2
+ "name": "@lotargo/memory_plugin",
3
+ "version": "1.1.6",
4
+ "description": "Persistent memory agent for coding AI tools — remembers user preferences and project context across sessions. Works with Antigravity, OpenCode, Claude Code, and Codex.",
5
+ "type": "module",
6
+ "main": "opencode-plugin/index.js",
7
+ "scripts": {
8
+ "preinstall": "node mcp-server/preinstall.js || true"
9
+ },
10
+ "bin": {
11
+ "memory_plugin": "mcp-server/index.js",
12
+ "memory-agent": "mcp-server/index.js",
13
+ "memory-cli": "mcp-server/cli.js"
14
+ },
15
+ "files": [
16
+ "opencode-plugin",
17
+ "mcp-server/admin",
18
+ "mcp-server/benchmarks",
19
+ "mcp-server/config",
20
+ "mcp-server/db",
21
+ "mcp-server/graph",
22
+ "mcp-server/ingest",
23
+ "mcp-server/ml",
24
+ "mcp-server/retrieval",
25
+ "mcp-server/storage",
26
+ "mcp-server/cli.js",
27
+ "mcp-server/index.js",
28
+ "mcp-server/memory.js",
29
+ "mcp-server/setup.js",
30
+ "mcp-server/preinstall.js",
31
+ "skills"
32
+ ],
33
+ "keywords": [
34
+ "opencode",
35
+ "claude-code",
36
+ "codex",
37
+ "antigravity",
38
+ "plugin",
39
+ "memory",
40
+ "mcp",
41
+ "ai",
42
+ "context"
43
+ ],
44
+ "author": "Lotargo",
45
+ "license": "MIT",
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "https://github.com/Lotargo/memory_pugin.git"
52
+ },
53
+ "dependencies": {
54
+ "@modelcontextprotocol/sdk": "^1.29.0",
55
+ "@huggingface/transformers": "^3.3.3",
56
+ "zod": "^4.1.0"
57
+ }
58
+ }