claude-recall 0.7.3 → 0.7.5
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/.claude/CLAUDE.md +7 -0
- package/README.md +279 -32
- package/dist/cli/claude-recall-cli.js +7 -1
- package/dist/cli/commands/mcp-commands.js +248 -0
- package/dist/cli/commands/project-commands.js +309 -0
- package/dist/mcp/server.js +93 -1
- package/dist/services/process-manager.js +251 -0
- package/dist/services/project-registry.js +241 -0
- package/package.json +3 -2
- package/scripts/postinstall.js +47 -0
- package/scripts/uninstall.js +89 -0
package/.claude/CLAUDE.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# Claude Recall - Skills Integration
|
|
2
|
+
|
|
3
|
+
**Note**: Claude Recall now uses Claude Code Skills for better memory management.
|
|
4
|
+
See [.claude/skills/memory-management/SKILL.md](./.claude/skills/memory-management/SKILL.md) for details.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# Claude Recall - Memory-First Development with Learning Loop
|
|
2
9
|
|
|
3
10
|
This file provides instructions to Claude Code when working with projects that use Claude Recall for persistent memory.
|
package/README.md
CHANGED
|
@@ -94,7 +94,22 @@ npm uninstall -g claude-recall
|
|
|
94
94
|
|
|
95
95
|
Claude Recall works on **Windows, Linux, and macOS**. Native binaries (SQLite) compile automatically for your platform during `npm install`.
|
|
96
96
|
|
|
97
|
-
**WSL Users
|
|
97
|
+
**WSL Users - Special Case:**
|
|
98
|
+
|
|
99
|
+
If you use **both Windows and WSL** for the same project (e.g., Electron app runs on Windows, but Claude Code runs in WSL):
|
|
100
|
+
|
|
101
|
+
**Problem**: Installing locally creates Windows binaries, but WSL needs Linux binaries → "invalid ELF header" errors.
|
|
102
|
+
|
|
103
|
+
**Solution**: Install globally in WSL only:
|
|
104
|
+
```bash
|
|
105
|
+
# From WSL:
|
|
106
|
+
npm install -g claude-recall
|
|
107
|
+
|
|
108
|
+
# Verify:
|
|
109
|
+
claude-recall --version
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Important**: Global installation does NOT affect project-specific memory scoping! See [How Project Scoping Works](#how-project-scoping-works-installation-location) below.
|
|
98
113
|
|
|
99
114
|
**Everyone else:** Both local and global work, but local is still recommended for the benefits above.
|
|
100
115
|
|
|
@@ -371,40 +386,39 @@ Claude Recall stores different types of memories (sorted by priority):
|
|
|
371
386
|
|
|
372
387
|
## CLI Commands
|
|
373
388
|
|
|
374
|
-
|
|
375
|
-
```bash
|
|
376
|
-
# View statistics
|
|
377
|
-
claude-recall stats
|
|
389
|
+
All commands can be run from your terminal or **within Claude Code sessions** (Claude can execute them using the Bash tool).
|
|
378
390
|
|
|
379
|
-
|
|
380
|
-
claude-recall search "database configuration"
|
|
391
|
+
### Memory Operations
|
|
381
392
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
#
|
|
386
|
-
claude-recall
|
|
393
|
+
**Search memories:**
|
|
394
|
+
```bash
|
|
395
|
+
npx claude-recall search "database"
|
|
396
|
+
npx claude-recall search "auth" --limit 20 # Show up to 20 results
|
|
397
|
+
npx claude-recall search "config" --project my-app # Filter by project + universal
|
|
398
|
+
npx claude-recall search "testing" --global # Search all projects
|
|
399
|
+
npx claude-recall search "api" --json # Output as JSON
|
|
400
|
+
```
|
|
387
401
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
claude-recall
|
|
402
|
+
**View statistics:**
|
|
403
|
+
```bash
|
|
404
|
+
npx claude-recall stats # Current project + universal + unscoped
|
|
405
|
+
npx claude-recall stats --project my-app # Specific project + universal
|
|
406
|
+
npx claude-recall stats --global # All projects
|
|
407
|
+
```
|
|
391
408
|
|
|
392
|
-
|
|
393
|
-
|
|
409
|
+
**Store memory directly:**
|
|
410
|
+
```bash
|
|
411
|
+
npx claude-recall store "I prefer TypeScript with strict mode"
|
|
412
|
+
npx claude-recall store "Use PostgreSQL" --type project-knowledge
|
|
394
413
|
```
|
|
395
414
|
|
|
396
|
-
### Intelligence & Evolution
|
|
415
|
+
### Intelligence & Evolution (v0.7.0+)
|
|
397
416
|
|
|
417
|
+
**View memory evolution and sophistication metrics:**
|
|
398
418
|
```bash
|
|
399
|
-
|
|
400
|
-
claude-recall evolution
|
|
401
|
-
claude-recall evolution --
|
|
402
|
-
claude-recall evolution --project my-app # Filter by project
|
|
403
|
-
|
|
404
|
-
# View failure memories with counterfactual learning
|
|
405
|
-
claude-recall failures
|
|
406
|
-
claude-recall failures --limit 20 # Show 20 most recent
|
|
407
|
-
claude-recall failures --project my-app # Filter by project
|
|
419
|
+
npx claude-recall evolution # Last 30 days
|
|
420
|
+
npx claude-recall evolution --days 60 # Last 60 days
|
|
421
|
+
npx claude-recall evolution --project my-app # Filter by project
|
|
408
422
|
```
|
|
409
423
|
|
|
410
424
|
**Example `evolution` output:**
|
|
@@ -427,6 +441,19 @@ Failure Rate: 12.4% ↘
|
|
|
427
441
|
○ Agent developing adaptive patterns
|
|
428
442
|
```
|
|
429
443
|
|
|
444
|
+
**Sophistication Levels:**
|
|
445
|
+
- **L1 Procedural**: Basic tool use, simple actions
|
|
446
|
+
- **L2 Self-Reflection**: Error checking, corrections, learning from failures
|
|
447
|
+
- **L3 Adaptive**: Systematic workflows, devops patterns
|
|
448
|
+
- **L4 Compositional**: Multi-constraint reasoning, complex decision-making
|
|
449
|
+
|
|
450
|
+
**View failure memories with counterfactual learning:**
|
|
451
|
+
```bash
|
|
452
|
+
npx claude-recall failures # Last 10 failures
|
|
453
|
+
npx claude-recall failures --limit 20 # Show 20 most recent
|
|
454
|
+
npx claude-recall failures --project my-app # Filter by project
|
|
455
|
+
```
|
|
456
|
+
|
|
430
457
|
**Example `failures` output:**
|
|
431
458
|
```
|
|
432
459
|
❌ Failure Memories (Counterfactual Learning)
|
|
@@ -445,11 +472,166 @@ Failure Rate: 12.4% ↘
|
|
|
445
472
|
Should Do: Use JWT tokens instead
|
|
446
473
|
```
|
|
447
474
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
-
|
|
475
|
+
### Data Management
|
|
476
|
+
|
|
477
|
+
**Export/import memories:**
|
|
478
|
+
```bash
|
|
479
|
+
npx claude-recall export memories.json # Export all memories
|
|
480
|
+
npx claude-recall export backup.json --json # Export as JSON
|
|
481
|
+
npx claude-recall import memories.json # Import memories
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Clear memories (use with caution):**
|
|
485
|
+
```bash
|
|
486
|
+
npx claude-recall clear --force # Clear everything (requires --force)
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### MCP Server Commands
|
|
490
|
+
|
|
491
|
+
**What are MCP commands?**
|
|
492
|
+
The MCP (Model Context Protocol) server is how Claude Code communicates with Claude Recall. When you install claude-recall, it automatically configures `~/.claude.json` to start the MCP server.
|
|
493
|
+
|
|
494
|
+
**Process Management (v0.7.4+):**
|
|
495
|
+
```bash
|
|
496
|
+
# Start/stop
|
|
497
|
+
npx claude-recall mcp start # Start MCP server (auto-started by Claude Code)
|
|
498
|
+
npx claude-recall mcp stop # Stop running server gracefully
|
|
499
|
+
npx claude-recall mcp restart # Restart server
|
|
500
|
+
npx claude-recall mcp test # Test MCP server functionality
|
|
501
|
+
|
|
502
|
+
# Monitoring
|
|
503
|
+
npx claude-recall mcp status # Show server status for current project
|
|
504
|
+
npx claude-recall mcp ps # List all running MCP servers (all projects)
|
|
505
|
+
|
|
506
|
+
# Cleanup
|
|
507
|
+
npx claude-recall mcp cleanup # Remove stale PID files and processes
|
|
508
|
+
npx claude-recall mcp cleanup --dry-run # Preview cleanup actions
|
|
509
|
+
npx claude-recall mcp cleanup --all # Stop all MCP servers (all projects)
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**When to use:**
|
|
513
|
+
- **Auto-started**: Claude Code automatically starts the MCP server on launch
|
|
514
|
+
- **Manual management**: Stop, restart, or cleanup stale servers as needed
|
|
515
|
+
- **Troubleshooting**: Use `mcp ps` to see running servers, `mcp cleanup` to remove zombies
|
|
516
|
+
- **Testing**: Use `mcp test` to verify the server responds correctly
|
|
517
|
+
|
|
518
|
+
### Utilities
|
|
519
|
+
|
|
520
|
+
**Check installation status:**
|
|
521
|
+
```bash
|
|
522
|
+
npx claude-recall status # Show installation and system status
|
|
523
|
+
npx claude-recall --version # Show version
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**Monitoring (advanced):**
|
|
527
|
+
```bash
|
|
528
|
+
npx claude-recall monitor # View search monitoring stats
|
|
529
|
+
npx claude-recall test-memory-search # Test if Claude searches before file creation
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Migration (if upgrading from old versions):**
|
|
533
|
+
```bash
|
|
534
|
+
npx claude-recall migrate # Migrate from file-watcher to MCP architecture
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### Global Options
|
|
538
|
+
|
|
539
|
+
All commands support:
|
|
540
|
+
- `--verbose` - Enable verbose logging
|
|
541
|
+
- `--config <path>` - Use custom config file
|
|
542
|
+
- `-h, --help` - Show help for any command
|
|
543
|
+
|
|
544
|
+
## Project Management (v0.7.5+)
|
|
545
|
+
|
|
546
|
+
Claude Recall maintains a **project registry** to track all projects using it, enabling better organization and visibility across multiple projects.
|
|
547
|
+
|
|
548
|
+
### Auto-Registration
|
|
549
|
+
|
|
550
|
+
Projects are automatically registered when:
|
|
551
|
+
- The MCP server starts (every time Claude Code connects)
|
|
552
|
+
- You run `npm install claude-recall` locally
|
|
553
|
+
- You manually run `npx claude-recall project register`
|
|
554
|
+
|
|
555
|
+
The registry stores:
|
|
556
|
+
- Project path
|
|
557
|
+
- Claude Recall version
|
|
558
|
+
- Registration date
|
|
559
|
+
- Last activity timestamp
|
|
560
|
+
|
|
561
|
+
### Project Commands
|
|
562
|
+
|
|
563
|
+
**List all registered projects:**
|
|
564
|
+
```bash
|
|
565
|
+
npx claude-recall project list # Human-friendly output
|
|
566
|
+
npx claude-recall project list --json # JSON format
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Shows:
|
|
570
|
+
- Project name and path
|
|
571
|
+
- Claude Recall version
|
|
572
|
+
- Last activity
|
|
573
|
+
- MCP server status (active/inactive)
|
|
574
|
+
|
|
575
|
+
**Show project details:**
|
|
576
|
+
```bash
|
|
577
|
+
npx claude-recall project show # Current project
|
|
578
|
+
npx claude-recall project show my-project # Specific project
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
Displays:
|
|
582
|
+
- Registry information (path, version, timestamps)
|
|
583
|
+
- MCP server status (running/stopped, PID)
|
|
584
|
+
|
|
585
|
+
**Register a project:**
|
|
586
|
+
```bash
|
|
587
|
+
npx claude-recall project register # Current directory
|
|
588
|
+
npx claude-recall project register --path /path/to/project
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**Unregister a project:**
|
|
592
|
+
```bash
|
|
593
|
+
npx claude-recall project unregister # Current project
|
|
594
|
+
npx claude-recall project unregister my-project
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
**Note**: Unregistering does NOT remove memories or MCP configuration - only the registry entry.
|
|
598
|
+
|
|
599
|
+
**Clean up stale entries:**
|
|
600
|
+
```bash
|
|
601
|
+
npx claude-recall project clean # Remove projects not seen in 30 days
|
|
602
|
+
npx claude-recall project clean --days 60 # Custom threshold
|
|
603
|
+
npx claude-recall project clean --dry-run # Preview without changes
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Enhanced MCP Commands
|
|
607
|
+
|
|
608
|
+
MCP commands now show registry information:
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
npx claude-recall mcp status # Shows registry info + MCP status
|
|
612
|
+
npx claude-recall mcp ps # Lists all servers with version info
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Registry Storage
|
|
616
|
+
|
|
617
|
+
Registry stored at: `~/.claude-recall/projects.json`
|
|
618
|
+
|
|
619
|
+
Format:
|
|
620
|
+
```json
|
|
621
|
+
{
|
|
622
|
+
"version": 1,
|
|
623
|
+
"projects": {
|
|
624
|
+
"my-project": {
|
|
625
|
+
"path": "/full/path/to/my-project",
|
|
626
|
+
"registeredAt": "2025-11-09T...",
|
|
627
|
+
"version": "0.7.5",
|
|
628
|
+
"lastSeen": "2025-11-09T..."
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**Note**: The registry is separate from your memory database. Cleaning the registry does NOT affect your stored memories.
|
|
453
635
|
|
|
454
636
|
## Project Scoping (v0.7.2+)
|
|
455
637
|
|
|
@@ -535,6 +717,71 @@ npx claude-recall stats --global
|
|
|
535
717
|
- Works like v0.7.1 and earlier
|
|
536
718
|
- Available everywhere unless you explicitly scope them
|
|
537
719
|
|
|
720
|
+
### How Project Scoping Works (Installation Location)
|
|
721
|
+
|
|
722
|
+
**Important**: Where you install claude-recall (global vs local) does NOT affect project-specific memory scoping!
|
|
723
|
+
|
|
724
|
+
**What Determines Project Scope:**
|
|
725
|
+
|
|
726
|
+
1. ✅ **Claude Code's working directory** - Where you run Claude Code
|
|
727
|
+
2. ✅ **Database scoping logic** - Filters memories by project_id
|
|
728
|
+
3. ❌ **Installation location** - Doesn't matter for scoping
|
|
729
|
+
|
|
730
|
+
**How It Works:**
|
|
731
|
+
|
|
732
|
+
```
|
|
733
|
+
# Claude Code runs in this directory:
|
|
734
|
+
/home/user/projects/my-app
|
|
735
|
+
|
|
736
|
+
# Project ID detected from directory name:
|
|
737
|
+
project_id = "my-app"
|
|
738
|
+
|
|
739
|
+
# Memories stored/searched with that project_id:
|
|
740
|
+
- "For this project, use PostgreSQL" → stored with project_id="my-app"
|
|
741
|
+
- "Remember everywhere: I prefer TypeScript" → stored with scope="universal"
|
|
742
|
+
|
|
743
|
+
# Same behavior whether claude-recall is:
|
|
744
|
+
# - Installed globally: /usr/local/lib/node_modules/claude-recall
|
|
745
|
+
# - Installed locally: ./node_modules/claude-recall
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
**Database Location (Always Global):**
|
|
749
|
+
|
|
750
|
+
Whether you install globally or locally, the database is **always** at:
|
|
751
|
+
```
|
|
752
|
+
~/.claude-recall/claude-recall.db
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
This single database contains:
|
|
756
|
+
- Project-specific memories for each project (isolated by project_id)
|
|
757
|
+
- Universal memories (available in all projects)
|
|
758
|
+
- Unscoped memories (backward compatible)
|
|
759
|
+
|
|
760
|
+
**Example: Two Projects, One Installation**
|
|
761
|
+
|
|
762
|
+
```bash
|
|
763
|
+
# Project A:
|
|
764
|
+
cd ~/projects/project-a
|
|
765
|
+
# Claude Code detects: project_id = "project-a"
|
|
766
|
+
# Memories: isolated to project-a + universal + unscoped
|
|
767
|
+
|
|
768
|
+
# Project B:
|
|
769
|
+
cd ~/projects/project-b
|
|
770
|
+
# Claude Code detects: project_id = "project-b"
|
|
771
|
+
# Memories: isolated to project-b + universal + unscoped
|
|
772
|
+
|
|
773
|
+
# Same global installation, proper isolation!
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
**WSL Users:**
|
|
777
|
+
|
|
778
|
+
This is why **global installation in WSL** works perfectly for project scoping:
|
|
779
|
+
- Code location: `/home/user/.nvm/.../bin/claude-recall` (global)
|
|
780
|
+
- Project detection: Based on Claude Code's `cwd`, NOT installation path
|
|
781
|
+
- Memory isolation: Each project gets its own memories + universal preferences
|
|
782
|
+
|
|
783
|
+
Global installation actually **helps** WSL users by avoiding binary conflicts while maintaining perfect project isolation!
|
|
784
|
+
|
|
538
785
|
## Memory Management
|
|
539
786
|
|
|
540
787
|
Claude Recall automatically manages memory to prevent unlimited database growth, with user notifications:
|
|
@@ -47,6 +47,8 @@ const search_monitor_1 = require("../services/search-monitor");
|
|
|
47
47
|
const live_test_1 = require("./commands/live-test");
|
|
48
48
|
const queue_integration_1 = require("../services/queue-integration");
|
|
49
49
|
const memory_evolution_1 = require("../services/memory-evolution");
|
|
50
|
+
const mcp_commands_1 = require("./commands/mcp-commands");
|
|
51
|
+
const project_commands_1 = require("./commands/project-commands");
|
|
50
52
|
const program = new commander_1.Command();
|
|
51
53
|
class ClaudeRecallCLI {
|
|
52
54
|
constructor(options) {
|
|
@@ -548,7 +550,7 @@ async function main() {
|
|
|
548
550
|
// MCP command
|
|
549
551
|
const mcpCmd = program
|
|
550
552
|
.command('mcp')
|
|
551
|
-
.description('MCP server commands');
|
|
553
|
+
.description('MCP server commands (start, stop, status, cleanup, ps, restart)');
|
|
552
554
|
mcpCmd
|
|
553
555
|
.command('start')
|
|
554
556
|
.description('Start Claude Recall as an MCP server')
|
|
@@ -609,6 +611,10 @@ async function main() {
|
|
|
609
611
|
process.exit(1);
|
|
610
612
|
}
|
|
611
613
|
});
|
|
614
|
+
// Register MCP process management commands
|
|
615
|
+
mcp_commands_1.MCPCommands.register(mcpCmd);
|
|
616
|
+
// Project management commands
|
|
617
|
+
project_commands_1.ProjectCommands.register(program);
|
|
612
618
|
// Migration commands
|
|
613
619
|
migrate_1.MigrateCommand.register(program);
|
|
614
620
|
// Register live test command
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MCPCommands = void 0;
|
|
7
|
+
const process_manager_1 = require("../../services/process-manager");
|
|
8
|
+
const config_1 = require("../../services/config");
|
|
9
|
+
const project_registry_1 = require("../../services/project-registry");
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
/**
|
|
12
|
+
* MCP Process Management Commands
|
|
13
|
+
*
|
|
14
|
+
* Provides CLI commands for managing MCP server processes:
|
|
15
|
+
* - status: Show MCP server status
|
|
16
|
+
* - ps: List all running MCP servers
|
|
17
|
+
* - stop: Stop MCP server
|
|
18
|
+
* - restart: Restart MCP server
|
|
19
|
+
* - cleanup: Clean up stale PID files and processes
|
|
20
|
+
*/
|
|
21
|
+
class MCPCommands {
|
|
22
|
+
constructor() {
|
|
23
|
+
this.processManager = process_manager_1.ProcessManager.getInstance();
|
|
24
|
+
this.config = config_1.ConfigService.getInstance();
|
|
25
|
+
this.projectRegistry = project_registry_1.ProjectRegistry.getInstance();
|
|
26
|
+
}
|
|
27
|
+
static register(mcpCmd) {
|
|
28
|
+
const commands = new MCPCommands();
|
|
29
|
+
// mcp status - Show current project's MCP server status
|
|
30
|
+
mcpCmd
|
|
31
|
+
.command('status')
|
|
32
|
+
.description('Show MCP server status for current project')
|
|
33
|
+
.action(async () => {
|
|
34
|
+
await commands.showStatus();
|
|
35
|
+
});
|
|
36
|
+
// mcp ps - List all running MCP servers
|
|
37
|
+
mcpCmd
|
|
38
|
+
.command('ps')
|
|
39
|
+
.description('List all running MCP servers across all projects')
|
|
40
|
+
.action(async () => {
|
|
41
|
+
await commands.listServers();
|
|
42
|
+
});
|
|
43
|
+
// mcp stop - Stop MCP server
|
|
44
|
+
mcpCmd
|
|
45
|
+
.command('stop')
|
|
46
|
+
.description('Stop MCP server')
|
|
47
|
+
.option('--project <id>', 'Stop specific project server (default: current project)')
|
|
48
|
+
.option('--force', 'Force kill (SIGKILL) instead of graceful shutdown (SIGTERM)')
|
|
49
|
+
.action(async (options) => {
|
|
50
|
+
await commands.stopServer(options);
|
|
51
|
+
});
|
|
52
|
+
// mcp restart - Restart MCP server
|
|
53
|
+
mcpCmd
|
|
54
|
+
.command('restart')
|
|
55
|
+
.description('Restart MCP server for current project')
|
|
56
|
+
.option('--force', 'Force kill before restart')
|
|
57
|
+
.action(async (options) => {
|
|
58
|
+
await commands.restartServer(options);
|
|
59
|
+
});
|
|
60
|
+
// mcp cleanup - Clean up stale processes and PID files
|
|
61
|
+
mcpCmd
|
|
62
|
+
.command('cleanup')
|
|
63
|
+
.description('Clean up stale PID files and processes')
|
|
64
|
+
.option('--dry-run', 'Show what would be cleaned without making changes')
|
|
65
|
+
.option('--all', 'Stop all running MCP servers')
|
|
66
|
+
.option('--force', 'Force kill processes')
|
|
67
|
+
.action(async (options) => {
|
|
68
|
+
await commands.cleanup(options);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Show status of MCP server for current project
|
|
73
|
+
*/
|
|
74
|
+
async showStatus() {
|
|
75
|
+
const projectId = this.config.getProjectId();
|
|
76
|
+
const status = this.processManager.getServerStatus(projectId);
|
|
77
|
+
const registryEntry = this.projectRegistry.get(projectId);
|
|
78
|
+
console.log(chalk_1.default.cyan('\n📊 MCP Server Status\n'));
|
|
79
|
+
console.log(`Project: ${chalk_1.default.yellow(projectId)}`);
|
|
80
|
+
console.log(`Status: ${status.isRunning ? chalk_1.default.green('✓ Running') : chalk_1.default.gray('✗ Stopped')}`);
|
|
81
|
+
if (status.pid !== null) {
|
|
82
|
+
console.log(`PID: ${chalk_1.default.yellow(status.pid)}`);
|
|
83
|
+
if (!status.isRunning) {
|
|
84
|
+
console.log(chalk_1.default.gray(` (stale PID file exists)`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
console.log(`PID File: ${chalk_1.default.gray(status.pidFile)}`);
|
|
88
|
+
// Show registry information if available
|
|
89
|
+
if (registryEntry) {
|
|
90
|
+
console.log();
|
|
91
|
+
console.log(chalk_1.default.bold('Registry Info:'));
|
|
92
|
+
console.log(` Version: ${chalk_1.default.gray(registryEntry.version)}`);
|
|
93
|
+
console.log(` Path: ${chalk_1.default.gray(registryEntry.path)}`);
|
|
94
|
+
console.log(` Registered: ${chalk_1.default.gray(new Date(registryEntry.registeredAt).toLocaleString())}`);
|
|
95
|
+
console.log(` Last Seen: ${chalk_1.default.gray(new Date(registryEntry.lastSeen).toLocaleString())}`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log();
|
|
99
|
+
console.log(chalk_1.default.yellow('⚠ Project not registered in registry'));
|
|
100
|
+
console.log(chalk_1.default.gray(' Run `npx claude-recall project register` to register'));
|
|
101
|
+
}
|
|
102
|
+
console.log();
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* List all running MCP servers across projects
|
|
106
|
+
*/
|
|
107
|
+
async listServers() {
|
|
108
|
+
const servers = this.processManager.getAllRunningServers();
|
|
109
|
+
const registeredProjects = this.projectRegistry.list();
|
|
110
|
+
console.log(chalk_1.default.cyan('\n📋 MCP Servers & Registered Projects\n'));
|
|
111
|
+
if (servers.length === 0 && registeredProjects.length === 0) {
|
|
112
|
+
console.log(chalk_1.default.gray('No MCP servers or registered projects found.'));
|
|
113
|
+
console.log();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const runningServers = servers.filter(s => s.isRunning);
|
|
117
|
+
const staleServers = servers.filter(s => !s.isRunning);
|
|
118
|
+
if (runningServers.length > 0) {
|
|
119
|
+
console.log(chalk_1.default.green(`✓ Running (${runningServers.length}):`));
|
|
120
|
+
for (const server of runningServers) {
|
|
121
|
+
const registryEntry = this.projectRegistry.get(server.projectId);
|
|
122
|
+
const versionInfo = registryEntry ? ` [v${registryEntry.version}]` : '';
|
|
123
|
+
console.log(` ${chalk_1.default.yellow(server.projectId.padEnd(40))} PID: ${chalk_1.default.cyan(server.pid)}${chalk_1.default.gray(versionInfo)}`);
|
|
124
|
+
}
|
|
125
|
+
console.log();
|
|
126
|
+
}
|
|
127
|
+
if (staleServers.length > 0) {
|
|
128
|
+
console.log(chalk_1.default.gray(`✗ Stale (${staleServers.length}):`));
|
|
129
|
+
for (const server of staleServers) {
|
|
130
|
+
console.log(` ${chalk_1.default.gray(server.projectId.padEnd(40))} PID: ${chalk_1.default.gray(server.pid)} (not running)`);
|
|
131
|
+
}
|
|
132
|
+
console.log();
|
|
133
|
+
console.log(chalk_1.default.yellow(`💡 Run 'npx claude-recall mcp cleanup' to remove stale PID files`));
|
|
134
|
+
console.log();
|
|
135
|
+
}
|
|
136
|
+
// Show registered projects that don't have running servers
|
|
137
|
+
const runningProjectIds = new Set(runningServers.map(s => s.projectId));
|
|
138
|
+
const inactiveProjects = registeredProjects.filter(({ projectId }) => !runningProjectIds.has(projectId));
|
|
139
|
+
if (inactiveProjects.length > 0) {
|
|
140
|
+
console.log(chalk_1.default.gray(`📂 Registered but Inactive (${inactiveProjects.length}):`));
|
|
141
|
+
for (const { projectId, entry } of inactiveProjects) {
|
|
142
|
+
console.log(` ${chalk_1.default.gray(projectId.padEnd(40))} v${entry.version}`);
|
|
143
|
+
}
|
|
144
|
+
console.log();
|
|
145
|
+
console.log(chalk_1.default.gray(`💡 Run 'npx claude-recall project list' for detailed registry info`));
|
|
146
|
+
console.log();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Stop MCP server
|
|
151
|
+
*/
|
|
152
|
+
async stopServer(options) {
|
|
153
|
+
const projectId = options.project || this.config.getProjectId();
|
|
154
|
+
const status = this.processManager.getServerStatus(projectId);
|
|
155
|
+
console.log(chalk_1.default.cyan('\n🛑 Stopping MCP Server\n'));
|
|
156
|
+
console.log(`Project: ${chalk_1.default.yellow(projectId)}`);
|
|
157
|
+
if (!status.isRunning) {
|
|
158
|
+
if (status.pid !== null) {
|
|
159
|
+
console.log(chalk_1.default.yellow('⚠ Server not running, but stale PID file exists'));
|
|
160
|
+
console.log('Removing stale PID file...');
|
|
161
|
+
this.processManager.removePidFile(projectId);
|
|
162
|
+
console.log(chalk_1.default.green('✓ Stale PID file removed'));
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(chalk_1.default.gray('✗ Server not running'));
|
|
166
|
+
}
|
|
167
|
+
console.log();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const signal = options.force ? 'SIGKILL' : 'SIGTERM';
|
|
171
|
+
console.log(`Sending ${signal} to PID ${chalk_1.default.yellow(status.pid)}...`);
|
|
172
|
+
try {
|
|
173
|
+
this.processManager.killProcess(status.pid, options.force || false);
|
|
174
|
+
this.processManager.removePidFile(projectId);
|
|
175
|
+
// Give it a moment to shut down
|
|
176
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
177
|
+
// Verify it stopped
|
|
178
|
+
const newStatus = this.processManager.getServerStatus(projectId);
|
|
179
|
+
if (!newStatus.isRunning) {
|
|
180
|
+
console.log(chalk_1.default.green('✓ Server stopped successfully'));
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
console.log(chalk_1.default.yellow('⚠ Server may still be running. Try --force flag.'));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
console.log(chalk_1.default.red(`✗ Failed to stop server: ${error}`));
|
|
188
|
+
}
|
|
189
|
+
console.log();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Restart MCP server
|
|
193
|
+
*/
|
|
194
|
+
async restartServer(options) {
|
|
195
|
+
const projectId = this.config.getProjectId();
|
|
196
|
+
const status = this.processManager.getServerStatus(projectId);
|
|
197
|
+
console.log(chalk_1.default.cyan('\n🔄 Restarting MCP Server\n'));
|
|
198
|
+
console.log(`Project: ${chalk_1.default.yellow(projectId)}`);
|
|
199
|
+
if (status.isRunning) {
|
|
200
|
+
console.log('Stopping current server...');
|
|
201
|
+
await this.stopServer({ force: options.force });
|
|
202
|
+
// Wait a bit longer for graceful shutdown
|
|
203
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
204
|
+
}
|
|
205
|
+
console.log('\nTo start the server, run:');
|
|
206
|
+
console.log(chalk_1.default.cyan(' npx claude-recall mcp start'));
|
|
207
|
+
console.log();
|
|
208
|
+
console.log(chalk_1.default.gray('Note: The MCP server is normally started automatically by Claude Code.'));
|
|
209
|
+
console.log(chalk_1.default.gray(' You only need to run this manually for debugging purposes.'));
|
|
210
|
+
console.log();
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Clean up stale PID files and optionally stop all servers
|
|
214
|
+
*/
|
|
215
|
+
async cleanup(options) {
|
|
216
|
+
console.log(chalk_1.default.cyan('\n🧹 MCP Server Cleanup\n'));
|
|
217
|
+
if (options.dryRun) {
|
|
218
|
+
console.log(chalk_1.default.yellow('DRY RUN MODE - No changes will be made\n'));
|
|
219
|
+
}
|
|
220
|
+
if (options.all) {
|
|
221
|
+
console.log(chalk_1.default.yellow('⚠ Stopping ALL MCP servers...\n'));
|
|
222
|
+
const stopped = this.processManager.stopAllServers(options.dryRun || false, options.force || false);
|
|
223
|
+
if (options.dryRun) {
|
|
224
|
+
console.log(chalk_1.default.gray(`Would stop ${stopped} server(s)`));
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
console.log(chalk_1.default.green(`✓ Stopped ${stopped} server(s)`));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
console.log('Cleaning up stale PID files...\n');
|
|
232
|
+
const cleaned = this.processManager.cleanupStalePidFiles(options.dryRun || false);
|
|
233
|
+
if (cleaned === 0) {
|
|
234
|
+
console.log(chalk_1.default.green('✓ No stale PID files found'));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
if (options.dryRun) {
|
|
238
|
+
console.log(chalk_1.default.gray(`\nWould remove ${cleaned} stale PID file(s)`));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
console.log(chalk_1.default.green(`\n✓ Removed ${cleaned} stale PID file(s)`));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
console.log();
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.MCPCommands = MCPCommands;
|