@lotargo/memory_plugin 1.1.4 → 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,148 +1,148 @@
1
- import { readFile, writeFile, mkdir } from "fs/promises";
2
- import { existsSync } from "fs";
3
- import { join } from "path";
4
- import { homedir } from "os";
5
-
6
- export async function runSetup() {
7
- const args = process.argv.slice(2);
8
- const hasSpecificFlag = args.some((a) =>
9
- ["--opencode", "--claude", "--codex", "--antigravity", "--gemini"].includes(a.toLowerCase())
10
- );
11
-
12
- const doOpenCode = !hasSpecificFlag || args.includes("--opencode");
13
- const doClaude = !hasSpecificFlag || args.includes("--claude");
14
- const doAntigravity = !hasSpecificFlag || args.includes("--antigravity") || args.includes("--gemini");
15
- const doCodex = !hasSpecificFlag || args.includes("--codex");
16
-
17
- console.log("\nSetting up @lotargo/memory_plugin...\n");
18
- const home = homedir();
19
- let configuredCount = 0;
20
-
21
- // 1. OpenCode (~/.config/opencode/opencode.json)
22
- if (doOpenCode) {
23
- try {
24
- const opencodeDir = process.env.OPENCODE_CONFIG_DIR || join(home, ".config", "opencode");
25
- const opencodeConfigPath = join(opencodeDir, "opencode.json");
26
- await mkdir(opencodeDir, { recursive: true });
27
-
28
- let config = {};
29
- if (existsSync(opencodeConfigPath)) {
30
- try {
31
- config = JSON.parse(await readFile(opencodeConfigPath, "utf-8"));
32
- } catch (e) {}
33
- }
34
- if (!Array.isArray(config.plugin)) config.plugin = [];
35
- // Clean up legacy / incorrect plugin entry names
36
- const obsoleteNames = ["opencode-memory-plugin", "memory_plugin", "memory-plugin"];
37
- config.plugin = config.plugin.filter((p) => !obsoleteNames.includes(p));
38
- if (!config.plugin.includes("@lotargo/memory_plugin")) {
39
- config.plugin.push("@lotargo/memory_plugin");
40
- }
41
- // Clean up legacy mcp-helper.js standalone file plugin if present
42
- const legacyPluginFile = join(opencodeDir, "plugins", "mcp-helper.js");
43
- if (existsSync(legacyPluginFile)) {
44
- try { const { unlink } = await import("fs/promises"); await unlink(legacyPluginFile); } catch (e) {}
45
- }
46
- await writeFile(opencodeConfigPath, JSON.stringify(config, null, 2));
47
- console.log(" [OK] OpenCode: configured plugin in ~/.config/opencode/opencode.json");
48
- configuredCount++;
49
- } catch (err) {
50
- console.log(" [SKIP] OpenCode setup skipped:", err.message);
51
- }
52
- }
53
-
54
- // 2. Claude Code (~/.claude.json)
55
- if (doClaude) {
56
- try {
57
- const claudePath = join(home, ".claude.json");
58
- let config = {};
59
- if (existsSync(claudePath)) {
60
- try {
61
- config = JSON.parse(await readFile(claudePath, "utf-8"));
62
- } catch (e) {}
63
- }
64
- if (!config.mcpServers) config.mcpServers = {};
65
- config.mcpServers["memory-agent"] = {
66
- command: "npx",
67
- args: ["-y", "@lotargo/memory_plugin"],
68
- };
69
- await writeFile(claudePath, JSON.stringify(config, null, 2));
70
- console.log(" [OK] Claude Code: configured MCP server in ~/.claude.json");
71
- configuredCount++;
72
- } catch (err) {
73
- console.log(" [SKIP] Claude Code setup skipped:", err.message);
74
- }
75
- }
76
-
77
- // 3. Antigravity / Gemini CLI (~/.gemini/config/mcp_config.json & .agents/mcp_config.json)
78
- if (doAntigravity) {
79
- try {
80
- // Global Antigravity config
81
- const geminiConfigDir = join(home, ".gemini", "config");
82
- await mkdir(geminiConfigDir, { recursive: true });
83
- const geminiConfigFile = join(geminiConfigDir, "mcp_config.json");
84
-
85
- let config = {};
86
- if (existsSync(geminiConfigFile)) {
87
- try {
88
- config = JSON.parse(await readFile(geminiConfigFile, "utf-8"));
89
- } catch (e) {}
90
- }
91
- if (!config.mcpServers) config.mcpServers = {};
92
- config.mcpServers["memory-agent"] = {
93
- command: "npx",
94
- args: ["-y", "@lotargo/memory_plugin"],
95
- };
96
- await writeFile(geminiConfigFile, JSON.stringify(config, null, 2));
97
-
98
- // Local workspace config (.agents/mcp_config.json) if in project
99
- const cwd = process.cwd();
100
- if (existsSync(join(cwd, ".agents")) || existsSync(join(cwd, "package.json")) || existsSync(join(cwd, ".git"))) {
101
- const localAgentsDir = join(cwd, ".agents");
102
- await mkdir(localAgentsDir, { recursive: true });
103
- const localMcpFile = join(localAgentsDir, "mcp_config.json");
104
- let localConfig = {};
105
- if (existsSync(localMcpFile)) {
106
- try {
107
- localConfig = JSON.parse(await readFile(localMcpFile, "utf-8"));
108
- } catch (e) {}
109
- }
110
- if (!localConfig.mcpServers) localConfig.mcpServers = {};
111
- localConfig.mcpServers["memory-agent"] = {
112
- command: "npx",
113
- args: ["-y", "@lotargo/memory_plugin"],
114
- };
115
- await writeFile(localMcpFile, JSON.stringify(localConfig, null, 2));
116
- }
117
-
118
- console.log(" [OK] Antigravity: configured MCP server in ~/.gemini/config/mcp_config.json and .agents/mcp_config.json");
119
- configuredCount++;
120
- } catch (err) {
121
- console.log(" [SKIP] Antigravity setup skipped:", err.message);
122
- }
123
- }
124
-
125
- // 4. Codex (~/.codex/config.toml)
126
- if (doCodex) {
127
- try {
128
- const codexDir = join(home, ".codex");
129
- const codexConfig = join(codexDir, "config.toml");
130
- if (existsSync(codexDir)) {
131
- let content = existsSync(codexConfig) ? await readFile(codexConfig, "utf-8") : "";
132
- if (!content.includes("memory-agent")) {
133
- const tomlSnippet = `\n[mcp_servers.memory-agent]\ncommand = "npx"\nargs = ["-y", "@lotargo/memory_plugin"]\n`;
134
- content += tomlSnippet;
135
- await writeFile(codexConfig, content);
136
- console.log(" [OK] Codex: added mcp_servers.memory-agent to ~/.codex/config.toml");
137
- configuredCount++;
138
- } else {
139
- console.log(" [INFO] Codex: already configured");
140
- }
141
- }
142
- } catch (err) {
143
- console.log(" [SKIP] Codex setup skipped:", err.message);
144
- }
145
- }
146
-
147
- console.log(`\nSetup complete. Configured ${configuredCount} environment(s).\n`);
148
- }
1
+ import { readFile, writeFile, mkdir } from "fs/promises";
2
+ import { existsSync } from "fs";
3
+ import { join } from "path";
4
+ import { homedir } from "os";
5
+
6
+ export async function runSetup() {
7
+ const args = process.argv.slice(2);
8
+ const hasSpecificFlag = args.some((a) =>
9
+ ["--opencode", "--claude", "--codex", "--antigravity", "--gemini"].includes(a.toLowerCase())
10
+ );
11
+
12
+ const doOpenCode = !hasSpecificFlag || args.includes("--opencode");
13
+ const doClaude = !hasSpecificFlag || args.includes("--claude");
14
+ const doAntigravity = !hasSpecificFlag || args.includes("--antigravity") || args.includes("--gemini");
15
+ const doCodex = !hasSpecificFlag || args.includes("--codex");
16
+
17
+ console.log("\nSetting up @lotargo/memory_plugin...\n");
18
+ const home = homedir();
19
+ let configuredCount = 0;
20
+
21
+ // 1. OpenCode (~/.config/opencode/opencode.json)
22
+ if (doOpenCode) {
23
+ try {
24
+ const opencodeDir = process.env.OPENCODE_CONFIG_DIR || join(home, ".config", "opencode");
25
+ const opencodeConfigPath = join(opencodeDir, "opencode.json");
26
+ await mkdir(opencodeDir, { recursive: true });
27
+
28
+ let config = {};
29
+ if (existsSync(opencodeConfigPath)) {
30
+ try {
31
+ config = JSON.parse(await readFile(opencodeConfigPath, "utf-8"));
32
+ } catch (e) {}
33
+ }
34
+ if (!Array.isArray(config.plugin)) config.plugin = [];
35
+ // Clean up legacy / incorrect plugin entry names
36
+ const obsoleteNames = ["opencode-memory-plugin", "memory_plugin", "memory-plugin"];
37
+ config.plugin = config.plugin.filter((p) => !obsoleteNames.includes(p));
38
+ if (!config.plugin.includes("@lotargo/memory_plugin")) {
39
+ config.plugin.push("@lotargo/memory_plugin");
40
+ }
41
+ // Clean up legacy mcp-helper.js standalone file plugin if present
42
+ const legacyPluginFile = join(opencodeDir, "plugins", "mcp-helper.js");
43
+ if (existsSync(legacyPluginFile)) {
44
+ try { const { unlink } = await import("fs/promises"); await unlink(legacyPluginFile); } catch (e) {}
45
+ }
46
+ await writeFile(opencodeConfigPath, JSON.stringify(config, null, 2));
47
+ console.log(" [OK] OpenCode: configured plugin in ~/.config/opencode/opencode.json");
48
+ configuredCount++;
49
+ } catch (err) {
50
+ console.log(" [SKIP] OpenCode setup skipped:", err.message);
51
+ }
52
+ }
53
+
54
+ // 2. Claude Code (~/.claude.json)
55
+ if (doClaude) {
56
+ try {
57
+ const claudePath = join(home, ".claude.json");
58
+ let config = {};
59
+ if (existsSync(claudePath)) {
60
+ try {
61
+ config = JSON.parse(await readFile(claudePath, "utf-8"));
62
+ } catch (e) {}
63
+ }
64
+ if (!config.mcpServers) config.mcpServers = {};
65
+ config.mcpServers["memory-agent"] = {
66
+ command: "npx",
67
+ args: ["-y", "@lotargo/memory_plugin"],
68
+ };
69
+ await writeFile(claudePath, JSON.stringify(config, null, 2));
70
+ console.log(" [OK] Claude Code: configured MCP server in ~/.claude.json");
71
+ configuredCount++;
72
+ } catch (err) {
73
+ console.log(" [SKIP] Claude Code setup skipped:", err.message);
74
+ }
75
+ }
76
+
77
+ // 3. Antigravity / Gemini CLI (~/.gemini/config/mcp_config.json & .agents/mcp_config.json)
78
+ if (doAntigravity) {
79
+ try {
80
+ // Global Antigravity config
81
+ const geminiConfigDir = join(home, ".gemini", "config");
82
+ await mkdir(geminiConfigDir, { recursive: true });
83
+ const geminiConfigFile = join(geminiConfigDir, "mcp_config.json");
84
+
85
+ let config = {};
86
+ if (existsSync(geminiConfigFile)) {
87
+ try {
88
+ config = JSON.parse(await readFile(geminiConfigFile, "utf-8"));
89
+ } catch (e) {}
90
+ }
91
+ if (!config.mcpServers) config.mcpServers = {};
92
+ config.mcpServers["memory-agent"] = {
93
+ command: "npx",
94
+ args: ["-y", "@lotargo/memory_plugin"],
95
+ };
96
+ await writeFile(geminiConfigFile, JSON.stringify(config, null, 2));
97
+
98
+ // Local workspace config (.agents/mcp_config.json) if in project
99
+ const cwd = process.cwd();
100
+ if (existsSync(join(cwd, ".agents")) || existsSync(join(cwd, "package.json")) || existsSync(join(cwd, ".git"))) {
101
+ const localAgentsDir = join(cwd, ".agents");
102
+ await mkdir(localAgentsDir, { recursive: true });
103
+ const localMcpFile = join(localAgentsDir, "mcp_config.json");
104
+ let localConfig = {};
105
+ if (existsSync(localMcpFile)) {
106
+ try {
107
+ localConfig = JSON.parse(await readFile(localMcpFile, "utf-8"));
108
+ } catch (e) {}
109
+ }
110
+ if (!localConfig.mcpServers) localConfig.mcpServers = {};
111
+ localConfig.mcpServers["memory-agent"] = {
112
+ command: "npx",
113
+ args: ["-y", "@lotargo/memory_plugin"],
114
+ };
115
+ await writeFile(localMcpFile, JSON.stringify(localConfig, null, 2));
116
+ }
117
+
118
+ console.log(" [OK] Antigravity: configured MCP server in ~/.gemini/config/mcp_config.json and .agents/mcp_config.json");
119
+ configuredCount++;
120
+ } catch (err) {
121
+ console.log(" [SKIP] Antigravity setup skipped:", err.message);
122
+ }
123
+ }
124
+
125
+ // 4. Codex (~/.codex/config.toml)
126
+ if (doCodex) {
127
+ try {
128
+ const codexDir = join(home, ".codex");
129
+ const codexConfig = join(codexDir, "config.toml");
130
+ if (existsSync(codexDir)) {
131
+ let content = existsSync(codexConfig) ? await readFile(codexConfig, "utf-8") : "";
132
+ if (!content.includes("memory-agent")) {
133
+ const tomlSnippet = `\n[mcp_servers.memory-agent]\ncommand = "npx"\nargs = ["-y", "@lotargo/memory_plugin"]\n`;
134
+ content += tomlSnippet;
135
+ await writeFile(codexConfig, content);
136
+ console.log(" [OK] Codex: added mcp_servers.memory-agent to ~/.codex/config.toml");
137
+ configuredCount++;
138
+ } else {
139
+ console.log(" [INFO] Codex: already configured");
140
+ }
141
+ }
142
+ } catch (err) {
143
+ console.log(" [SKIP] Codex setup skipped:", err.message);
144
+ }
145
+ }
146
+
147
+ console.log(`\nSetup complete. Configured ${configuredCount} environment(s).\n`);
148
+ }
@@ -1,62 +1,62 @@
1
- import { createHash } from "node:crypto";
2
- import { gzipSync, gunzipSync } from "node:zlib";
3
- import { readFile, writeFile, mkdir, unlink, access } from "node:fs/promises";
4
- import { existsSync } from "node:fs";
5
- import { join } from "node:path";
6
- import { BLOBS_DIR } from "../db/database.js";
7
-
8
- export function hashContent(data) {
9
- const hash = createHash("sha256");
10
- hash.update(data);
11
- return hash.digest("hex");
12
- }
13
-
14
- export function getBlobPath(hash, baseDir = BLOBS_DIR) {
15
- const prefix = hash.substring(0, 2);
16
- return join(baseDir, prefix, `${hash}.raw.gz`);
17
- }
18
-
19
- export async function blobExists(hash, baseDir = BLOBS_DIR) {
20
- const blobPath = getBlobPath(hash, baseDir);
21
- return existsSync(blobPath);
22
- }
23
-
24
- export async function saveBlob(content, baseDir = BLOBS_DIR) {
25
- const buffer = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
26
- const hash = hashContent(buffer);
27
- const blobPath = getBlobPath(hash, baseDir);
28
-
29
- if (existsSync(blobPath)) {
30
- return { hash, size: buffer.length, path: blobPath, deduplicated: true };
31
- }
32
-
33
- const parentDir = join(blobPath, "..");
34
- if (!existsSync(parentDir)) {
35
- await mkdir(parentDir, { recursive: true });
36
- }
37
-
38
- const compressed = gzipSync(buffer);
39
- await writeFile(blobPath, compressed);
40
-
41
- return { hash, size: buffer.length, path: blobPath, deduplicated: false };
42
- }
43
-
44
- export async function readBlob(hash, baseDir = BLOBS_DIR) {
45
- const blobPath = getBlobPath(hash, baseDir);
46
- if (!existsSync(blobPath)) {
47
- throw new Error(`Blob not found for hash: ${hash}`);
48
- }
49
-
50
- const compressed = await readFile(blobPath);
51
- const decompressed = gunzipSync(compressed);
52
- return decompressed.toString("utf-8");
53
- }
54
-
55
- export async function deleteBlob(hash, baseDir = BLOBS_DIR) {
56
- const blobPath = getBlobPath(hash, baseDir);
57
- if (existsSync(blobPath)) {
58
- await unlink(blobPath);
59
- return true;
60
- }
61
- return false;
62
- }
1
+ import { createHash } from "node:crypto";
2
+ import { gzipSync, gunzipSync } from "node:zlib";
3
+ import { readFile, writeFile, mkdir, unlink, access } from "node:fs/promises";
4
+ import { existsSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { BLOBS_DIR } from "../db/database.js";
7
+
8
+ export function hashContent(data) {
9
+ const hash = createHash("sha256");
10
+ hash.update(data);
11
+ return hash.digest("hex");
12
+ }
13
+
14
+ export function getBlobPath(hash, baseDir = BLOBS_DIR) {
15
+ const prefix = hash.substring(0, 2);
16
+ return join(baseDir, prefix, `${hash}.raw.gz`);
17
+ }
18
+
19
+ export async function blobExists(hash, baseDir = BLOBS_DIR) {
20
+ const blobPath = getBlobPath(hash, baseDir);
21
+ return existsSync(blobPath);
22
+ }
23
+
24
+ export async function saveBlob(content, baseDir = BLOBS_DIR) {
25
+ const buffer = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
26
+ const hash = hashContent(buffer);
27
+ const blobPath = getBlobPath(hash, baseDir);
28
+
29
+ if (existsSync(blobPath)) {
30
+ return { hash, size: buffer.length, path: blobPath, deduplicated: true };
31
+ }
32
+
33
+ const parentDir = join(blobPath, "..");
34
+ if (!existsSync(parentDir)) {
35
+ await mkdir(parentDir, { recursive: true });
36
+ }
37
+
38
+ const compressed = gzipSync(buffer);
39
+ await writeFile(blobPath, compressed);
40
+
41
+ return { hash, size: buffer.length, path: blobPath, deduplicated: false };
42
+ }
43
+
44
+ export async function readBlob(hash, baseDir = BLOBS_DIR) {
45
+ const blobPath = getBlobPath(hash, baseDir);
46
+ if (!existsSync(blobPath)) {
47
+ throw new Error(`Blob not found for hash: ${hash}`);
48
+ }
49
+
50
+ const compressed = await readFile(blobPath);
51
+ const decompressed = gunzipSync(compressed);
52
+ return decompressed.toString("utf-8");
53
+ }
54
+
55
+ export async function deleteBlob(hash, baseDir = BLOBS_DIR) {
56
+ const blobPath = getBlobPath(hash, baseDir);
57
+ if (existsSync(blobPath)) {
58
+ await unlink(blobPath);
59
+ return true;
60
+ }
61
+ return false;
62
+ }