claude-memory-agent 2.0.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.
Files changed (100) hide show
  1. package/.env.example +107 -0
  2. package/README.md +200 -0
  3. package/agent_card.py +512 -0
  4. package/bin/cli.js +181 -0
  5. package/bin/postinstall.js +216 -0
  6. package/config.py +104 -0
  7. package/dashboard.html +2689 -0
  8. package/hooks/README.md +196 -0
  9. package/hooks/__pycache__/auto-detect-response.cpython-312.pyc +0 -0
  10. package/hooks/__pycache__/auto_capture.cpython-312.pyc +0 -0
  11. package/hooks/__pycache__/session_end.cpython-312.pyc +0 -0
  12. package/hooks/__pycache__/session_start.cpython-312.pyc +0 -0
  13. package/hooks/auto-detect-response.py +348 -0
  14. package/hooks/auto_capture.py +255 -0
  15. package/hooks/detect-correction.py +173 -0
  16. package/hooks/grounding-hook.py +348 -0
  17. package/hooks/log-tool-use.py +234 -0
  18. package/hooks/log-user-request.py +208 -0
  19. package/hooks/pre-tool-decision.py +218 -0
  20. package/hooks/problem-detector.py +343 -0
  21. package/hooks/session_end.py +192 -0
  22. package/hooks/session_start.py +227 -0
  23. package/install.py +887 -0
  24. package/main.py +2859 -0
  25. package/manager.py +997 -0
  26. package/package.json +55 -0
  27. package/requirements.txt +8 -0
  28. package/run_server.py +136 -0
  29. package/services/__init__.py +50 -0
  30. package/services/__pycache__/__init__.cpython-312.pyc +0 -0
  31. package/services/__pycache__/agent_registry.cpython-312.pyc +0 -0
  32. package/services/__pycache__/auth.cpython-312.pyc +0 -0
  33. package/services/__pycache__/auto_inject.cpython-312.pyc +0 -0
  34. package/services/__pycache__/claude_md_sync.cpython-312.pyc +0 -0
  35. package/services/__pycache__/cleanup.cpython-312.pyc +0 -0
  36. package/services/__pycache__/compaction_flush.cpython-312.pyc +0 -0
  37. package/services/__pycache__/confidence.cpython-312.pyc +0 -0
  38. package/services/__pycache__/daily_log.cpython-312.pyc +0 -0
  39. package/services/__pycache__/database.cpython-312.pyc +0 -0
  40. package/services/__pycache__/embeddings.cpython-312.pyc +0 -0
  41. package/services/__pycache__/insights.cpython-312.pyc +0 -0
  42. package/services/__pycache__/llm_analyzer.cpython-312.pyc +0 -0
  43. package/services/__pycache__/memory_md_sync.cpython-312.pyc +0 -0
  44. package/services/__pycache__/retry_queue.cpython-312.pyc +0 -0
  45. package/services/__pycache__/timeline.cpython-312.pyc +0 -0
  46. package/services/__pycache__/vector_index.cpython-312.pyc +0 -0
  47. package/services/__pycache__/websocket.cpython-312.pyc +0 -0
  48. package/services/agent_registry.py +753 -0
  49. package/services/auth.py +331 -0
  50. package/services/auto_inject.py +250 -0
  51. package/services/claude_md_sync.py +275 -0
  52. package/services/cleanup.py +667 -0
  53. package/services/compaction_flush.py +447 -0
  54. package/services/confidence.py +301 -0
  55. package/services/daily_log.py +333 -0
  56. package/services/database.py +2485 -0
  57. package/services/embeddings.py +358 -0
  58. package/services/insights.py +632 -0
  59. package/services/llm_analyzer.py +595 -0
  60. package/services/memory_md_sync.py +409 -0
  61. package/services/retry_queue.py +453 -0
  62. package/services/timeline.py +579 -0
  63. package/services/vector_index.py +398 -0
  64. package/services/websocket.py +257 -0
  65. package/skills/__init__.py +6 -0
  66. package/skills/__pycache__/__init__.cpython-312.pyc +0 -0
  67. package/skills/__pycache__/admin.cpython-312.pyc +0 -0
  68. package/skills/__pycache__/checkpoint.cpython-312.pyc +0 -0
  69. package/skills/__pycache__/claude_md.cpython-312.pyc +0 -0
  70. package/skills/__pycache__/cleanup.cpython-312.pyc +0 -0
  71. package/skills/__pycache__/grounding.cpython-312.pyc +0 -0
  72. package/skills/__pycache__/insights.cpython-312.pyc +0 -0
  73. package/skills/__pycache__/natural_language.cpython-312.pyc +0 -0
  74. package/skills/__pycache__/retrieve.cpython-312.pyc +0 -0
  75. package/skills/__pycache__/search.cpython-312.pyc +0 -0
  76. package/skills/__pycache__/state.cpython-312.pyc +0 -0
  77. package/skills/__pycache__/store.cpython-312.pyc +0 -0
  78. package/skills/__pycache__/summarize.cpython-312.pyc +0 -0
  79. package/skills/__pycache__/timeline.cpython-312.pyc +0 -0
  80. package/skills/__pycache__/verification.cpython-312.pyc +0 -0
  81. package/skills/admin.py +469 -0
  82. package/skills/checkpoint.py +198 -0
  83. package/skills/claude_md.py +363 -0
  84. package/skills/cleanup.py +241 -0
  85. package/skills/grounding.py +801 -0
  86. package/skills/insights.py +231 -0
  87. package/skills/natural_language.py +277 -0
  88. package/skills/retrieve.py +67 -0
  89. package/skills/search.py +213 -0
  90. package/skills/state.py +182 -0
  91. package/skills/store.py +179 -0
  92. package/skills/summarize.py +588 -0
  93. package/skills/timeline.py +387 -0
  94. package/skills/verification.py +391 -0
  95. package/start_daemon.py +155 -0
  96. package/test_automation.py +221 -0
  97. package/test_complete.py +338 -0
  98. package/test_full.py +322 -0
  99. package/update_system.py +817 -0
  100. package/verify_db.py +134 -0
package/bin/cli.js ADDED
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Claude Memory Agent CLI
5
+ *
6
+ * This is the npm entry point that wraps the Python CLI.
7
+ * Usage:
8
+ * claude-memory-agent install - Run installation wizard
9
+ * claude-memory-agent start - Start the agent
10
+ * claude-memory-agent stop - Stop the agent
11
+ * claude-memory-agent status - Check status
12
+ * claude-memory-agent dashboard - Open dashboard
13
+ */
14
+
15
+ const { spawn, execSync } = require('child_process');
16
+ const path = require('path');
17
+ const fs = require('fs');
18
+
19
+ const AGENT_DIR = path.dirname(__dirname);
20
+ const args = process.argv.slice(2);
21
+ const command = args[0] || 'help';
22
+
23
+ // Check Python availability
24
+ function getPython() {
25
+ const pythonCommands = ['python3', 'python', 'py'];
26
+
27
+ for (const cmd of pythonCommands) {
28
+ try {
29
+ const result = execSync(`${cmd} --version`, {
30
+ encoding: 'utf8',
31
+ stdio: ['pipe', 'pipe', 'pipe']
32
+ });
33
+ if (result.includes('Python 3')) {
34
+ return cmd;
35
+ }
36
+ } catch (e) {
37
+ continue;
38
+ }
39
+ }
40
+ return null;
41
+ }
42
+
43
+ // Check if Python dependencies are installed
44
+ function checkDependencies(python) {
45
+ try {
46
+ execSync(`${python} -c "import fastapi, uvicorn, dotenv"`, {
47
+ cwd: AGENT_DIR,
48
+ stdio: ['pipe', 'pipe', 'pipe']
49
+ });
50
+ return true;
51
+ } catch (e) {
52
+ return false;
53
+ }
54
+ }
55
+
56
+ // Install Python dependencies
57
+ function installDependencies(python) {
58
+ console.log('Installing Python dependencies...');
59
+ try {
60
+ execSync(`${python} -m pip install -r requirements.txt -q`, {
61
+ cwd: AGENT_DIR,
62
+ stdio: 'inherit'
63
+ });
64
+ return true;
65
+ } catch (e) {
66
+ console.error('Failed to install dependencies:', e.message);
67
+ return false;
68
+ }
69
+ }
70
+
71
+ // Run Python script
72
+ function runPython(script, scriptArgs = []) {
73
+ const python = getPython();
74
+
75
+ if (!python) {
76
+ console.error('Error: Python 3 is required but not found.');
77
+ console.error('Please install Python 3.9+ from https://python.org/');
78
+ process.exit(1);
79
+ }
80
+
81
+ const proc = spawn(python, [script, ...scriptArgs], {
82
+ cwd: AGENT_DIR,
83
+ stdio: 'inherit',
84
+ shell: process.platform === 'win32'
85
+ });
86
+
87
+ proc.on('close', (code) => {
88
+ process.exit(code || 0);
89
+ });
90
+
91
+ proc.on('error', (err) => {
92
+ console.error('Failed to start:', err.message);
93
+ process.exit(1);
94
+ });
95
+ }
96
+
97
+ // Print help
98
+ function printHelp() {
99
+ console.log(`
100
+ Claude Memory Agent v2.0.0
101
+ Persistent semantic memory for Claude Code sessions
102
+
103
+ USAGE:
104
+ claude-memory-agent <command> [options]
105
+
106
+ COMMANDS:
107
+ install Run the installation wizard
108
+ start Start the memory agent in background
109
+ stop Stop the running agent
110
+ status Check if agent is running
111
+ dashboard Open the web dashboard
112
+ logs Show recent log output
113
+ help Show this help message
114
+
115
+ QUICK START:
116
+ 1. claude-memory-agent install # Configure everything
117
+ 2. claude-memory-agent start # Start the agent
118
+ 3. claude-memory-agent dashboard # Open web UI
119
+
120
+ REQUIREMENTS:
121
+ - Python 3.9+
122
+ - Ollama with nomic-embed-text model (for embeddings)
123
+ - Claude Code (for full integration)
124
+
125
+ For more info: https://github.com/yourusername/claude-memory-agent
126
+ `);
127
+ }
128
+
129
+ // Main
130
+ function main() {
131
+ switch (command) {
132
+ case 'install':
133
+ case 'setup':
134
+ runPython('install.py', args.slice(1));
135
+ break;
136
+
137
+ case 'start':
138
+ runPython('memory-agent', ['start', ...args.slice(1)]);
139
+ break;
140
+
141
+ case 'stop':
142
+ runPython('memory-agent', ['stop', ...args.slice(1)]);
143
+ break;
144
+
145
+ case 'status':
146
+ runPython('memory-agent', ['status', ...args.slice(1)]);
147
+ break;
148
+
149
+ case 'dashboard':
150
+ runPython('memory-agent', ['dashboard', ...args.slice(1)]);
151
+ break;
152
+
153
+ case 'logs':
154
+ runPython('memory-agent', ['logs', ...args.slice(1)]);
155
+ break;
156
+
157
+ case 'run':
158
+ case 'server':
159
+ // Run directly (not in background)
160
+ runPython('main.py', args.slice(1));
161
+ break;
162
+
163
+ case 'help':
164
+ case '--help':
165
+ case '-h':
166
+ printHelp();
167
+ break;
168
+
169
+ case '--version':
170
+ case '-v':
171
+ console.log('claude-memory-agent v2.0.0');
172
+ break;
173
+
174
+ default:
175
+ console.error(`Unknown command: ${command}`);
176
+ console.error('Run "claude-memory-agent help" for usage.');
177
+ process.exit(1);
178
+ }
179
+ }
180
+
181
+ main();
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Post-installation script for Claude Memory Agent
5
+ *
6
+ * This runs automatically after npm install to:
7
+ * 1. Check Python availability
8
+ * 2. Install Python dependencies
9
+ * 3. Run the configuration wizard (if interactive)
10
+ */
11
+
12
+ const { execSync, spawn } = require('child_process');
13
+ const path = require('path');
14
+ const fs = require('fs');
15
+ const readline = require('readline');
16
+
17
+ const AGENT_DIR = path.dirname(__dirname);
18
+
19
+ // Colors for terminal output
20
+ const colors = {
21
+ reset: '\x1b[0m',
22
+ green: '\x1b[32m',
23
+ yellow: '\x1b[33m',
24
+ red: '\x1b[31m',
25
+ cyan: '\x1b[36m',
26
+ bold: '\x1b[1m'
27
+ };
28
+
29
+ function log(msg) {
30
+ console.log(msg);
31
+ }
32
+
33
+ function success(msg) {
34
+ console.log(`${colors.green}✓${colors.reset} ${msg}`);
35
+ }
36
+
37
+ function warn(msg) {
38
+ console.log(`${colors.yellow}!${colors.reset} ${msg}`);
39
+ }
40
+
41
+ function error(msg) {
42
+ console.log(`${colors.red}✗${colors.reset} ${msg}`);
43
+ }
44
+
45
+ function header(msg) {
46
+ console.log(`\n${colors.bold}${colors.cyan}${msg}${colors.reset}\n`);
47
+ }
48
+
49
+ // Check Python availability
50
+ function getPython() {
51
+ const pythonCommands = ['python3', 'python', 'py'];
52
+
53
+ for (const cmd of pythonCommands) {
54
+ try {
55
+ const result = execSync(`${cmd} --version`, {
56
+ encoding: 'utf8',
57
+ stdio: ['pipe', 'pipe', 'pipe']
58
+ });
59
+ const match = result.match(/Python (\d+)\.(\d+)/);
60
+ if (match) {
61
+ const major = parseInt(match[1]);
62
+ const minor = parseInt(match[2]);
63
+ if (major >= 3 && minor >= 9) {
64
+ return { cmd, version: result.trim() };
65
+ }
66
+ }
67
+ } catch (e) {
68
+ continue;
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+
74
+ // Check if Ollama is running
75
+ function checkOllama() {
76
+ try {
77
+ const http = require('http');
78
+ return new Promise((resolve) => {
79
+ const req = http.get('http://localhost:11434/api/tags', { timeout: 2000 }, (res) => {
80
+ resolve(res.statusCode === 200);
81
+ });
82
+ req.on('error', () => resolve(false));
83
+ req.on('timeout', () => {
84
+ req.destroy();
85
+ resolve(false);
86
+ });
87
+ });
88
+ } catch (e) {
89
+ return Promise.resolve(false);
90
+ }
91
+ }
92
+
93
+ // Install Python dependencies
94
+ function installPythonDeps(python) {
95
+ const requirementsPath = path.join(AGENT_DIR, 'requirements.txt');
96
+
97
+ if (!fs.existsSync(requirementsPath)) {
98
+ warn('requirements.txt not found, skipping Python dependencies');
99
+ return true;
100
+ }
101
+
102
+ log('Installing Python dependencies...');
103
+ try {
104
+ execSync(`${python} -m pip install -r requirements.txt -q --disable-pip-version-check`, {
105
+ cwd: AGENT_DIR,
106
+ stdio: ['pipe', 'pipe', 'pipe']
107
+ });
108
+ success('Python dependencies installed');
109
+ return true;
110
+ } catch (e) {
111
+ error('Failed to install Python dependencies');
112
+ console.log(' Run manually: pip install -r requirements.txt');
113
+ return false;
114
+ }
115
+ }
116
+
117
+ // Create .env file if it doesn't exist
118
+ function createEnvFile() {
119
+ const envPath = path.join(AGENT_DIR, '.env');
120
+ const examplePath = path.join(AGENT_DIR, '.env.example');
121
+
122
+ if (fs.existsSync(envPath)) {
123
+ success('.env file already exists');
124
+ return true;
125
+ }
126
+
127
+ // Create basic .env
128
+ const envContent = `# Claude Memory Agent Configuration
129
+ # Generated during npm install
130
+
131
+ # Server
132
+ PORT=8102
133
+ HOST=0.0.0.0
134
+ MEMORY_AGENT_URL=http://localhost:8102
135
+
136
+ # Ollama
137
+ OLLAMA_HOST=http://localhost:11434
138
+ EMBEDDING_MODEL=nomic-embed-text
139
+
140
+ # Database (relative to agent directory)
141
+ DATABASE_PATH=${path.join(AGENT_DIR, 'memories.db').replace(/\\/g, '/')}
142
+
143
+ # Logging
144
+ LOG_LEVEL=INFO
145
+ `;
146
+
147
+ try {
148
+ fs.writeFileSync(envPath, envContent);
149
+ success('Created .env configuration file');
150
+ return true;
151
+ } catch (e) {
152
+ warn('Could not create .env file');
153
+ return false;
154
+ }
155
+ }
156
+
157
+ // Main installation
158
+ async function main() {
159
+ header('Claude Memory Agent - Post-Installation Setup');
160
+
161
+ // Check Python
162
+ log('Checking Python...');
163
+ const python = getPython();
164
+ if (!python) {
165
+ error('Python 3.9+ is required but not found');
166
+ console.log('\n Please install Python from https://python.org/');
167
+ console.log(' Then run: claude-memory-agent install\n');
168
+ process.exit(1);
169
+ }
170
+ success(`Found ${python.version}`);
171
+
172
+ // Install Python dependencies
173
+ installPythonDeps(python.cmd);
174
+
175
+ // Create .env file
176
+ createEnvFile();
177
+
178
+ // Check Ollama (non-blocking)
179
+ log('Checking Ollama...');
180
+ const ollamaRunning = await checkOllama();
181
+ if (ollamaRunning) {
182
+ success('Ollama is running');
183
+ } else {
184
+ warn('Ollama not detected - embeddings require Ollama');
185
+ console.log(' Install from: https://ollama.ai/');
186
+ console.log(' Then run: ollama pull nomic-embed-text');
187
+ }
188
+
189
+ // Print next steps
190
+ header('Installation Complete!');
191
+ console.log('Next steps:');
192
+ console.log('');
193
+ console.log(' 1. Run the setup wizard:');
194
+ console.log(' claude-memory-agent install');
195
+ console.log('');
196
+ console.log(' 2. Start the agent:');
197
+ console.log(' claude-memory-agent start');
198
+ console.log('');
199
+ console.log(' 3. Open the dashboard:');
200
+ console.log(' claude-memory-agent dashboard');
201
+ console.log('');
202
+
203
+ if (!ollamaRunning) {
204
+ console.log(' For embeddings, install and start Ollama:');
205
+ console.log(' ollama pull nomic-embed-text');
206
+ console.log(' ollama serve');
207
+ console.log('');
208
+ }
209
+ }
210
+
211
+ // Run if not in CI/CD environment
212
+ if (!process.env.CI && !process.env.npm_config_ignore_scripts) {
213
+ main().catch(console.error);
214
+ } else {
215
+ console.log('Skipping post-install in CI environment');
216
+ }
package/config.py ADDED
@@ -0,0 +1,104 @@
1
+ """
2
+ Centralized configuration for Claude Memory Agent.
3
+
4
+ All configuration is loaded from environment variables with sensible defaults.
5
+ Use .env file for local overrides (not committed to git).
6
+
7
+ Usage:
8
+ from config import config
9
+ print(config.PORT)
10
+ print(config.MEMORY_AGENT_URL)
11
+ """
12
+ import os
13
+ from pathlib import Path
14
+ from typing import Optional
15
+ from dotenv import load_dotenv
16
+
17
+ # Load .env from agent directory
18
+ AGENT_DIR = Path(__file__).parent.resolve()
19
+ load_dotenv(AGENT_DIR / ".env")
20
+
21
+
22
+ class Config:
23
+ """Configuration singleton with environment variable loading."""
24
+
25
+ def __init__(self):
26
+ # Paths (auto-detected from script location)
27
+ self.AGENT_DIR = AGENT_DIR
28
+ self.DATABASE_PATH = Path(os.getenv(
29
+ "DATABASE_PATH",
30
+ str(AGENT_DIR / "memories.db")
31
+ ))
32
+ self.INDEX_DIR = Path(os.getenv(
33
+ "INDEX_DIR",
34
+ str(AGENT_DIR / "indexes")
35
+ ))
36
+ self.LOG_FILE = AGENT_DIR / "memory-agent.log"
37
+ self.LOCK_FILE = AGENT_DIR / "memory-agent.lock"
38
+ self.PID_FILE = AGENT_DIR / "memory-agent.pid"
39
+
40
+ # Server configuration
41
+ self.HOST = os.getenv("HOST", "0.0.0.0")
42
+ self.PORT = int(os.getenv("PORT", "8102"))
43
+ self.MEMORY_AGENT_URL = os.getenv(
44
+ "MEMORY_AGENT_URL",
45
+ f"http://localhost:{self.PORT}"
46
+ )
47
+
48
+ # Ollama / Embeddings
49
+ self.OLLAMA_HOST = os.getenv("OLLAMA_HOST", "http://localhost:11434")
50
+ self.EMBEDDING_MODEL = os.getenv("EMBEDDING_MODEL", "nomic-embed-text")
51
+ self.EMBEDDING_DIM = int(os.getenv("EMBEDDING_DIM", "768"))
52
+ self.OLLAMA_HEALTH_TIMEOUT = float(os.getenv("OLLAMA_HEALTH_TIMEOUT", "2.0"))
53
+ self.OLLAMA_HEALTH_CACHE_TTL = float(os.getenv("OLLAMA_HEALTH_CACHE_TTL", "30.0"))
54
+
55
+ # Database
56
+ self.USE_VECTOR_INDEX = os.getenv("USE_VECTOR_INDEX", "true").lower() == "true"
57
+ self.DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "5"))
58
+ self.DB_TIMEOUT = float(os.getenv("DB_TIMEOUT", "30.0"))
59
+ self.DB_MAX_RETRIES = int(os.getenv("DB_MAX_RETRIES", "3"))
60
+ self.DB_RETRY_BASE_DELAY = float(os.getenv("DB_RETRY_BASE_DELAY", "0.1"))
61
+
62
+ # Authentication
63
+ self.AUTH_ENABLED = os.getenv("AUTH_ENABLED", "false").lower() == "true"
64
+ self.AUTH_KEY_FILE = Path(os.getenv(
65
+ "AUTH_KEY_FILE",
66
+ str(Path.home() / ".claude" / "memory-agent-keys.json")
67
+ ))
68
+ self.AUTH_RATE_LIMIT = int(os.getenv("AUTH_RATE_LIMIT", "100"))
69
+ self.AUTH_RATE_WINDOW = int(os.getenv("AUTH_RATE_WINDOW", "60"))
70
+
71
+ # Logging
72
+ self.LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")
73
+
74
+ # Hook timeouts
75
+ self.API_TIMEOUT = int(os.getenv("API_TIMEOUT", "30"))
76
+
77
+ def get_health_url(self) -> str:
78
+ """Get the health check URL."""
79
+ return f"{self.MEMORY_AGENT_URL}/health"
80
+
81
+ def get_dashboard_url(self) -> str:
82
+ """Get the dashboard URL."""
83
+ return f"{self.MEMORY_AGENT_URL}/dashboard"
84
+
85
+ def to_dict(self) -> dict:
86
+ """Export configuration as dictionary (for debugging)."""
87
+ return {
88
+ key: str(value) if isinstance(value, Path) else value
89
+ for key, value in vars(self).items()
90
+ if not key.startswith("_")
91
+ }
92
+
93
+
94
+ # Singleton instance
95
+ config = Config()
96
+
97
+
98
+ # Convenience exports for backwards compatibility
99
+ PORT = config.PORT
100
+ HOST = config.HOST
101
+ MEMORY_AGENT_URL = config.MEMORY_AGENT_URL
102
+ OLLAMA_HOST = config.OLLAMA_HOST
103
+ EMBEDDING_MODEL = config.EMBEDDING_MODEL
104
+ DATABASE_PATH = config.DATABASE_PATH