toon-memory 1.6.3 → 1.6.5

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/dist/cli/setup.js CHANGED
@@ -1,20 +1,12 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdirSync, statSync } from "fs";
2
2
  import { basename, dirname, join } from "path";
3
3
  import { fileURLToPath } from "url";
4
- import { execSync } from "child_process";
5
4
  import { createInterface } from "readline";
6
- import { createRequire } from "module";
7
5
  import { gzipSync, gunzipSync } from "zlib";
8
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
9
7
  const projectRoot = process.cwd();
10
8
  const sourceDir = join(__dirname, "..", "..", "src");
11
9
  const HOME = process.env.HOME || process.env.USERPROFILE || "~";
12
- try {
13
- createRequire(import.meta.url).resolve("@toon-format/toon");
14
- } catch {
15
- console.log("Installing @toon-format/toon...");
16
- execSync("npm install @toon-format/toon", { cwd: projectRoot, stdio: "inherit" });
17
- }
18
10
  function detectAgents() {
19
11
  const agents2 = [];
20
12
  const opencodeGlobal = join(HOME, ".config", "opencode", "opencode.json");
@@ -206,16 +198,16 @@ function status() {
206
198
  function upgrade() {
207
199
  console.log("\n\u{1F9E0} toon-memory upgrade\n");
208
200
  try {
209
- console.log("Checking for updates...");
210
- const latest = execSync("npm view toon-memory version", { encoding: "utf-8" }).trim();
211
- console.log(`Latest version: ${latest}`);
212
- console.log("Upgrading...");
213
- execSync("npm install -g toon-memory@" + latest, { stdio: "inherit" });
214
- console.log(`
215
- \u2705 Upgraded to toon-memory@${latest}`);
216
- console.log("Restart your agent to use the new version.\n");
217
- } catch (error) {
218
- console.error("Upgrade failed:", error.message);
201
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
202
+ const currentVersion = pkg.version;
203
+ console.log(`Current version: ${currentVersion}`);
204
+ console.log("\nTo upgrade, run:");
205
+ console.log(" npm install -g toon-memory@latest");
206
+ console.log("\nThen restart your agent.\n");
207
+ } catch {
208
+ console.log("To upgrade, run:");
209
+ console.log(" npm install -g toon-memory@latest");
210
+ console.log("\nThen restart your agent.\n");
219
211
  }
220
212
  }
221
213
  function stats() {
package/mcp/server.js CHANGED
@@ -27793,7 +27793,7 @@ server.registerTool(
27793
27793
  },
27794
27794
  async ({ category, key, content, file: file2, tags }) => {
27795
27795
  const data = readMemory();
27796
- const id = generateId();
27796
+ const newId = generateId();
27797
27797
  const date5 = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
27798
27798
  const lines = data.split("\n");
27799
27799
  let headerIdx = lines.findIndex((l) => l.startsWith("entries[") || /^\[\d+\|]/.test(l));
@@ -27802,6 +27802,7 @@ server.registerTool(
27802
27802
  headerIdx = lines.length - 1;
27803
27803
  }
27804
27804
  let existingIdx = -1;
27805
+ let existingId = newId;
27805
27806
  for (let i = headerIdx + 1; i < lines.length; i++) {
27806
27807
  const line = lines[i];
27807
27808
  if (!line.startsWith(" ") || !line.includes("|")) continue;
@@ -27809,10 +27810,12 @@ server.registerTool(
27809
27810
  const parts = line.trim().split("|");
27810
27811
  if (parts[2] === key) {
27811
27812
  existingIdx = i;
27813
+ existingId = parts[0];
27812
27814
  break;
27813
27815
  }
27814
27816
  }
27815
- const newEntry = `${id}|${category}|${key}|${content}|${file2 || ""}|${tags || ""}|${date5}`;
27817
+ const entryId = existingIdx !== -1 ? existingId : newId;
27818
+ const newEntry = `${entryId}|${category}|${key}|${content}|${file2 || ""}|${tags || ""}|${date5}`;
27816
27819
  let action = "Guardado";
27817
27820
  if (existingIdx !== -1) {
27818
27821
  lines[existingIdx] = ` ${newEntry}`;
@@ -27825,7 +27828,7 @@ server.registerTool(
27825
27828
  }
27826
27829
  writeMemory(lines.join("\n"));
27827
27830
  return {
27828
- content: [{ type: "text", text: `\u{1F9E0} ${action}: ${category}/${key} (${id})
27831
+ content: [{ type: "text", text: `\u{1F9E0} ${action}: ${category}/${key} (${entryId})
27829
27832
  ${content}` }]
27830
27833
  };
27831
27834
  }
@@ -27845,7 +27848,8 @@ server.registerTool(
27845
27848
  async ({ query, category, from_date, to_date }) => {
27846
27849
  const data = readMemory();
27847
27850
  const lines = data.split("\n").filter((l) => l.startsWith(" ") && l.includes("|") && !l.startsWith("summaries:"));
27848
- const queryLower = query.toLowerCase();
27851
+ const normalize = (s) => s.toLowerCase().replace(/[-_]/g, " ").replace(/\s+/g, " ").trim();
27852
+ const queryTokens = normalize(query).split(" ").filter(Boolean);
27849
27853
  const results = lines.map((line) => {
27850
27854
  const trimmed = line.trim();
27851
27855
  const parts = trimmed.split("|");
@@ -27854,8 +27858,8 @@ server.registerTool(
27854
27858
  if (category && cat !== category) return null;
27855
27859
  if (from_date && date5 < from_date) return null;
27856
27860
  if (to_date && date5 > to_date) return null;
27857
- const searchStr = `${id} ${cat} ${key} ${content} ${file2} ${tags}`.toLowerCase();
27858
- if (!searchStr.includes(queryLower)) return null;
27861
+ const searchStr = normalize(`${id} ${cat} ${key} ${content} ${file2} ${tags}`);
27862
+ if (!queryTokens.every((token) => searchStr.includes(token))) return null;
27859
27863
  return { id, cat, key, content, file: file2, tags, date: date5 };
27860
27864
  }).filter(Boolean);
27861
27865
  if (results.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toon-memory",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
4
4
  "description": "Persistent memory system for AI coding agents using TOON format (40% fewer tokens than JSON)",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli/setup.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync, cpSync, unlinkSync, readdirSync, statSync } from "fs"
2
2
  import { basename, dirname, join } from "path"
3
3
  import { fileURLToPath } from "url"
4
- import { execSync } from "child_process"
5
4
  import { createInterface } from "readline"
6
- import { createRequire } from "module"
7
5
  import { gzipSync, gunzipSync } from "zlib"
8
6
 
9
7
  const __dirname = dirname(fileURLToPath(import.meta.url))
@@ -25,14 +23,6 @@ interface Agent {
25
23
  mcpKey: string
26
24
  }
27
25
 
28
- // Auto-install @toon-format/toon if not present
29
- try {
30
- createRequire(import.meta.url).resolve("@toon-format/toon")
31
- } catch {
32
- console.log("Installing @toon-format/toon...")
33
- execSync("npm install @toon-format/toon", { cwd: projectRoot, stdio: "inherit" })
34
- }
35
-
36
26
  /**
37
27
  * Detect all supported AI coding agents on the system.
38
28
  *
@@ -375,17 +365,17 @@ function upgrade(): void {
375
365
  console.log("\n🧠 toon-memory upgrade\n")
376
366
 
377
367
  try {
378
- console.log("Checking for updates...")
379
- const latest = execSync("npm view toon-memory version", { encoding: "utf-8" }).trim()
380
- console.log(`Latest version: ${latest}`)
381
-
382
- console.log("Upgrading...")
383
- execSync("npm install -g toon-memory@" + latest, { stdio: "inherit" })
368
+ const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"))
369
+ const currentVersion = pkg.version
384
370
 
385
- console.log(`\n✅ Upgraded to toon-memory@${latest}`)
386
- console.log("Restart your agent to use the new version.\n")
387
- } catch (error) {
388
- console.error("Upgrade failed:", (error as Error).message)
371
+ console.log(`Current version: ${currentVersion}`)
372
+ console.log("\nTo upgrade, run:")
373
+ console.log(" npm install -g toon-memory@latest")
374
+ console.log("\nThen restart your agent.\n")
375
+ } catch {
376
+ console.log("To upgrade, run:")
377
+ console.log(" npm install -g toon-memory@latest")
378
+ console.log("\nThen restart your agent.\n")
389
379
  }
390
380
  }
391
381
 
package/src/mcp/server.ts CHANGED
@@ -306,7 +306,7 @@ server.registerTool(
306
306
  },
307
307
  async ({ category, key, content, file, tags }) => {
308
308
  const data = readMemory()
309
- const id = generateId()
309
+ const newId = generateId()
310
310
  const date = new Date().toISOString().split("T")[0]
311
311
  const lines = data.split("\n")
312
312
 
@@ -318,6 +318,7 @@ server.registerTool(
318
318
 
319
319
  // Find existing entry with same key (upsert)
320
320
  let existingIdx = -1
321
+ let existingId = newId
321
322
  for (let i = headerIdx + 1; i < lines.length; i++) {
322
323
  const line = lines[i]
323
324
  if (!line.startsWith(" ") || !line.includes("|")) continue
@@ -325,11 +326,13 @@ server.registerTool(
325
326
  const parts = line.trim().split("|")
326
327
  if (parts[2] === key) {
327
328
  existingIdx = i
329
+ existingId = parts[0] // Preserve original ID
328
330
  break
329
331
  }
330
332
  }
331
333
 
332
- const newEntry = `${id}|${category}|${key}|${content}|${file || ""}|${tags || ""}|${date}`
334
+ const entryId = existingIdx !== -1 ? existingId : newId
335
+ const newEntry = `${entryId}|${category}|${key}|${content}|${file || ""}|${tags || ""}|${date}`
333
336
  let action = "Guardado"
334
337
 
335
338
  if (existingIdx !== -1) {
@@ -346,7 +349,7 @@ server.registerTool(
346
349
 
347
350
  writeMemory(lines.join("\n"))
348
351
  return {
349
- content: [{ type: "text" as const, text: `🧠 ${action}: ${category}/${key} (${id})\n${content}` }],
352
+ content: [{ type: "text" as const, text: `🧠 ${action}: ${category}/${key} (${entryId})\n${content}` }],
350
353
  }
351
354
  }
352
355
  )
@@ -377,7 +380,10 @@ server.registerTool(
377
380
  async ({ query, category, from_date, to_date }) => {
378
381
  const data = readMemory()
379
382
  const lines = data.split("\n").filter((l) => l.startsWith(" ") && l.includes("|") && !l.startsWith("summaries:"))
380
- const queryLower = query.toLowerCase()
383
+
384
+ // Normalize for fuzzy matching: hyphens/underscores → spaces, collapse whitespace
385
+ const normalize = (s: string) => s.toLowerCase().replace(/[-_]/g, " ").replace(/\s+/g, " ").trim()
386
+ const queryTokens = normalize(query).split(" ").filter(Boolean)
381
387
 
382
388
  const results = lines
383
389
  .map((line) => {
@@ -388,8 +394,9 @@ server.registerTool(
388
394
  if (category && cat !== category) return null
389
395
  if (from_date && date < from_date) return null
390
396
  if (to_date && date > to_date) return null
391
- const searchStr = `${id} ${cat} ${key} ${content} ${file} ${tags}`.toLowerCase()
392
- if (!searchStr.includes(queryLower)) return null
397
+ const searchStr = normalize(`${id} ${cat} ${key} ${content} ${file} ${tags}`)
398
+ // All query tokens must match (AND logic)
399
+ if (!queryTokens.every((token) => searchStr.includes(token))) return null
393
400
  return { id, cat, key, content, file, tags, date }
394
401
  })
395
402
  .filter(Boolean)
package/uninstall.sh CHANGED
@@ -4,59 +4,41 @@ set -e
4
4
  # toon-memory uninstaller
5
5
  # Usage: npx toon-memory uninstall
6
6
 
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+
7
9
  echo "🧠 toon-memory uninstaller"
8
10
  echo ""
9
11
 
10
- # Remove from OpenCode
11
- OPENCODE_GLOBAL="${HOME}/.config/opencode/opencode.json"
12
- OPENCODE_LOCAL=".opencode/opencode.json"
13
-
12
+ # Helper: remove toon-memory from a config file
14
13
  remove_from_config() {
15
14
  local file="$1"
16
- local name="$2"
17
-
18
15
  if [ -f "${file}" ]; then
19
- if grep -q "toon-memory" "${file}" 2>/dev/null; then
20
- echo "Removing from ${name} (${file})..."
21
- # Use node to remove the MCP entry
22
- node -e "
23
- const fs = require('fs');
24
- const config = JSON.parse(fs.readFileSync('${file}', 'utf-8'));
25
- if (config.mcp && config.mcp['toon-memory']) {
26
- delete config.mcp['toon-memory'];
27
- fs.writeFileSync('${file}', JSON.stringify(config, null, 2));
28
- console.log(' ✅ Removed');
29
- } else if (config.mcpServers && config.mcpServers['toon-memory']) {
30
- delete config.mcpServers['toon-memory'];
31
- fs.writeFileSync('${file}', JSON.stringify(config, null, 2));
32
- console.log(' ✅ Removed');
33
- } else {
34
- console.log(' ⚠️ Not found');
35
- }
36
- " 2>/dev/null || echo " ⚠️ Could not parse config"
37
- fi
16
+ node "${SCRIPT_DIR}/scripts/remove-mcp.js" "${file}"
38
17
  fi
39
18
  }
40
19
 
41
20
  # OpenCode
42
- remove_from_config "${OPENCODE_GLOBAL}" "OpenCode (global)"
43
- remove_from_config "${OPENCODE_LOCAL}" "OpenCode (local)"
21
+ remove_from_config "${HOME}/.config/opencode/opencode.json"
22
+ remove_from_config ".opencode/opencode.json"
44
23
 
45
24
  # VS Code
46
- remove_from_config ".vscode/mcp.json" "VS Code"
25
+ remove_from_config ".vscode/mcp.json"
47
26
 
48
27
  # Claude
49
- remove_from_config "${HOME}/.claude/settings.json" "Claude (global)"
50
- remove_from_config ".claude/settings.json" "Claude (local)"
28
+ remove_from_config "${HOME}/.claude/settings.json"
29
+ remove_from_config ".claude/settings.json"
51
30
 
52
31
  # Cursor
53
- remove_from_config ".cursor/mcp.json" "Cursor"
32
+ remove_from_config ".cursor/mcp.json"
33
+
34
+ # Windsurf
35
+ remove_from_config "${HOME}/.codeium/windsurf/mcp_config.json"
54
36
 
55
37
  # Cline
56
- remove_from_config ".cline/mcp.json" "Cline"
38
+ remove_from_config ".cline/mcp.json"
57
39
 
58
40
  # Continue
59
- remove_from_config ".continue/config.json" "Continue"
41
+ remove_from_config ".continue/config.json"
60
42
 
61
43
  # Remove custom tools if they exist
62
44
  if [ -d ".opencode/tools" ]; then