@strvmarv/total-recall 0.1.5 → 0.2.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.
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "name": "total-recall",
3
3
  "description": "Multi-tiered memory and knowledge base with semantic search, auto-compaction, and built-in evaluation. Works across Claude Code, Copilot CLI, OpenCode, Cline, and Cursor.",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "author": {
6
6
  "name": "strvmarv"
7
7
  },
8
- "skills": "./skills/",
9
- "agents": "./agents/",
10
- "hooks": "./hooks/hooks.json",
11
- "mcpServers": {
12
- "total-recall": {
13
- "command": "npx",
14
- "args": ["-y", "@strvmarv/total-recall"]
15
- }
16
- }
8
+ "homepage": "https://github.com/strvmarv/total-recall",
9
+ "repository": "https://github.com/strvmarv/total-recall",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "memory",
13
+ "knowledge-base",
14
+ "mcp",
15
+ "vector-search",
16
+ "sqlite",
17
+ "embeddings"
18
+ ]
17
19
  }
package/.mcp.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "total-recall": {
4
+ "command": "bash",
5
+ "args": ["bin/total-recall.sh"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bash
2
+ # total-recall MCP server launcher
3
+ # Finds node in common locations even when not in PATH
4
+
5
+ find_node() {
6
+ # Check PATH first
7
+ if command -v node &>/dev/null; then
8
+ echo "node"
9
+ return 0
10
+ fi
11
+
12
+ # Check nvm
13
+ if [ -d "$HOME/.nvm/versions/node" ]; then
14
+ local latest=$(ls -1d "$HOME/.nvm/versions/node"/v* 2>/dev/null | sort -V | tail -1)
15
+ if [ -n "$latest" ] && [ -x "$latest/bin/node" ]; then
16
+ echo "$latest/bin/node"
17
+ return 0
18
+ fi
19
+ fi
20
+
21
+ # Check fnm
22
+ if [ -d "$HOME/.local/share/fnm/node-versions" ]; then
23
+ local latest=$(ls -1d "$HOME/.local/share/fnm/node-versions"/v*/installation 2>/dev/null | sort -V | tail -1)
24
+ if [ -n "$latest" ] && [ -x "$latest/bin/node" ]; then
25
+ echo "$latest/bin/node"
26
+ return 0
27
+ fi
28
+ fi
29
+
30
+ # Check Homebrew
31
+ if [ -x "/home/linuxbrew/.linuxbrew/bin/node" ]; then
32
+ echo "/home/linuxbrew/.linuxbrew/bin/node"
33
+ return 0
34
+ fi
35
+ if [ -x "/opt/homebrew/bin/node" ]; then
36
+ echo "/opt/homebrew/bin/node"
37
+ return 0
38
+ fi
39
+ if [ -x "/usr/local/bin/node" ]; then
40
+ echo "/usr/local/bin/node"
41
+ return 0
42
+ fi
43
+
44
+ # Check Volta
45
+ if [ -x "$HOME/.volta/bin/node" ]; then
46
+ echo "$HOME/.volta/bin/node"
47
+ return 0
48
+ fi
49
+
50
+ echo ""
51
+ return 1
52
+ }
53
+
54
+ NODE=$(find_node)
55
+ if [ -z "$NODE" ]; then
56
+ echo "total-recall: error: node.js not found. Install Node.js 20+ via nvm, fnm, Volta, or your package manager." >&2
57
+ exit 1
58
+ fi
59
+
60
+ # Find the package entry point
61
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
62
+ PACKAGE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
63
+ ENTRY="$PACKAGE_DIR/dist/index.js"
64
+
65
+ # Strategy 1: Local dist/index.js (source install or npm install)
66
+ if [ -f "$ENTRY" ]; then
67
+ exec "$NODE" "$ENTRY" "$@"
68
+ fi
69
+
70
+ # Strategy 2: Global install (npm install -g @strvmarv/total-recall)
71
+ if command -v total-recall &>/dev/null; then
72
+ exec total-recall "$@"
73
+ fi
74
+
75
+ # Strategy 3: Find entry point in global node_modules
76
+ NODE_DIR="$(dirname "$NODE")"
77
+ GLOBAL_ENTRY=$("$NODE_DIR/npm" root -g 2>/dev/null)/@strvmarv/total-recall/dist/index.js
78
+ if [ -f "$GLOBAL_ENTRY" ]; then
79
+ exec "$NODE" "$GLOBAL_ENTRY" "$@"
80
+ fi
81
+
82
+ echo "total-recall: error: could not find dist/index.js or total-recall binary." >&2
83
+ echo " Run 'npm run build' (git clone) or 'npm install -g @strvmarv/total-recall'." >&2
84
+ exit 1
@@ -0,0 +1,28 @@
1
+ # total-recall default configuration
2
+ # Copy to ~/.total-recall/config.toml to override
3
+
4
+ [tiers.hot]
5
+ max_entries = 50
6
+ token_budget = 4000
7
+ carry_forward_threshold = 0.7
8
+
9
+ [tiers.warm]
10
+ max_entries = 10000
11
+ retrieval_top_k = 5
12
+ similarity_threshold = 0.65
13
+ cold_decay_days = 30
14
+
15
+ [tiers.cold]
16
+ chunk_max_tokens = 512
17
+ chunk_overlap_tokens = 50
18
+ lazy_summary_threshold = 5
19
+
20
+ [compaction]
21
+ decay_half_life_hours = 168
22
+ warm_threshold = 0.3
23
+ promote_threshold = 0.7
24
+ warm_sweep_interval_days = 7
25
+
26
+ [embedding]
27
+ model = "all-MiniLM-L6-v2"
28
+ dimensions = 384
package/dist/index.js CHANGED
@@ -228,9 +228,18 @@ import { writeFile } from "fs/promises";
228
228
  import { join as join3 } from "path";
229
229
  var HF_BASE_URL = "https://huggingface.co";
230
230
  var HF_REVISION = "main";
231
- function getModelPath(modelName) {
231
+ function getBundledModelPath(modelName) {
232
+ const distDir = new URL(".", import.meta.url).pathname;
233
+ return join3(distDir, "..", "models", modelName);
234
+ }
235
+ function getUserModelPath(modelName) {
232
236
  return join3(getDataDir(), "models", modelName);
233
237
  }
238
+ function getModelPath(modelName) {
239
+ const bundled = getBundledModelPath(modelName);
240
+ if (isModelDownloaded(bundled)) return bundled;
241
+ return getUserModelPath(modelName);
242
+ }
234
243
  function isModelDownloaded(modelPath) {
235
244
  if (!existsSync3(modelPath)) return false;
236
245
  try {
@@ -253,12 +262,23 @@ async function validateDownload(modelPath) {
253
262
  }
254
263
  }
255
264
  async function downloadModel(modelName) {
256
- const modelPath = getModelPath(modelName);
265
+ const modelPath = getUserModelPath(modelName);
257
266
  mkdirSync2(modelPath, { recursive: true });
258
- const files = ["model.onnx", "tokenizer.json", "tokenizer_config.json"];
259
- const repoUrl = `${HF_BASE_URL}/sentence-transformers/${modelName}/resolve/${HF_REVISION}/onnx`;
260
- for (const file of files) {
261
- const url = `${repoUrl}/${file}`;
267
+ const fileUrls = [
268
+ {
269
+ file: "model.onnx",
270
+ url: `${HF_BASE_URL}/sentence-transformers/${modelName}/resolve/${HF_REVISION}/onnx/model.onnx`
271
+ },
272
+ {
273
+ file: "tokenizer.json",
274
+ url: `${HF_BASE_URL}/sentence-transformers/${modelName}/resolve/${HF_REVISION}/tokenizer.json`
275
+ },
276
+ {
277
+ file: "tokenizer_config.json",
278
+ url: `${HF_BASE_URL}/sentence-transformers/${modelName}/resolve/${HF_REVISION}/tokenizer_config.json`
279
+ }
280
+ ];
281
+ for (const { file, url } of fileUrls) {
262
282
  const dest = join3(modelPath, file);
263
283
  const response = await fetch(url);
264
284
  if (!response.ok) {
@@ -0,0 +1,3 @@
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6fd5d72fe4589f189f8ebc006442dbb529bb7ce38f8082112682524616046452
3
+ size 90405214