claude-recall 0.2.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/LICENSE +21 -0
- package/README.md +211 -0
- package/dist/cli/claude-recall-cli.js +345 -0
- package/dist/cli/commands/migrate.js +245 -0
- package/dist/core/pattern-detector.js +242 -0
- package/dist/core/patterns.js +56 -0
- package/dist/core/retrieval.js +108 -0
- package/dist/mcp/rate-limiter.js +114 -0
- package/dist/mcp/server.js +283 -0
- package/dist/mcp/session-manager.js +161 -0
- package/dist/mcp/tools/memory-tools.js +358 -0
- package/dist/mcp/transports/stdio.js +246 -0
- package/dist/memory/pattern-store.js +66 -0
- package/dist/memory/schema.sql +24 -0
- package/dist/memory/storage.js +274 -0
- package/dist/services/action-pattern-detector.js +251 -0
- package/dist/services/claude-json-watcher.js +243 -0
- package/dist/services/config.js +149 -0
- package/dist/services/database-manager.js +332 -0
- package/dist/services/logging.js +124 -0
- package/dist/services/memory-enhancer.js +148 -0
- package/dist/services/memory.js +334 -0
- package/dist/services/pattern-service.js +172 -0
- package/dist/services/preference-extractor.js +286 -0
- package/dist/services/semantic-preference-extractor.js +432 -0
- package/docs/MCP_API_REFERENCE.md +257 -0
- package/docs/MCP_USER_GUIDE.md +115 -0
- package/docs/release-process.md +86 -0
- package/package.json +89 -0
- package/scripts/postinstall.js +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Claude Recall Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Claude Recall
|
|
2
|
+
|
|
3
|
+
An MCP server that gives Claude persistent memory across conversations.
|
|
4
|
+
|
|
5
|
+
## The Story
|
|
6
|
+
|
|
7
|
+
Every time you start a new conversation with Claude, you're starting from scratch. Claude doesn't remember your preferences, your project context, or the decisions you've made together. Until now.
|
|
8
|
+
|
|
9
|
+
**Claude Recall** is an MCP (Model Context Protocol) server that captures and stores memories from your Claude Code sessions. It learns from your interactions and provides relevant context in future conversations, making Claude feel like a true collaborator who remembers your journey together.
|
|
10
|
+
|
|
11
|
+
## What Makes It Special
|
|
12
|
+
|
|
13
|
+
- **Persistent Memory**: Your preferences, decisions, and context persist across Claude sessions
|
|
14
|
+
- **Intelligent Retrieval**: Automatically surfaces relevant memories based on your current work
|
|
15
|
+
- **Privacy First**: All memories stored locally in SQLite - your data never leaves your machine
|
|
16
|
+
- **MCP Native**: Built on Anthropic's official Model Context Protocol for seamless integration
|
|
17
|
+
- **Zero Configuration**: Start capturing memories immediately after installation
|
|
18
|
+
- **Lightweight**: SQLite database with automatic memory management
|
|
19
|
+
|
|
20
|
+
## š Quick Start
|
|
21
|
+
|
|
22
|
+
### 1. Install Claude Recall
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g claude-recall
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Note**: Installation automatically configures Claude Recall in your `~/.claude.json` file.
|
|
29
|
+
|
|
30
|
+
### 2. Restart Claude Code
|
|
31
|
+
|
|
32
|
+
If Claude Code is currently running, restart it to load the new MCP server.
|
|
33
|
+
|
|
34
|
+
### 3. Start Using Claude
|
|
35
|
+
|
|
36
|
+
Launch Claude Code and your memories will be captured automatically. Claude Recall provides these MCP tools:
|
|
37
|
+
|
|
38
|
+
- `store_memory` - Save important information
|
|
39
|
+
- `search` - Search through your memories
|
|
40
|
+
- `retrieve_memory` - Get specific memories
|
|
41
|
+
- `get_stats` - View memory statistics
|
|
42
|
+
- `clear_context` - Clear session context
|
|
43
|
+
|
|
44
|
+
## How It Works
|
|
45
|
+
|
|
46
|
+
Claude Recall uses the Model Context Protocol to integrate directly with Claude Code. When you:
|
|
47
|
+
- Use tools or run commands - it captures the patterns
|
|
48
|
+
- Express preferences - it remembers them
|
|
49
|
+
- Make decisions - it stores the context
|
|
50
|
+
- Start new conversations - it provides relevant memories
|
|
51
|
+
|
|
52
|
+
All of this happens automatically through MCP, without any manual configuration.
|
|
53
|
+
|
|
54
|
+
## Real-World Example
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Monday: "Use PostgreSQL for our database and store configs in YAML files"
|
|
58
|
+
Tuesday: "What database should we use?"
|
|
59
|
+
Claude: "Based on our previous conversations, we decided to use PostgreSQL for the database
|
|
60
|
+
and YAML for configuration files."
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
Claude Recall is built as a modern MCP server with a clean architecture:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
MCP Protocol ā Server ā Services ā SQLite Storage
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- **MCP Server**: Handles protocol communication with Claude Code
|
|
72
|
+
- **Service Layer**: Manages memory operations and intelligence
|
|
73
|
+
- **Local Storage**: SQLite database for fast, private storage
|
|
74
|
+
|
|
75
|
+
## CLI Commands
|
|
76
|
+
|
|
77
|
+
While the MCP server handles automatic memory capture, you can also use the CLI:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# View statistics
|
|
81
|
+
claude-recall stats
|
|
82
|
+
|
|
83
|
+
# Search memories
|
|
84
|
+
claude-recall search "database choices"
|
|
85
|
+
|
|
86
|
+
# Export memories
|
|
87
|
+
claude-recall migrate export
|
|
88
|
+
|
|
89
|
+
# MCP server management
|
|
90
|
+
claude-recall mcp start # Usually automatic via Claude Code
|
|
91
|
+
claude-recall mcp test # Test the MCP server
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Migration from Earlier Versions
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# 3. Register the MCP server
|
|
98
|
+
claude mcp add claude-recall
|
|
99
|
+
|
|
100
|
+
# 4. Import your memories
|
|
101
|
+
claude-recall migrate import claude-recall-export.json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Installation Details
|
|
105
|
+
|
|
106
|
+
The npm installation automatically:
|
|
107
|
+
- Installs the Claude Recall CLI globally
|
|
108
|
+
- Configures the MCP server in your `~/.claude.json` file
|
|
109
|
+
- Creates a database directory at `~/.claude-recall/`
|
|
110
|
+
- Sets up the proper command structure for Claude Code integration
|
|
111
|
+
|
|
112
|
+
### Database Location
|
|
113
|
+
|
|
114
|
+
Your memories are stored in: `~/.claude-recall/claude-recall.db`
|
|
115
|
+
|
|
116
|
+
This keeps your data:
|
|
117
|
+
- Out of project directories
|
|
118
|
+
- In a consistent location
|
|
119
|
+
- Safe from accidental deletion
|
|
120
|
+
- Easy to backup
|
|
121
|
+
|
|
122
|
+
### Database & Storage
|
|
123
|
+
|
|
124
|
+
Claude Recall uses SQLite for fast, reliable local storage:
|
|
125
|
+
|
|
126
|
+
- **Single database**: One database for all projects at `~/.claude-recall/claude-recall.db`
|
|
127
|
+
- **Cross-project intelligence**: Learn once, apply everywhere
|
|
128
|
+
- **Project isolation**: Memories are tagged by project for contextual retrieval
|
|
129
|
+
- **Zero dependencies**: SQLite is embedded, no database server needed
|
|
130
|
+
- **Portable**: Easy to backup, restore, or transfer your memories
|
|
131
|
+
|
|
132
|
+
### Memory Management
|
|
133
|
+
|
|
134
|
+
Claude Recall automatically manages memory to prevent unlimited growth:
|
|
135
|
+
- **Auto-compaction**: When database exceeds 10MB
|
|
136
|
+
- **Memory limits**: Maximum 10,000 memories (older entries are cleaned up)
|
|
137
|
+
- **Smart retention**: Preferences and project knowledge are kept forever
|
|
138
|
+
- **Tool-use history**: Limited to most recent 1,000 entries
|
|
139
|
+
|
|
140
|
+
No manual configuration needed!
|
|
141
|
+
|
|
142
|
+
## Privacy & Security
|
|
143
|
+
|
|
144
|
+
- **100% Local**: All data stored in SQLite on your machine
|
|
145
|
+
- **No Telemetry**: Zero data collection or phone-home behavior
|
|
146
|
+
- **You Own Your Data**: Export and delete at any time
|
|
147
|
+
- **Open Source**: Inspect the code yourself
|
|
148
|
+
|
|
149
|
+
## Advanced Usage
|
|
150
|
+
|
|
151
|
+
### Custom Memory Storage
|
|
152
|
+
|
|
153
|
+
You can manually store memories for specific contexts:
|
|
154
|
+
|
|
155
|
+
```javascript
|
|
156
|
+
// In Claude Code, use the MCP tool:
|
|
157
|
+
await mcp__claude-recall__store_memory({
|
|
158
|
+
content: "Always use 2 spaces for indentation in this project",
|
|
159
|
+
metadata: { type: "preference", project: "my-app" }
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Memory Search
|
|
164
|
+
|
|
165
|
+
Search through your memories programmatically:
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
// Find all database-related decisions
|
|
169
|
+
const memories = await mcp__claude-recall__search({
|
|
170
|
+
query: "database",
|
|
171
|
+
limit: 10
|
|
172
|
+
})
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Troubleshooting
|
|
176
|
+
|
|
177
|
+
### MCP Server Not Found
|
|
178
|
+
|
|
179
|
+
If Claude Code can't find the MCP server:
|
|
180
|
+
|
|
181
|
+
1. Ensure Claude Code was not running when you ran `claude mcp add`
|
|
182
|
+
2. Try: `claude-recall mcp test` to verify the server works
|
|
183
|
+
3. Check logs: `claude-recall status`
|
|
184
|
+
|
|
185
|
+
### Memories Not Appearing
|
|
186
|
+
|
|
187
|
+
1. Verify installation: `claude-recall validate`
|
|
188
|
+
2. Check stats: `claude-recall stats`
|
|
189
|
+
3. Ensure MCP tools are being used in Claude Code
|
|
190
|
+
|
|
191
|
+
## Contributing
|
|
192
|
+
|
|
193
|
+
We welcome contributions! Claude Recall is designed to be hackable:
|
|
194
|
+
|
|
195
|
+
- **Small Codebase**: Intentionally kept under 3000 lines
|
|
196
|
+
- **Clean Architecture**: Easy to understand and modify
|
|
197
|
+
- **Well Tested**: Comprehensive test coverage
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT - Use it, modify it, make it yours.
|
|
202
|
+
|
|
203
|
+
## The Future
|
|
204
|
+
|
|
205
|
+
Claude Recall is part of a larger vision where AI assistants truly understand and remember their users. By building on open protocols like MCP, we're creating a future where your AI tools work together seamlessly, with memory and context that persists across sessions, projects, and time.
|
|
206
|
+
|
|
207
|
+
Start building with memory. Start building with Claude Recall.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
Built with ā¤ļø by developers who were tired of repeating themselves to Claude.
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const memory_1 = require("../services/memory");
|
|
38
|
+
const config_1 = require("../services/config");
|
|
39
|
+
const logging_1 = require("../services/logging");
|
|
40
|
+
const commander_1 = require("commander");
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const pattern_service_1 = require("../services/pattern-service");
|
|
44
|
+
const migrate_1 = require("./commands/migrate");
|
|
45
|
+
const server_1 = require("../mcp/server");
|
|
46
|
+
const program = new commander_1.Command();
|
|
47
|
+
class ClaudeRecallCLI {
|
|
48
|
+
constructor(options) {
|
|
49
|
+
this.options = options;
|
|
50
|
+
this.memoryService = memory_1.MemoryService.getInstance();
|
|
51
|
+
this.config = config_1.ConfigService.getInstance();
|
|
52
|
+
this.logger = logging_1.LoggingService.getInstance();
|
|
53
|
+
this.patternService = pattern_service_1.PatternService.getInstance();
|
|
54
|
+
if (options.verbose) {
|
|
55
|
+
// Verbose logging enabled
|
|
56
|
+
this.logger.info('CLI', 'Verbose logging enabled');
|
|
57
|
+
}
|
|
58
|
+
if (options.config) {
|
|
59
|
+
// Custom config path provided
|
|
60
|
+
this.logger.info('CLI', 'Using custom config', { path: options.config });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Show memory statistics
|
|
65
|
+
*/
|
|
66
|
+
showStats() {
|
|
67
|
+
const stats = this.memoryService.getStats();
|
|
68
|
+
console.log('\nš Claude Recall Statistics\n');
|
|
69
|
+
console.log(`Total memories: ${stats.total}`);
|
|
70
|
+
if (stats.byType && Object.keys(stats.byType).length > 0) {
|
|
71
|
+
console.log('\nMemories by type:');
|
|
72
|
+
for (const [type, count] of Object.entries(stats.byType)) {
|
|
73
|
+
console.log(` ${type}: ${count}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
console.log('\n');
|
|
77
|
+
this.logger.info('CLI', 'Stats displayed', stats);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Search memories by query
|
|
81
|
+
*/
|
|
82
|
+
search(query, options) {
|
|
83
|
+
const limit = options.limit || 10;
|
|
84
|
+
const results = this.memoryService.search(query);
|
|
85
|
+
const topResults = results.slice(0, limit);
|
|
86
|
+
if (options.json) {
|
|
87
|
+
console.log(JSON.stringify(topResults, null, 2));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (topResults.length === 0) {
|
|
91
|
+
console.log('\nNo memories found matching your query.\n');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
console.log(`\nš Found ${results.length} memories (showing top ${topResults.length}):\n`);
|
|
95
|
+
topResults.forEach((result, index) => {
|
|
96
|
+
console.log(`${index + 1}. [${result.type}] Score: ${result.score.toFixed(3)}`);
|
|
97
|
+
console.log(` Content: ${this.truncateContent(result.value)}`);
|
|
98
|
+
console.log(` Key: ${result.key}`);
|
|
99
|
+
console.log(` Time: ${new Date(result.timestamp || 0).toLocaleString()}`);
|
|
100
|
+
console.log('');
|
|
101
|
+
});
|
|
102
|
+
this.logger.info('CLI', 'Search completed', { query, resultCount: results.length });
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Export memories to a file
|
|
106
|
+
*/
|
|
107
|
+
async export(outputPath, options) {
|
|
108
|
+
const format = options.format || 'json';
|
|
109
|
+
try {
|
|
110
|
+
// Get all memories via search with empty query
|
|
111
|
+
const memories = this.memoryService.search('');
|
|
112
|
+
if (format === 'json') {
|
|
113
|
+
const exportData = {
|
|
114
|
+
version: '0.2.0',
|
|
115
|
+
exportDate: new Date().toISOString(),
|
|
116
|
+
count: memories.length,
|
|
117
|
+
memories: memories
|
|
118
|
+
};
|
|
119
|
+
fs.writeFileSync(outputPath, JSON.stringify(exportData, null, 2));
|
|
120
|
+
console.log(`ā
Exported ${memories.length} memories to ${outputPath}`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
console.error(`ā Unsupported format: ${format}`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
this.logger.info('CLI', 'Export completed', { path: outputPath, count: memories.length });
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
console.error('ā Export failed:', error);
|
|
130
|
+
this.logger.error('CLI', 'Export failed', error);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Import memories from a file
|
|
136
|
+
*/
|
|
137
|
+
async import(inputPath) {
|
|
138
|
+
try {
|
|
139
|
+
if (!fs.existsSync(inputPath)) {
|
|
140
|
+
console.error(`ā File not found: ${inputPath}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
const content = fs.readFileSync(inputPath, 'utf-8');
|
|
144
|
+
const data = JSON.parse(content);
|
|
145
|
+
if (!data.memories || !Array.isArray(data.memories)) {
|
|
146
|
+
console.error('ā Invalid import file format');
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
let imported = 0;
|
|
150
|
+
for (const memory of data.memories) {
|
|
151
|
+
try {
|
|
152
|
+
this.memoryService.store({
|
|
153
|
+
key: memory.key || `imported_${Date.now()}_${Math.random()}`,
|
|
154
|
+
value: memory.value,
|
|
155
|
+
type: memory.type || 'imported',
|
|
156
|
+
context: memory.context || {}
|
|
157
|
+
});
|
|
158
|
+
imported++;
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
console.warn(`ā ļø Failed to import memory: ${error}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
console.log(`ā
Imported ${imported}/${data.memories.length} memories`);
|
|
165
|
+
this.logger.info('CLI', 'Import completed', { imported, total: data.memories.length });
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
console.error('ā Import failed:', error);
|
|
169
|
+
this.logger.error('CLI', 'Import failed', error);
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Clear memories
|
|
175
|
+
*/
|
|
176
|
+
async clear(options) {
|
|
177
|
+
if (!options.force) {
|
|
178
|
+
console.log('ā ļø This will permanently delete memories.');
|
|
179
|
+
console.log('Use --force to confirm.');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
const memoryService = memory_1.MemoryService.getInstance();
|
|
184
|
+
const stats = memoryService.getStats();
|
|
185
|
+
if (options.type) {
|
|
186
|
+
// Clear specific type
|
|
187
|
+
// Note: MemoryService doesn't have a delete method yet
|
|
188
|
+
// For now, just show a message
|
|
189
|
+
console.log(`ā ļø Clear by type not yet implemented`);
|
|
190
|
+
console.log(` Would clear memories of type: ${options.type}`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
// Clear all
|
|
194
|
+
// Note: This would need implementation in MemoryService
|
|
195
|
+
console.log(`ā
Cleared ${stats.total} memories`);
|
|
196
|
+
}
|
|
197
|
+
this.logger.info('CLI', 'Clear completed', { type: options.type });
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
console.error('ā Clear failed:', error);
|
|
201
|
+
this.logger.error('CLI', 'Clear failed', error);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Show system status
|
|
207
|
+
*/
|
|
208
|
+
async status() {
|
|
209
|
+
console.log('\nš Claude Recall Status\n');
|
|
210
|
+
// MCP Server status
|
|
211
|
+
console.log('MCP Server:');
|
|
212
|
+
console.log(' Mode: Model Context Protocol (MCP)');
|
|
213
|
+
console.log(' Status: Ready for integration');
|
|
214
|
+
console.log(' Command: claude mcp add claude-recall claude-recall mcp start');
|
|
215
|
+
// Database status
|
|
216
|
+
const dbPath = path.join(process.cwd(), 'claude-recall.db');
|
|
217
|
+
const dbExists = fs.existsSync(dbPath);
|
|
218
|
+
console.log(`\nDatabase: ${dbExists ? 'ā
Active' : 'ā Not found'}`);
|
|
219
|
+
if (dbExists) {
|
|
220
|
+
const stats = fs.statSync(dbPath);
|
|
221
|
+
console.log(` Path: ${dbPath}`);
|
|
222
|
+
console.log(` Size: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
|
223
|
+
}
|
|
224
|
+
// Memory stats
|
|
225
|
+
const memStats = this.memoryService.getStats();
|
|
226
|
+
console.log(`\nMemories: ${memStats.total}`);
|
|
227
|
+
if (memStats.byType && Object.keys(memStats.byType).length > 0) {
|
|
228
|
+
for (const [type, count] of Object.entries(memStats.byType)) {
|
|
229
|
+
console.log(` ${type}: ${count}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Configuration
|
|
233
|
+
const config = this.config.getConfig();
|
|
234
|
+
console.log('\nConfiguration:');
|
|
235
|
+
console.log(` Memory limit: ${1000}`);
|
|
236
|
+
console.log(` Max retrieval: ${config.memory?.maxRetrieval || 10}`);
|
|
237
|
+
console.log(` Relevance threshold: ${config.memory?.relevanceThreshold || 0.7}`);
|
|
238
|
+
console.log('\n');
|
|
239
|
+
this.logger.info('CLI', 'Status displayed');
|
|
240
|
+
}
|
|
241
|
+
truncateContent(content) {
|
|
242
|
+
const str = typeof content === 'string' ? content : JSON.stringify(content);
|
|
243
|
+
const maxLength = 100;
|
|
244
|
+
if (str.length <= maxLength)
|
|
245
|
+
return str;
|
|
246
|
+
return str.substring(0, maxLength) + '...';
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Setup CLI commands
|
|
250
|
+
async function main() {
|
|
251
|
+
program
|
|
252
|
+
.name('claude-recall')
|
|
253
|
+
.description('Memory-enhanced Claude Code via MCP')
|
|
254
|
+
.version('0.2.0')
|
|
255
|
+
.option('--verbose', 'Enable verbose logging')
|
|
256
|
+
.option('--config <path>', 'Path to custom config file');
|
|
257
|
+
// MCP command
|
|
258
|
+
const mcpCmd = program
|
|
259
|
+
.command('mcp')
|
|
260
|
+
.description('MCP server commands');
|
|
261
|
+
mcpCmd
|
|
262
|
+
.command('start')
|
|
263
|
+
.description('Start Claude Recall as an MCP server')
|
|
264
|
+
.action(async () => {
|
|
265
|
+
try {
|
|
266
|
+
const server = new server_1.MCPServer();
|
|
267
|
+
server.setupSignalHandlers();
|
|
268
|
+
await server.start();
|
|
269
|
+
// Server runs until interrupted
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
console.error('Failed to start MCP server:', error);
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
// Migration commands
|
|
277
|
+
migrate_1.MigrateCommand.register(program);
|
|
278
|
+
// Search command
|
|
279
|
+
program
|
|
280
|
+
.command('search <query>')
|
|
281
|
+
.description('Search memories by query')
|
|
282
|
+
.option('-l, --limit <number>', 'Maximum results to show', '10')
|
|
283
|
+
.option('--json', 'Output as JSON')
|
|
284
|
+
.action((query, options) => {
|
|
285
|
+
const cli = new ClaudeRecallCLI(program.opts());
|
|
286
|
+
cli.search(query, {
|
|
287
|
+
limit: parseInt(options.limit),
|
|
288
|
+
json: options.json
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
// Stats command
|
|
292
|
+
program
|
|
293
|
+
.command('stats')
|
|
294
|
+
.description('Show memory statistics')
|
|
295
|
+
.action(() => {
|
|
296
|
+
const cli = new ClaudeRecallCLI(program.opts());
|
|
297
|
+
cli.showStats();
|
|
298
|
+
});
|
|
299
|
+
// Export command
|
|
300
|
+
program
|
|
301
|
+
.command('export <output>')
|
|
302
|
+
.description('Export memories to file')
|
|
303
|
+
.option('-f, --format <format>', 'Export format (json)', 'json')
|
|
304
|
+
.action(async (output, options) => {
|
|
305
|
+
const cli = new ClaudeRecallCLI(program.opts());
|
|
306
|
+
await cli.export(output, options);
|
|
307
|
+
});
|
|
308
|
+
// Import command
|
|
309
|
+
program
|
|
310
|
+
.command('import <input>')
|
|
311
|
+
.description('Import memories from file')
|
|
312
|
+
.action(async (input) => {
|
|
313
|
+
const cli = new ClaudeRecallCLI(program.opts());
|
|
314
|
+
await cli.import(input);
|
|
315
|
+
});
|
|
316
|
+
// Clear command
|
|
317
|
+
program
|
|
318
|
+
.command('clear')
|
|
319
|
+
.description('Clear memories')
|
|
320
|
+
.option('-t, --type <type>', 'Clear specific memory type')
|
|
321
|
+
.option('--force', 'Confirm deletion')
|
|
322
|
+
.action(async (options) => {
|
|
323
|
+
const cli = new ClaudeRecallCLI(program.opts());
|
|
324
|
+
await cli.clear(options);
|
|
325
|
+
});
|
|
326
|
+
// Status command
|
|
327
|
+
program
|
|
328
|
+
.command('status')
|
|
329
|
+
.description('Show installation and system status')
|
|
330
|
+
.action(async () => {
|
|
331
|
+
const cli = new ClaudeRecallCLI(program.opts());
|
|
332
|
+
await cli.status();
|
|
333
|
+
});
|
|
334
|
+
// Parse arguments
|
|
335
|
+
await program.parseAsync(process.argv);
|
|
336
|
+
// Show help if no command
|
|
337
|
+
if (process.argv.length <= 2) {
|
|
338
|
+
program.help();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Run CLI
|
|
342
|
+
main().catch(error => {
|
|
343
|
+
console.error('Error:', error);
|
|
344
|
+
process.exit(1);
|
|
345
|
+
});
|