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,45 @@
|
|
|
1
|
+
SuperLocalMemory V2.1.0 - Installation Complete!
|
|
2
|
+
================================================
|
|
3
|
+
|
|
4
|
+
Installation successful!
|
|
5
|
+
|
|
6
|
+
Location: %USERPROFILE%\.claude-memory\
|
|
7
|
+
CLI Command: slm
|
|
8
|
+
|
|
9
|
+
Quick Start:
|
|
10
|
+
------------
|
|
11
|
+
1. Open a NEW Command Prompt or PowerShell window
|
|
12
|
+
(Required for PATH changes to take effect)
|
|
13
|
+
|
|
14
|
+
2. Verify installation:
|
|
15
|
+
> slm status
|
|
16
|
+
|
|
17
|
+
3. Store your first memory:
|
|
18
|
+
> slm remember "React is my preferred framework" --tags frontend
|
|
19
|
+
|
|
20
|
+
4. Search memories:
|
|
21
|
+
> slm recall "React"
|
|
22
|
+
|
|
23
|
+
5. Launch dashboard (optional):
|
|
24
|
+
> powershell -ExecutionPolicy Bypass -File start-dashboard.ps1
|
|
25
|
+
|
|
26
|
+
Integrated IDEs:
|
|
27
|
+
----------------
|
|
28
|
+
SuperLocalMemory is now available in:
|
|
29
|
+
✓ Claude Desktop (restart to see @SuperLocalMemory)
|
|
30
|
+
✓ Cursor (restart IDE)
|
|
31
|
+
✓ Windsurf (restart IDE)
|
|
32
|
+
✓ Continue.dev (use /slm-* skills)
|
|
33
|
+
✓ Cody (use custom commands)
|
|
34
|
+
✓ And 6+ more tools (11+ IDEs supported total)
|
|
35
|
+
|
|
36
|
+
Troubleshooting:
|
|
37
|
+
----------------
|
|
38
|
+
• 'slm' not found: Open NEW terminal window
|
|
39
|
+
• Python errors: Ensure Python 3.8+ is installed
|
|
40
|
+
• Permission errors: Run PowerShell as Administrator
|
|
41
|
+
|
|
42
|
+
Documentation: https://github.com/varun369/SuperLocalMemoryV2/wiki
|
|
43
|
+
Support: https://github.com/varun369/SuperLocalMemoryV2/issues
|
|
44
|
+
|
|
45
|
+
Copyright (c) 2026 Varun Pratap Bhardwaj
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
SuperLocalMemory V2 - example_graph_usage.py
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2026 Varun Pratap Bhardwaj
|
|
6
|
+
Solution Architect & Original Creator
|
|
7
|
+
|
|
8
|
+
Licensed under MIT License (see LICENSE file)
|
|
9
|
+
Repository: https://github.com/varun369/SuperLocalMemoryV2
|
|
10
|
+
|
|
11
|
+
ATTRIBUTION REQUIRED: This notice must be preserved in all copies.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# Add parent directory to path
|
|
18
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
19
|
+
|
|
20
|
+
from graph_engine import GraphEngine
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def example_build_graph():
|
|
24
|
+
"""Example: Build complete knowledge graph."""
|
|
25
|
+
print("=" * 60)
|
|
26
|
+
print("Example 1: Build Knowledge Graph")
|
|
27
|
+
print("=" * 60)
|
|
28
|
+
|
|
29
|
+
engine = GraphEngine()
|
|
30
|
+
|
|
31
|
+
# Build graph with default similarity threshold (0.3)
|
|
32
|
+
stats = engine.build_graph(min_similarity=0.3)
|
|
33
|
+
|
|
34
|
+
print(f"Graph built successfully!")
|
|
35
|
+
print(f" - Nodes: {stats['nodes']}")
|
|
36
|
+
print(f" - Edges: {stats['edges']}")
|
|
37
|
+
print(f" - Clusters: {stats['clusters']}")
|
|
38
|
+
print(f" - Time: {stats['time_seconds']}s")
|
|
39
|
+
print()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def example_find_related():
|
|
43
|
+
"""Example: Find related memories."""
|
|
44
|
+
print("=" * 60)
|
|
45
|
+
print("Example 2: Find Related Memories")
|
|
46
|
+
print("=" * 60)
|
|
47
|
+
|
|
48
|
+
engine = GraphEngine()
|
|
49
|
+
|
|
50
|
+
# Find memories related to memory #1
|
|
51
|
+
memory_id = 1
|
|
52
|
+
related = engine.get_related(memory_id, max_hops=2)
|
|
53
|
+
|
|
54
|
+
print(f"Memories related to #{memory_id}:")
|
|
55
|
+
for idx, mem in enumerate(related[:5], 1): # Top 5
|
|
56
|
+
print(f"\n{idx}. Memory #{mem['id']} ({mem['hops']}-hop)")
|
|
57
|
+
print(f" Relationship: {mem['relationship']}")
|
|
58
|
+
print(f" Weight: {mem['weight']:.3f}")
|
|
59
|
+
print(f" Importance: {mem['importance']}")
|
|
60
|
+
if mem['shared_entities']:
|
|
61
|
+
print(f" Shared entities: {', '.join(mem['shared_entities'][:3])}")
|
|
62
|
+
print()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def example_query_clusters():
|
|
66
|
+
"""Example: Query memory clusters."""
|
|
67
|
+
print("=" * 60)
|
|
68
|
+
print("Example 3: Query Clusters")
|
|
69
|
+
print("=" * 60)
|
|
70
|
+
|
|
71
|
+
engine = GraphEngine()
|
|
72
|
+
|
|
73
|
+
# Get statistics
|
|
74
|
+
stats = engine.get_stats()
|
|
75
|
+
|
|
76
|
+
print(f"Total clusters: {stats['clusters']}")
|
|
77
|
+
print("\nTop clusters:")
|
|
78
|
+
|
|
79
|
+
for cluster in stats['top_clusters'][:5]:
|
|
80
|
+
print(f"\n - {cluster['name']}")
|
|
81
|
+
print(f" Members: {cluster['members']}")
|
|
82
|
+
print(f" Avg Importance: {cluster['avg_importance']}")
|
|
83
|
+
|
|
84
|
+
# Get cluster members
|
|
85
|
+
cluster_id = stats['top_clusters'].index(cluster) + 1
|
|
86
|
+
members = engine.get_cluster_members(cluster_id)
|
|
87
|
+
|
|
88
|
+
print(f" Sample memories: {[m['id'] for m in members[:3]]}")
|
|
89
|
+
print()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def example_incremental_add():
|
|
93
|
+
"""Example: Add memory to existing graph."""
|
|
94
|
+
print("=" * 60)
|
|
95
|
+
print("Example 4: Incremental Add")
|
|
96
|
+
print("=" * 60)
|
|
97
|
+
|
|
98
|
+
engine = GraphEngine()
|
|
99
|
+
|
|
100
|
+
# Simulate adding a new memory (would normally be created first)
|
|
101
|
+
memory_id = 5 # Existing memory
|
|
102
|
+
|
|
103
|
+
print(f"Adding memory #{memory_id} to graph...")
|
|
104
|
+
success = engine.add_memory_incremental(memory_id)
|
|
105
|
+
|
|
106
|
+
if success:
|
|
107
|
+
print(f"Memory #{memory_id} added successfully!")
|
|
108
|
+
|
|
109
|
+
# Find what it connected to
|
|
110
|
+
related = engine.get_related(memory_id, max_hops=1)
|
|
111
|
+
print(f"Connected to {len(related)} existing memories")
|
|
112
|
+
else:
|
|
113
|
+
print("Failed to add memory")
|
|
114
|
+
print()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def example_extract_entities():
|
|
118
|
+
"""Example: Extract entities from a memory."""
|
|
119
|
+
print("=" * 60)
|
|
120
|
+
print("Example 5: Entity Extraction")
|
|
121
|
+
print("=" * 60)
|
|
122
|
+
|
|
123
|
+
engine = GraphEngine()
|
|
124
|
+
|
|
125
|
+
memory_id = 1
|
|
126
|
+
entities = engine.extract_entities(memory_id)
|
|
127
|
+
|
|
128
|
+
print(f"Entities extracted from memory #{memory_id}:")
|
|
129
|
+
for idx, entity in enumerate(entities[:10], 1):
|
|
130
|
+
print(f" {idx}. {entity}")
|
|
131
|
+
print()
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if __name__ == '__main__':
|
|
135
|
+
print("\n" + "=" * 60)
|
|
136
|
+
print("GraphEngine Usage Examples")
|
|
137
|
+
print("=" * 60 + "\n")
|
|
138
|
+
|
|
139
|
+
# Run all examples
|
|
140
|
+
example_build_graph()
|
|
141
|
+
example_find_related()
|
|
142
|
+
example_query_clusters()
|
|
143
|
+
example_extract_entities()
|
|
144
|
+
example_incremental_add()
|
|
145
|
+
|
|
146
|
+
print("=" * 60)
|
|
147
|
+
print("All examples completed!")
|
|
148
|
+
print("=" * 60)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Memory List CLI Skill
|
|
4
|
+
* List recent memories with sorting and filtering
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { execFile } = require('child_process');
|
|
8
|
+
const { promisify } = require('util');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const execFileAsync = promisify(execFile);
|
|
12
|
+
|
|
13
|
+
async function memoryListSkill() {
|
|
14
|
+
const memoryScript = path.join(process.env.HOME, '.claude-memory', 'memory_store_v2.py');
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
|
|
17
|
+
// Show help if --help
|
|
18
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
19
|
+
console.log(`
|
|
20
|
+
╔══════════════════════════════════════════════════════════╗
|
|
21
|
+
║ ║
|
|
22
|
+
║ SuperLocalMemory V2 - List Recent Memories ║
|
|
23
|
+
║ ║
|
|
24
|
+
╚══════════════════════════════════════════════════════════╝
|
|
25
|
+
|
|
26
|
+
Display recent memories with optional sorting and limits.
|
|
27
|
+
Quick overview of what's stored in your memory database.
|
|
28
|
+
|
|
29
|
+
Usage: memory-list [options]
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
--limit <n> Number of memories to show (default: 20)
|
|
33
|
+
--sort <field> Sort by: recent, accessed, importance
|
|
34
|
+
• recent: Latest created first (default)
|
|
35
|
+
• accessed: Most recently accessed
|
|
36
|
+
• importance: Highest importance first
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
memory-list
|
|
40
|
+
|
|
41
|
+
memory-list --limit 50
|
|
42
|
+
|
|
43
|
+
memory-list --sort importance
|
|
44
|
+
|
|
45
|
+
memory-list --limit 10 --sort accessed
|
|
46
|
+
|
|
47
|
+
Output Format:
|
|
48
|
+
• ID, Content (truncated), Tags, Importance
|
|
49
|
+
• Creation timestamp
|
|
50
|
+
• Access count and last accessed time
|
|
51
|
+
|
|
52
|
+
Notes:
|
|
53
|
+
• Default shows last 20 memories
|
|
54
|
+
• Content is truncated to 100 chars for readability
|
|
55
|
+
• Use ID with memory-recall to see full content
|
|
56
|
+
• Sort by 'accessed' to find frequently used memories
|
|
57
|
+
`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Parse options
|
|
62
|
+
let limit = 20;
|
|
63
|
+
let sortBy = 'recent';
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < args.length; i++) {
|
|
66
|
+
const arg = args[i];
|
|
67
|
+
|
|
68
|
+
if (arg === '--limit' && i + 1 < args.length) {
|
|
69
|
+
const parsedLimit = parseInt(args[i + 1]);
|
|
70
|
+
if (parsedLimit > 0 && parsedLimit <= 1000) {
|
|
71
|
+
limit = parsedLimit;
|
|
72
|
+
} else {
|
|
73
|
+
console.error('❌ ERROR: Limit must be between 1-1000');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
i++;
|
|
77
|
+
} else if (arg === '--sort' && i + 1 < args.length) {
|
|
78
|
+
const validSorts = ['recent', 'accessed', 'importance'];
|
|
79
|
+
if (validSorts.includes(args[i + 1])) {
|
|
80
|
+
sortBy = args[i + 1];
|
|
81
|
+
} else {
|
|
82
|
+
console.error(`❌ ERROR: Sort must be one of: ${validSorts.join(', ')}`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
i++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Build Python command based on sort type
|
|
90
|
+
// Note: V1 store only supports 'recent' and 'list' commands without sort flags
|
|
91
|
+
let pythonArgs = [];
|
|
92
|
+
|
|
93
|
+
if (sortBy === 'recent' || sortBy === 'accessed') {
|
|
94
|
+
pythonArgs = ['recent', limit.toString()];
|
|
95
|
+
} else {
|
|
96
|
+
// Default to list for importance or other sorts
|
|
97
|
+
pythonArgs = ['list', limit.toString()];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const { stdout, stderr } = await execFileAsync('python3', [memoryScript, ...pythonArgs]);
|
|
102
|
+
|
|
103
|
+
if (stderr) {
|
|
104
|
+
console.error('⚠️ Warning:', stderr);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log(`
|
|
108
|
+
╔══════════════════════════════════════════════════════════╗
|
|
109
|
+
║ Recent Memories (${sortBy} | limit: ${limit})
|
|
110
|
+
╚══════════════════════════════════════════════════════════╝
|
|
111
|
+
`);
|
|
112
|
+
|
|
113
|
+
console.log(stdout);
|
|
114
|
+
|
|
115
|
+
// Show helpful next steps
|
|
116
|
+
console.log(`
|
|
117
|
+
Next steps:
|
|
118
|
+
• Use \`memory-recall <query>\` to search memories
|
|
119
|
+
• Use \`memory-remember <content>\` to add new memories
|
|
120
|
+
• Use \`memory-list --sort <field>\` to change sort order
|
|
121
|
+
`);
|
|
122
|
+
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error('❌ Error listing memories:', error.message);
|
|
125
|
+
if (error.stdout) console.log(error.stdout);
|
|
126
|
+
if (error.stderr) console.error(error.stderr);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
memoryListSkill();
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Memory Profile CLI Skill
|
|
4
|
+
* Provides memory-profile commands for managing multiple memory contexts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { execFile } = require('child_process');
|
|
8
|
+
const { promisify } = require('util');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const readline = require('readline');
|
|
11
|
+
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
|
|
14
|
+
const rl = readline.createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stdout
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
20
|
+
|
|
21
|
+
async function memoryProfileSkill() {
|
|
22
|
+
const profileScript = path.join(process.env.HOME, '.claude-memory', 'memory-profiles.py');
|
|
23
|
+
const args = process.argv.slice(2); // Get command line arguments
|
|
24
|
+
|
|
25
|
+
// Show help if no args
|
|
26
|
+
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
27
|
+
console.log(`
|
|
28
|
+
╔══════════════════════════════════════════════════════════╗
|
|
29
|
+
║ ║
|
|
30
|
+
║ SuperLocalMemory V2 - Profile Management ║
|
|
31
|
+
║ ║
|
|
32
|
+
╚══════════════════════════════════════════════════════════╝
|
|
33
|
+
|
|
34
|
+
Profiles let you maintain separate memory databases for different contexts:
|
|
35
|
+
• Work vs Personal projects
|
|
36
|
+
• Different clients or teams
|
|
37
|
+
• Different AI personalities
|
|
38
|
+
• Experimentation vs Production
|
|
39
|
+
|
|
40
|
+
Each profile has isolated: memories, graph, patterns, archives
|
|
41
|
+
|
|
42
|
+
Usage: memory-profile <command> [options]
|
|
43
|
+
|
|
44
|
+
Commands:
|
|
45
|
+
list List all profiles and show active one
|
|
46
|
+
current Show current active profile
|
|
47
|
+
create <name> Create a new empty profile
|
|
48
|
+
switch <name> Switch to a different profile (requires restart)
|
|
49
|
+
delete <name> Delete a profile (with confirmation)
|
|
50
|
+
|
|
51
|
+
Examples:
|
|
52
|
+
memory-profile list
|
|
53
|
+
memory-profile current
|
|
54
|
+
memory-profile create work
|
|
55
|
+
memory-profile switch work
|
|
56
|
+
memory-profile delete old-project
|
|
57
|
+
|
|
58
|
+
Notes:
|
|
59
|
+
• Default profile is always available
|
|
60
|
+
• Switching profiles requires restarting Claude CLI
|
|
61
|
+
• Deleting a profile is permanent (but creates backup)
|
|
62
|
+
`);
|
|
63
|
+
rl.close();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const command = args[0];
|
|
68
|
+
|
|
69
|
+
// LIST command
|
|
70
|
+
if (command === 'list') {
|
|
71
|
+
try {
|
|
72
|
+
const { stdout } = await execFileAsync('python', [profileScript, 'list']);
|
|
73
|
+
console.log(stdout);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.error('❌ Error:', error.message);
|
|
76
|
+
}
|
|
77
|
+
rl.close();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// CURRENT command
|
|
82
|
+
if (command === 'current') {
|
|
83
|
+
try {
|
|
84
|
+
const { stdout } = await execFileAsync('python', [profileScript, 'current']);
|
|
85
|
+
console.log(stdout);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error('❌ Error:', error.message);
|
|
88
|
+
}
|
|
89
|
+
rl.close();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// CREATE command
|
|
94
|
+
if (command === 'create') {
|
|
95
|
+
if (args.length < 2) {
|
|
96
|
+
console.log(`
|
|
97
|
+
❌ ERROR: Profile name required
|
|
98
|
+
|
|
99
|
+
Usage: memory-profile create <name> [options]
|
|
100
|
+
|
|
101
|
+
Options:
|
|
102
|
+
--description "text" Profile description
|
|
103
|
+
--from-current Copy current profile's data to new profile
|
|
104
|
+
|
|
105
|
+
Examples:
|
|
106
|
+
memory-profile create work
|
|
107
|
+
memory-profile create work --description "Work projects"
|
|
108
|
+
memory-profile create personal --from-current
|
|
109
|
+
`);
|
|
110
|
+
rl.close();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const profileName = args[1];
|
|
115
|
+
const pythonArgs = ['create', profileName];
|
|
116
|
+
|
|
117
|
+
// Check for --description flag
|
|
118
|
+
const descIndex = args.indexOf('--description');
|
|
119
|
+
if (descIndex !== -1 && descIndex + 1 < args.length) {
|
|
120
|
+
pythonArgs.push('--description', args[descIndex + 1]);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check for --from-current flag
|
|
124
|
+
if (args.includes('--from-current')) {
|
|
125
|
+
pythonArgs.push('--from-current');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
const { stdout } = await execFileAsync('python', [profileScript, ...pythonArgs]);
|
|
130
|
+
console.log(stdout);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error('❌ Error:', error.message);
|
|
133
|
+
if (error.stdout) console.log(error.stdout);
|
|
134
|
+
}
|
|
135
|
+
rl.close();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// SWITCH command
|
|
140
|
+
if (command === 'switch') {
|
|
141
|
+
if (args.length < 2) {
|
|
142
|
+
console.log(`
|
|
143
|
+
❌ ERROR: Profile name required
|
|
144
|
+
|
|
145
|
+
Usage: memory-profile switch <name>
|
|
146
|
+
|
|
147
|
+
Example:
|
|
148
|
+
memory-profile switch work
|
|
149
|
+
|
|
150
|
+
After switching, restart Claude CLI for changes to take effect.
|
|
151
|
+
`);
|
|
152
|
+
rl.close();
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const profileName = args[1];
|
|
157
|
+
|
|
158
|
+
console.log(`
|
|
159
|
+
╔══════════════════════════════════════════════════════════╗
|
|
160
|
+
║ Profile Switch Confirmation ║
|
|
161
|
+
╚══════════════════════════════════════════════════════════╝
|
|
162
|
+
|
|
163
|
+
This will:
|
|
164
|
+
✓ Save current profile state
|
|
165
|
+
✓ Load profile "${profileName}"
|
|
166
|
+
✓ Update active profile marker
|
|
167
|
+
|
|
168
|
+
After switching, you MUST restart Claude CLI for the new profile
|
|
169
|
+
to take effect.
|
|
170
|
+
|
|
171
|
+
Current memories will be preserved in the old profile.
|
|
172
|
+
`);
|
|
173
|
+
|
|
174
|
+
const answer = await question('Proceed with profile switch? (yes/no): ');
|
|
175
|
+
|
|
176
|
+
if (answer.toLowerCase() === 'yes') {
|
|
177
|
+
try {
|
|
178
|
+
const { stdout } = await execFileAsync('python', [
|
|
179
|
+
profileScript,
|
|
180
|
+
'switch',
|
|
181
|
+
profileName
|
|
182
|
+
]);
|
|
183
|
+
console.log(stdout);
|
|
184
|
+
console.log(`
|
|
185
|
+
⚠️ IMPORTANT: Restart Claude CLI now for profile switch to complete.
|
|
186
|
+
|
|
187
|
+
The new profile will not be active until you restart.
|
|
188
|
+
`);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error('❌ Error:', error.message);
|
|
191
|
+
if (error.stdout) console.log(error.stdout);
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
console.log('\nCancelled. No changes made.');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
rl.close();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// DELETE command
|
|
202
|
+
if (command === 'delete') {
|
|
203
|
+
if (args.length < 2) {
|
|
204
|
+
console.log(`
|
|
205
|
+
❌ ERROR: Profile name required
|
|
206
|
+
|
|
207
|
+
Usage: memory-profile delete <name>
|
|
208
|
+
|
|
209
|
+
Example:
|
|
210
|
+
memory-profile delete old-project
|
|
211
|
+
|
|
212
|
+
Cannot delete:
|
|
213
|
+
• The "default" profile
|
|
214
|
+
• The currently active profile
|
|
215
|
+
`);
|
|
216
|
+
rl.close();
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const profileName = args[1];
|
|
221
|
+
|
|
222
|
+
// Prevent deleting default
|
|
223
|
+
if (profileName === 'default') {
|
|
224
|
+
console.log(`
|
|
225
|
+
❌ ERROR: Cannot delete the default profile
|
|
226
|
+
|
|
227
|
+
The default profile is protected and cannot be deleted.
|
|
228
|
+
`);
|
|
229
|
+
rl.close();
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
console.log(`
|
|
234
|
+
╔══════════════════════════════════════════════════════════╗
|
|
235
|
+
║ ⚠️ DELETE PROFILE WARNING ⚠️ ║
|
|
236
|
+
╚══════════════════════════════════════════════════════════╝
|
|
237
|
+
|
|
238
|
+
This will PERMANENTLY delete profile: "${profileName}"
|
|
239
|
+
|
|
240
|
+
What will be deleted:
|
|
241
|
+
🔴 All memories in this profile
|
|
242
|
+
🔴 Graph data (nodes, edges, clusters)
|
|
243
|
+
🔴 Learned patterns
|
|
244
|
+
🔴 Compressed archives
|
|
245
|
+
|
|
246
|
+
A backup will be created before deletion.
|
|
247
|
+
|
|
248
|
+
`);
|
|
249
|
+
|
|
250
|
+
const answer = await question(`Type the profile name "${profileName}" to confirm: `);
|
|
251
|
+
|
|
252
|
+
if (answer === profileName) {
|
|
253
|
+
try {
|
|
254
|
+
const { stdout } = await execFileAsync('python', [
|
|
255
|
+
profileScript,
|
|
256
|
+
'delete',
|
|
257
|
+
profileName
|
|
258
|
+
]);
|
|
259
|
+
console.log(stdout);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.error('❌ Error:', error.message);
|
|
262
|
+
if (error.stdout) console.log(error.stdout);
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
console.log('\nCancelled. No changes made.');
|
|
266
|
+
console.log(`(You must type exactly "${profileName}" to confirm)`);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
rl.close();
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Unknown command
|
|
274
|
+
console.log(`
|
|
275
|
+
❌ Unknown command: ${command}
|
|
276
|
+
|
|
277
|
+
Valid commands: list, current, create, switch, delete
|
|
278
|
+
|
|
279
|
+
Use: memory-profile --help for more information
|
|
280
|
+
`);
|
|
281
|
+
rl.close();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
memoryProfileSkill();
|