superlocalmemory 2.3.0
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/ATTRIBUTION.md +140 -0
- package/CHANGELOG.md +1749 -0
- package/LICENSE +21 -0
- package/README.md +600 -0
- package/bin/aider-smart +72 -0
- package/bin/slm +202 -0
- package/bin/slm-npm +73 -0
- package/bin/slm.bat +195 -0
- package/bin/slm.cmd +10 -0
- package/bin/superlocalmemoryv2:list +3 -0
- package/bin/superlocalmemoryv2:profile +3 -0
- package/bin/superlocalmemoryv2:recall +3 -0
- package/bin/superlocalmemoryv2:remember +3 -0
- package/bin/superlocalmemoryv2:reset +3 -0
- package/bin/superlocalmemoryv2:status +3 -0
- package/completions/slm.bash +58 -0
- package/completions/slm.zsh +76 -0
- package/configs/antigravity-mcp.json +13 -0
- package/configs/chatgpt-desktop-mcp.json +7 -0
- package/configs/claude-desktop-mcp.json +15 -0
- package/configs/codex-mcp.toml +13 -0
- package/configs/cody-commands.json +29 -0
- package/configs/continue-mcp.yaml +14 -0
- package/configs/continue-skills.yaml +26 -0
- package/configs/cursor-mcp.json +15 -0
- package/configs/gemini-cli-mcp.json +11 -0
- package/configs/jetbrains-mcp.json +11 -0
- package/configs/opencode-mcp.json +12 -0
- package/configs/perplexity-mcp.json +9 -0
- package/configs/vscode-copilot-mcp.json +12 -0
- package/configs/windsurf-mcp.json +16 -0
- package/configs/zed-mcp.json +12 -0
- package/docs/ARCHITECTURE.md +877 -0
- package/docs/CLI-COMMANDS-REFERENCE.md +425 -0
- package/docs/COMPETITIVE-ANALYSIS.md +210 -0
- package/docs/COMPRESSION-README.md +390 -0
- package/docs/GRAPH-ENGINE.md +503 -0
- package/docs/MCP-MANUAL-SETUP.md +720 -0
- package/docs/MCP-TROUBLESHOOTING.md +787 -0
- package/docs/PATTERN-LEARNING.md +363 -0
- package/docs/PROFILES-GUIDE.md +453 -0
- package/docs/RESET-GUIDE.md +353 -0
- package/docs/SEARCH-ENGINE-V2.2.0.md +748 -0
- package/docs/SEARCH-INTEGRATION-GUIDE.md +502 -0
- package/docs/UI-SERVER.md +254 -0
- package/docs/UNIVERSAL-INTEGRATION.md +432 -0
- package/docs/V2.2.0-OPTIONAL-SEARCH.md +666 -0
- package/docs/WINDOWS-INSTALL-README.txt +34 -0
- package/docs/WINDOWS-POST-INSTALL.txt +45 -0
- package/docs/example_graph_usage.py +148 -0
- package/hooks/memory-list-skill.js +130 -0
- package/hooks/memory-profile-skill.js +284 -0
- package/hooks/memory-recall-skill.js +109 -0
- package/hooks/memory-remember-skill.js +127 -0
- package/hooks/memory-reset-skill.js +274 -0
- package/install-skills.sh +436 -0
- package/install.ps1 +417 -0
- package/install.sh +755 -0
- package/mcp_server.py +585 -0
- package/package.json +94 -0
- package/requirements-core.txt +24 -0
- package/requirements.txt +10 -0
- package/scripts/postinstall.js +126 -0
- package/scripts/preuninstall.js +57 -0
- package/skills/slm-build-graph/SKILL.md +423 -0
- package/skills/slm-list-recent/SKILL.md +348 -0
- package/skills/slm-recall/SKILL.md +325 -0
- package/skills/slm-remember/SKILL.md +194 -0
- package/skills/slm-status/SKILL.md +363 -0
- package/skills/slm-switch-profile/SKILL.md +442 -0
- package/src/__pycache__/cache_manager.cpython-312.pyc +0 -0
- package/src/__pycache__/embedding_engine.cpython-312.pyc +0 -0
- package/src/__pycache__/graph_engine.cpython-312.pyc +0 -0
- package/src/__pycache__/hnsw_index.cpython-312.pyc +0 -0
- package/src/__pycache__/hybrid_search.cpython-312.pyc +0 -0
- package/src/__pycache__/memory-profiles.cpython-312.pyc +0 -0
- package/src/__pycache__/memory-reset.cpython-312.pyc +0 -0
- package/src/__pycache__/memory_compression.cpython-312.pyc +0 -0
- package/src/__pycache__/memory_store_v2.cpython-312.pyc +0 -0
- package/src/__pycache__/migrate_v1_to_v2.cpython-312.pyc +0 -0
- package/src/__pycache__/pattern_learner.cpython-312.pyc +0 -0
- package/src/__pycache__/query_optimizer.cpython-312.pyc +0 -0
- package/src/__pycache__/search_engine_v2.cpython-312.pyc +0 -0
- package/src/__pycache__/setup_validator.cpython-312.pyc +0 -0
- package/src/__pycache__/tree_manager.cpython-312.pyc +0 -0
- package/src/cache_manager.py +520 -0
- package/src/embedding_engine.py +671 -0
- package/src/graph_engine.py +970 -0
- package/src/hnsw_index.py +626 -0
- package/src/hybrid_search.py +693 -0
- package/src/memory-profiles.py +518 -0
- package/src/memory-reset.py +485 -0
- package/src/memory_compression.py +999 -0
- package/src/memory_store_v2.py +1088 -0
- package/src/migrate_v1_to_v2.py +638 -0
- package/src/pattern_learner.py +898 -0
- package/src/query_optimizer.py +513 -0
- package/src/search_engine_v2.py +403 -0
- package/src/setup_validator.py +479 -0
- package/src/tree_manager.py +720 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
SuperLocalMemory V2 - Setup Validator
|
|
4
|
+
Copyright (c) 2026 Varun Pratap Bhardwaj
|
|
5
|
+
Licensed under MIT License
|
|
6
|
+
|
|
7
|
+
Repository: https://github.com/varun369/SuperLocalMemoryV2
|
|
8
|
+
Author: Varun Pratap Bhardwaj (Solution Architect)
|
|
9
|
+
|
|
10
|
+
First-run setup validator that ensures all dependencies are installed
|
|
11
|
+
and the database is properly initialized.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
import os
|
|
16
|
+
import sqlite3
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Tuple, List, Optional
|
|
19
|
+
|
|
20
|
+
# Configuration
|
|
21
|
+
MEMORY_DIR = Path(os.environ.get('SUPERLOCALEMORY_DIR', str(Path.home() / ".claude-memory")))
|
|
22
|
+
DB_PATH = MEMORY_DIR / "memory.db"
|
|
23
|
+
|
|
24
|
+
# Required Python version
|
|
25
|
+
MIN_PYTHON_VERSION = (3, 8)
|
|
26
|
+
|
|
27
|
+
# Required tables for V2
|
|
28
|
+
REQUIRED_TABLES = [
|
|
29
|
+
'memories',
|
|
30
|
+
'graph_edges',
|
|
31
|
+
'graph_nodes',
|
|
32
|
+
'graph_clusters',
|
|
33
|
+
'identity_patterns',
|
|
34
|
+
'pattern_examples',
|
|
35
|
+
'memory_tree',
|
|
36
|
+
'memory_archive'
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def print_banner():
|
|
41
|
+
"""Print product banner."""
|
|
42
|
+
print("""
|
|
43
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
44
|
+
║ SuperLocalMemory V2 - Setup Validator ║
|
|
45
|
+
║ by Varun Pratap Bhardwaj ║
|
|
46
|
+
║ https://github.com/varun369/SuperLocalMemoryV2 ║
|
|
47
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
48
|
+
""")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def check_python_version() -> Tuple[bool, str]:
|
|
52
|
+
"""Check Python version meets requirements."""
|
|
53
|
+
current = sys.version_info[:2]
|
|
54
|
+
if current >= MIN_PYTHON_VERSION:
|
|
55
|
+
return True, f"Python {current[0]}.{current[1]}"
|
|
56
|
+
else:
|
|
57
|
+
return False, f"Python {current[0]}.{current[1]} (need {MIN_PYTHON_VERSION[0]}.{MIN_PYTHON_VERSION[1]}+)"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def check_core_dependencies() -> List[Tuple[str, bool, str]]:
|
|
61
|
+
"""Check core required dependencies."""
|
|
62
|
+
results = []
|
|
63
|
+
|
|
64
|
+
# SQLite3 (built-in)
|
|
65
|
+
try:
|
|
66
|
+
import sqlite3
|
|
67
|
+
results.append(("sqlite3", True, "Built-in"))
|
|
68
|
+
except ImportError:
|
|
69
|
+
results.append(("sqlite3", False, "pip install sqlite3"))
|
|
70
|
+
|
|
71
|
+
# JSON (built-in)
|
|
72
|
+
try:
|
|
73
|
+
import json
|
|
74
|
+
results.append(("json", True, "Built-in"))
|
|
75
|
+
except ImportError:
|
|
76
|
+
results.append(("json", False, "Built-in - should be available"))
|
|
77
|
+
|
|
78
|
+
# hashlib (built-in)
|
|
79
|
+
try:
|
|
80
|
+
import hashlib
|
|
81
|
+
results.append(("hashlib", True, "Built-in"))
|
|
82
|
+
except ImportError:
|
|
83
|
+
results.append(("hashlib", False, "Built-in - should be available"))
|
|
84
|
+
|
|
85
|
+
return results
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def check_optional_dependencies() -> List[Tuple[str, bool, str, str]]:
|
|
89
|
+
"""Check optional dependencies for advanced features."""
|
|
90
|
+
results = []
|
|
91
|
+
|
|
92
|
+
# scikit-learn (for knowledge graph)
|
|
93
|
+
try:
|
|
94
|
+
import sklearn
|
|
95
|
+
results.append(("scikit-learn", True, sklearn.__version__, "Knowledge Graph"))
|
|
96
|
+
except ImportError:
|
|
97
|
+
results.append(("scikit-learn", False, "pip install scikit-learn", "Knowledge Graph"))
|
|
98
|
+
|
|
99
|
+
# numpy (for vector operations)
|
|
100
|
+
try:
|
|
101
|
+
import numpy
|
|
102
|
+
results.append(("numpy", True, numpy.__version__, "Vector Operations"))
|
|
103
|
+
except ImportError:
|
|
104
|
+
results.append(("numpy", False, "pip install numpy", "Vector Operations"))
|
|
105
|
+
|
|
106
|
+
# igraph (for clustering)
|
|
107
|
+
try:
|
|
108
|
+
import igraph
|
|
109
|
+
results.append(("python-igraph", True, igraph.__version__, "Graph Clustering"))
|
|
110
|
+
except ImportError:
|
|
111
|
+
results.append(("python-igraph", False, "pip install python-igraph", "Graph Clustering"))
|
|
112
|
+
|
|
113
|
+
# leidenalg (for Leiden algorithm)
|
|
114
|
+
try:
|
|
115
|
+
import leidenalg
|
|
116
|
+
results.append(("leidenalg", True, leidenalg.__version__, "Leiden Clustering"))
|
|
117
|
+
except ImportError:
|
|
118
|
+
results.append(("leidenalg", False, "pip install leidenalg", "Leiden Clustering"))
|
|
119
|
+
|
|
120
|
+
# FastAPI (for UI server)
|
|
121
|
+
try:
|
|
122
|
+
import fastapi
|
|
123
|
+
results.append(("fastapi", True, fastapi.__version__, "UI Server"))
|
|
124
|
+
except ImportError:
|
|
125
|
+
results.append(("fastapi", False, "pip install fastapi uvicorn", "UI Server"))
|
|
126
|
+
|
|
127
|
+
return results
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def check_database() -> Tuple[bool, str, List[str]]:
|
|
131
|
+
"""Check database status and tables."""
|
|
132
|
+
if not DB_PATH.exists():
|
|
133
|
+
return False, "Not created yet (will be created on first use)", []
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
conn = sqlite3.connect(DB_PATH)
|
|
137
|
+
cursor = conn.cursor()
|
|
138
|
+
|
|
139
|
+
# Get existing tables
|
|
140
|
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
|
|
141
|
+
existing_tables = {row[0] for row in cursor.fetchall()}
|
|
142
|
+
|
|
143
|
+
# Check for required tables
|
|
144
|
+
missing_tables = []
|
|
145
|
+
for table in REQUIRED_TABLES:
|
|
146
|
+
if table not in existing_tables:
|
|
147
|
+
missing_tables.append(table)
|
|
148
|
+
|
|
149
|
+
# Get memory count
|
|
150
|
+
try:
|
|
151
|
+
cursor.execute("SELECT COUNT(*) FROM memories")
|
|
152
|
+
memory_count = cursor.fetchone()[0]
|
|
153
|
+
except:
|
|
154
|
+
memory_count = 0
|
|
155
|
+
|
|
156
|
+
conn.close()
|
|
157
|
+
|
|
158
|
+
if missing_tables:
|
|
159
|
+
return False, f"Missing tables: {', '.join(missing_tables)}", missing_tables
|
|
160
|
+
else:
|
|
161
|
+
return True, f"OK ({memory_count} memories)", []
|
|
162
|
+
|
|
163
|
+
except Exception as e:
|
|
164
|
+
return False, f"Error: {str(e)}", []
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def check_directory_structure() -> List[Tuple[str, bool, str]]:
|
|
168
|
+
"""Check required directories exist."""
|
|
169
|
+
results = []
|
|
170
|
+
|
|
171
|
+
# Memory directory
|
|
172
|
+
if MEMORY_DIR.exists():
|
|
173
|
+
results.append(("Memory Directory", True, str(MEMORY_DIR)))
|
|
174
|
+
else:
|
|
175
|
+
results.append(("Memory Directory", False, f"Will be created at {MEMORY_DIR}"))
|
|
176
|
+
|
|
177
|
+
# Profiles directory
|
|
178
|
+
profiles_dir = MEMORY_DIR / "profiles"
|
|
179
|
+
if profiles_dir.exists():
|
|
180
|
+
results.append(("Profiles Directory", True, str(profiles_dir)))
|
|
181
|
+
else:
|
|
182
|
+
results.append(("Profiles Directory", False, "Will be created on first profile"))
|
|
183
|
+
|
|
184
|
+
# Backups directory
|
|
185
|
+
backups_dir = MEMORY_DIR / "backups"
|
|
186
|
+
if backups_dir.exists():
|
|
187
|
+
results.append(("Backups Directory", True, str(backups_dir)))
|
|
188
|
+
else:
|
|
189
|
+
results.append(("Backups Directory", False, "Will be created on first backup"))
|
|
190
|
+
|
|
191
|
+
return results
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def initialize_database() -> Tuple[bool, str]:
|
|
195
|
+
"""Initialize database with required schema if needed."""
|
|
196
|
+
try:
|
|
197
|
+
# Create memory directory if needed
|
|
198
|
+
MEMORY_DIR.mkdir(parents=True, exist_ok=True)
|
|
199
|
+
|
|
200
|
+
conn = sqlite3.connect(DB_PATH)
|
|
201
|
+
cursor = conn.cursor()
|
|
202
|
+
|
|
203
|
+
# Create memories table (core)
|
|
204
|
+
cursor.execute('''
|
|
205
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
206
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
207
|
+
content TEXT NOT NULL,
|
|
208
|
+
summary TEXT,
|
|
209
|
+
project_path TEXT,
|
|
210
|
+
project_name TEXT,
|
|
211
|
+
tags TEXT DEFAULT '[]',
|
|
212
|
+
category TEXT,
|
|
213
|
+
parent_id INTEGER,
|
|
214
|
+
tree_path TEXT DEFAULT '/',
|
|
215
|
+
depth INTEGER DEFAULT 0,
|
|
216
|
+
memory_type TEXT DEFAULT 'session',
|
|
217
|
+
importance INTEGER DEFAULT 5,
|
|
218
|
+
content_hash TEXT,
|
|
219
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
220
|
+
last_accessed TIMESTAMP,
|
|
221
|
+
access_count INTEGER DEFAULT 0,
|
|
222
|
+
compressed_at TIMESTAMP,
|
|
223
|
+
tier INTEGER DEFAULT 1,
|
|
224
|
+
cluster_id INTEGER,
|
|
225
|
+
FOREIGN KEY (parent_id) REFERENCES memories(id)
|
|
226
|
+
)
|
|
227
|
+
''')
|
|
228
|
+
|
|
229
|
+
# Create graph tables
|
|
230
|
+
cursor.execute('''
|
|
231
|
+
CREATE TABLE IF NOT EXISTS graph_nodes (
|
|
232
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
233
|
+
memory_id INTEGER UNIQUE NOT NULL,
|
|
234
|
+
entities TEXT DEFAULT '[]',
|
|
235
|
+
embedding_vector BLOB,
|
|
236
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
237
|
+
FOREIGN KEY (memory_id) REFERENCES memories(id)
|
|
238
|
+
)
|
|
239
|
+
''')
|
|
240
|
+
|
|
241
|
+
cursor.execute('''
|
|
242
|
+
CREATE TABLE IF NOT EXISTS graph_edges (
|
|
243
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
244
|
+
source_memory_id INTEGER NOT NULL,
|
|
245
|
+
target_memory_id INTEGER NOT NULL,
|
|
246
|
+
similarity REAL NOT NULL,
|
|
247
|
+
relationship_type TEXT,
|
|
248
|
+
shared_entities TEXT DEFAULT '[]',
|
|
249
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
250
|
+
FOREIGN KEY (source_memory_id) REFERENCES memories(id),
|
|
251
|
+
FOREIGN KEY (target_memory_id) REFERENCES memories(id),
|
|
252
|
+
UNIQUE(source_memory_id, target_memory_id)
|
|
253
|
+
)
|
|
254
|
+
''')
|
|
255
|
+
|
|
256
|
+
cursor.execute('''
|
|
257
|
+
CREATE TABLE IF NOT EXISTS graph_clusters (
|
|
258
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
259
|
+
cluster_name TEXT,
|
|
260
|
+
description TEXT,
|
|
261
|
+
memory_count INTEGER DEFAULT 0,
|
|
262
|
+
avg_importance REAL DEFAULT 5.0,
|
|
263
|
+
top_entities TEXT DEFAULT '[]',
|
|
264
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
265
|
+
)
|
|
266
|
+
''')
|
|
267
|
+
|
|
268
|
+
# Create pattern learning tables
|
|
269
|
+
cursor.execute('''
|
|
270
|
+
CREATE TABLE IF NOT EXISTS identity_patterns (
|
|
271
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
272
|
+
pattern_type TEXT NOT NULL,
|
|
273
|
+
pattern_key TEXT NOT NULL,
|
|
274
|
+
pattern_value TEXT,
|
|
275
|
+
confidence REAL DEFAULT 0.0,
|
|
276
|
+
frequency INTEGER DEFAULT 1,
|
|
277
|
+
last_seen TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
278
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
279
|
+
UNIQUE(pattern_type, pattern_key)
|
|
280
|
+
)
|
|
281
|
+
''')
|
|
282
|
+
|
|
283
|
+
cursor.execute('''
|
|
284
|
+
CREATE TABLE IF NOT EXISTS pattern_examples (
|
|
285
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
286
|
+
pattern_id INTEGER NOT NULL,
|
|
287
|
+
memory_id INTEGER NOT NULL,
|
|
288
|
+
context TEXT,
|
|
289
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
290
|
+
FOREIGN KEY (pattern_id) REFERENCES identity_patterns(id),
|
|
291
|
+
FOREIGN KEY (memory_id) REFERENCES memories(id)
|
|
292
|
+
)
|
|
293
|
+
''')
|
|
294
|
+
|
|
295
|
+
# Create tree table
|
|
296
|
+
cursor.execute('''
|
|
297
|
+
CREATE TABLE IF NOT EXISTS memory_tree (
|
|
298
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
299
|
+
node_type TEXT NOT NULL,
|
|
300
|
+
name TEXT NOT NULL,
|
|
301
|
+
parent_id INTEGER,
|
|
302
|
+
tree_path TEXT DEFAULT '/',
|
|
303
|
+
depth INTEGER DEFAULT 0,
|
|
304
|
+
memory_count INTEGER DEFAULT 0,
|
|
305
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
306
|
+
FOREIGN KEY (parent_id) REFERENCES memory_tree(id)
|
|
307
|
+
)
|
|
308
|
+
''')
|
|
309
|
+
|
|
310
|
+
# Create archive table
|
|
311
|
+
cursor.execute('''
|
|
312
|
+
CREATE TABLE IF NOT EXISTS memory_archive (
|
|
313
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
314
|
+
original_memory_id INTEGER,
|
|
315
|
+
compressed_content TEXT NOT NULL,
|
|
316
|
+
compression_type TEXT DEFAULT 'tier2',
|
|
317
|
+
original_size INTEGER,
|
|
318
|
+
compressed_size INTEGER,
|
|
319
|
+
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
320
|
+
)
|
|
321
|
+
''')
|
|
322
|
+
|
|
323
|
+
# Create system metadata table for watermarking
|
|
324
|
+
cursor.execute('''
|
|
325
|
+
CREATE TABLE IF NOT EXISTS system_metadata (
|
|
326
|
+
key TEXT PRIMARY KEY,
|
|
327
|
+
value TEXT NOT NULL
|
|
328
|
+
)
|
|
329
|
+
''')
|
|
330
|
+
|
|
331
|
+
# Add system watermark
|
|
332
|
+
cursor.execute('''
|
|
333
|
+
INSERT OR REPLACE INTO system_metadata (key, value) VALUES
|
|
334
|
+
('product', 'SuperLocalMemory V2'),
|
|
335
|
+
('author', 'Varun Pratap Bhardwaj'),
|
|
336
|
+
('repository', 'https://github.com/varun369/SuperLocalMemoryV2'),
|
|
337
|
+
('license', 'MIT'),
|
|
338
|
+
('schema_version', '2.0.0')
|
|
339
|
+
''')
|
|
340
|
+
|
|
341
|
+
# Create indexes for performance
|
|
342
|
+
cursor.execute('CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project_name)')
|
|
343
|
+
cursor.execute('CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category)')
|
|
344
|
+
cursor.execute('CREATE INDEX IF NOT EXISTS idx_memories_cluster ON memories(cluster_id)')
|
|
345
|
+
cursor.execute('CREATE INDEX IF NOT EXISTS idx_memories_hash ON memories(content_hash)')
|
|
346
|
+
cursor.execute('CREATE INDEX IF NOT EXISTS idx_graph_edges_source ON graph_edges(source_memory_id)')
|
|
347
|
+
cursor.execute('CREATE INDEX IF NOT EXISTS idx_graph_edges_target ON graph_edges(target_memory_id)')
|
|
348
|
+
|
|
349
|
+
conn.commit()
|
|
350
|
+
conn.close()
|
|
351
|
+
|
|
352
|
+
return True, "Database initialized successfully"
|
|
353
|
+
|
|
354
|
+
except Exception as e:
|
|
355
|
+
return False, f"Error initializing database: {str(e)}"
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def validate_setup(auto_fix: bool = False) -> bool:
|
|
359
|
+
"""
|
|
360
|
+
Run complete setup validation.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
auto_fix: If True, automatically initialize missing components
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
True if all required checks pass
|
|
367
|
+
"""
|
|
368
|
+
print_banner()
|
|
369
|
+
|
|
370
|
+
all_passed = True
|
|
371
|
+
optional_issues = []
|
|
372
|
+
|
|
373
|
+
# Check Python version
|
|
374
|
+
print("Checking Python version...")
|
|
375
|
+
py_ok, py_msg = check_python_version()
|
|
376
|
+
print(f" {'✓' if py_ok else '✗'} {py_msg}")
|
|
377
|
+
if not py_ok:
|
|
378
|
+
all_passed = False
|
|
379
|
+
|
|
380
|
+
print()
|
|
381
|
+
|
|
382
|
+
# Check core dependencies
|
|
383
|
+
print("Checking core dependencies...")
|
|
384
|
+
for name, ok, msg in check_core_dependencies():
|
|
385
|
+
print(f" {'✓' if ok else '✗'} {name}: {msg}")
|
|
386
|
+
if not ok:
|
|
387
|
+
all_passed = False
|
|
388
|
+
|
|
389
|
+
print()
|
|
390
|
+
|
|
391
|
+
# Check optional dependencies
|
|
392
|
+
print("Checking optional dependencies...")
|
|
393
|
+
for name, ok, msg, feature in check_optional_dependencies():
|
|
394
|
+
status = '✓' if ok else '○'
|
|
395
|
+
print(f" {status} {name}: {msg if ok else 'Not installed'} ({feature})")
|
|
396
|
+
if not ok:
|
|
397
|
+
optional_issues.append((name, msg, feature))
|
|
398
|
+
|
|
399
|
+
print()
|
|
400
|
+
|
|
401
|
+
# Check directory structure
|
|
402
|
+
print("Checking directory structure...")
|
|
403
|
+
for name, ok, msg in check_directory_structure():
|
|
404
|
+
print(f" {'✓' if ok else '○'} {name}: {msg}")
|
|
405
|
+
|
|
406
|
+
print()
|
|
407
|
+
|
|
408
|
+
# Check database
|
|
409
|
+
print("Checking database...")
|
|
410
|
+
db_ok, db_msg, missing_tables = check_database()
|
|
411
|
+
print(f" {'✓' if db_ok else '○'} Database: {db_msg}")
|
|
412
|
+
|
|
413
|
+
if not db_ok and auto_fix:
|
|
414
|
+
print("\n Initializing database...")
|
|
415
|
+
init_ok, init_msg = initialize_database()
|
|
416
|
+
print(f" {'✓' if init_ok else '✗'} {init_msg}")
|
|
417
|
+
if init_ok:
|
|
418
|
+
db_ok = True
|
|
419
|
+
|
|
420
|
+
print()
|
|
421
|
+
print("=" * 60)
|
|
422
|
+
|
|
423
|
+
if all_passed and db_ok:
|
|
424
|
+
print("\n✓ All required checks passed!")
|
|
425
|
+
print("\nQuick Start Commands:")
|
|
426
|
+
print(" 1. Add a memory:")
|
|
427
|
+
print(" superlocalmemoryv2:remember 'Your content here'")
|
|
428
|
+
print("\n 2. Search memories:")
|
|
429
|
+
print(" superlocalmemoryv2:recall 'search query'")
|
|
430
|
+
print("\n 3. Build knowledge graph (after adding 2+ memories):")
|
|
431
|
+
print(" python ~/.claude-memory/graph_engine.py build")
|
|
432
|
+
print("\n 4. Start UI server:")
|
|
433
|
+
print(" python ~/.claude-memory/api_server.py")
|
|
434
|
+
print("\nDocumentation: https://github.com/varun369/SuperLocalMemoryV2")
|
|
435
|
+
return True
|
|
436
|
+
else:
|
|
437
|
+
print("\n⚠ Some checks need attention:")
|
|
438
|
+
if not all_passed:
|
|
439
|
+
print(" - Fix required dependency issues above")
|
|
440
|
+
if not db_ok:
|
|
441
|
+
print(" - Database needs initialization")
|
|
442
|
+
print(" Run: python setup_validator.py --init")
|
|
443
|
+
|
|
444
|
+
if optional_issues:
|
|
445
|
+
print("\nOptional (for full features):")
|
|
446
|
+
print(" pip install scikit-learn numpy python-igraph leidenalg fastapi uvicorn")
|
|
447
|
+
|
|
448
|
+
return False
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def main():
|
|
452
|
+
"""Main entry point."""
|
|
453
|
+
import argparse
|
|
454
|
+
|
|
455
|
+
parser = argparse.ArgumentParser(
|
|
456
|
+
description="SuperLocalMemory V2 Setup Validator",
|
|
457
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
458
|
+
epilog="""
|
|
459
|
+
Examples:
|
|
460
|
+
python setup_validator.py # Check setup
|
|
461
|
+
python setup_validator.py --init # Check and initialize database
|
|
462
|
+
|
|
463
|
+
Author: Varun Pratap Bhardwaj
|
|
464
|
+
Repository: https://github.com/varun369/SuperLocalMemoryV2
|
|
465
|
+
"""
|
|
466
|
+
)
|
|
467
|
+
parser.add_argument(
|
|
468
|
+
'--init', '-i',
|
|
469
|
+
action='store_true',
|
|
470
|
+
help='Initialize database if needed'
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
args = parser.parse_args()
|
|
474
|
+
success = validate_setup(auto_fix=args.init)
|
|
475
|
+
sys.exit(0 if success else 1)
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
if __name__ == "__main__":
|
|
479
|
+
main()
|