mirror of
https://github.com/samvallad33/vestige.git
synced 2026-05-09 07:42:37 +02:00
fix(npm): download binaries during postinstall
The npm package was missing the actual binary download step - users got wrapper scripts pointing to non-existent binaries. Changes: - postinstall.js now downloads correct binary from GitHub releases - Added vestige.js wrapper for CLI binary - Exposed both vestige-mcp and vestige commands in package.json - Updated README with troubleshooting, storage info, CLI docs - Added .gitignore for downloaded binaries Fixes fresh install issues where Claude Desktop couldn't attach and vestige CLI wasn't found. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e5b27ff1e5
commit
1e06344319
6 changed files with 278 additions and 24 deletions
7
packages/vestige-mcp-npm/.gitignore
vendored
Normal file
7
packages/vestige-mcp-npm/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Downloaded binaries (installed via postinstall)
|
||||||
|
bin/vestige
|
||||||
|
bin/vestige.exe
|
||||||
|
bin/vestige-mcp
|
||||||
|
bin/vestige-mcp.exe
|
||||||
|
bin/*.tar.gz
|
||||||
|
bin/*.zip
|
||||||
|
|
@ -10,6 +10,29 @@ Built on 130 years of cognitive science research, Vestige provides biologically-
|
||||||
npm install -g @vestige/mcp
|
npm install -g @vestige/mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This automatically downloads the correct binary for your platform (macOS, Linux, Windows) from GitHub releases.
|
||||||
|
|
||||||
|
### What gets installed
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `vestige-mcp` | MCP server for Claude integration |
|
||||||
|
| `vestige` | CLI for stats, health checks, and maintenance |
|
||||||
|
|
||||||
|
### Verify installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vestige health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage with Claude Code
|
||||||
|
|
||||||
|
```bash
|
||||||
|
claude mcp add vestige vestige-mcp -s user
|
||||||
|
```
|
||||||
|
|
||||||
|
Then restart Claude.
|
||||||
|
|
||||||
## Usage with Claude Desktop
|
## Usage with Claude Desktop
|
||||||
|
|
||||||
Add to your Claude Desktop configuration:
|
Add to your Claude Desktop configuration:
|
||||||
|
|
@ -21,30 +44,48 @@ Add to your Claude Desktop configuration:
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vestige": {
|
"vestige": {
|
||||||
"command": "vestige-mcp",
|
"command": "vestige-mcp"
|
||||||
"args": ["--project", "."]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## CLI Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
vestige stats # Memory statistics
|
||||||
|
vestige stats --states # Cognitive state distribution
|
||||||
|
vestige health # System health check
|
||||||
|
vestige consolidate # Run memory maintenance cycle
|
||||||
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **FSRS-6 Algorithm**: State-of-the-art spaced repetition for optimal memory retention
|
- **FSRS-6 Algorithm**: State-of-the-art spaced repetition for optimal memory retention
|
||||||
- **Dual-Strength Memory**: Bjork & Bjork (1992) - Storage + Retrieval strength model
|
- **Dual-Strength Memory**: Bjork & Bjork (1992) - Storage + Retrieval strength model
|
||||||
- **Sleep Consolidation**: Bio-inspired memory optimization cycles
|
- **Synaptic Tagging**: Memories become important retroactively (Frey & Morris 1997)
|
||||||
- **Semantic Search**: Local embeddings for intelligent memory retrieval
|
- **Semantic Search**: Local embeddings via nomic-embed-text-v1.5 (768 dimensions)
|
||||||
- **Local-First**: All data stays on your machine
|
- **Local-First**: All data stays on your machine - no cloud, no API costs
|
||||||
|
|
||||||
## MCP Tools
|
## Storage & Memory
|
||||||
|
|
||||||
| Tool | Description |
|
Vestige uses SQLite for storage. Your memories are stored on **disk**, not in RAM.
|
||||||
|------|-------------|
|
|
||||||
| `remember` | Store a new memory with importance scoring |
|
- **Database limit**: 216TB (SQLite theoretical max)
|
||||||
| `recall` | Retrieve memories by semantic similarity |
|
- **RAM usage**: ~64MB cache (configurable)
|
||||||
| `search` | Full-text search across all memories |
|
- **Typical usage**: 1 million memories ≈ 1-2GB on disk
|
||||||
| `consolidate` | Trigger memory consolidation (sleep cycle) |
|
|
||||||
| `get_context` | Get relevant context for current project |
|
You'll never run out of space. A heavy user creating 100 memories/day would use ~1.5GB after 10 years.
|
||||||
|
|
||||||
|
## Embeddings
|
||||||
|
|
||||||
|
On first use, Vestige downloads the nomic-embed-text-v1.5 model (~130MB). This is a one-time download and all subsequent operations are fully offline.
|
||||||
|
|
||||||
|
The model is stored in `.fastembed_cache/` in your working directory, or you can set a global location:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export FASTEMBED_CACHE_PATH="$HOME/.fastembed_cache"
|
||||||
|
```
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
|
|
@ -52,6 +93,36 @@ Add to your Claude Desktop configuration:
|
||||||
|----------|-------------|---------|
|
|----------|-------------|---------|
|
||||||
| `VESTIGE_DATA_DIR` | Data storage directory | `~/.vestige` |
|
| `VESTIGE_DATA_DIR` | Data storage directory | `~/.vestige` |
|
||||||
| `VESTIGE_LOG_LEVEL` | Log verbosity | `info` |
|
| `VESTIGE_LOG_LEVEL` | Log verbosity | `info` |
|
||||||
|
| `FASTEMBED_CACHE_PATH` | Embeddings model location | `./.fastembed_cache` |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Could not attach to MCP server vestige"
|
||||||
|
|
||||||
|
1. Verify binary exists: `which vestige-mcp`
|
||||||
|
2. Test directly: `vestige-mcp` (should wait for stdio input)
|
||||||
|
3. Check Claude logs: `~/Library/Logs/Claude/` (macOS)
|
||||||
|
|
||||||
|
### "vestige: command not found"
|
||||||
|
|
||||||
|
Reinstall the package:
|
||||||
|
```bash
|
||||||
|
npm install -g @vestige/mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Embeddings not downloading
|
||||||
|
|
||||||
|
The model downloads on first `ingest` or `search` operation. If Claude can't connect to the MCP server, no memory operations happen and no model downloads.
|
||||||
|
|
||||||
|
Fix the MCP connection first, then the model will download automatically.
|
||||||
|
|
||||||
|
## Supported Platforms
|
||||||
|
|
||||||
|
| Platform | Architecture |
|
||||||
|
|----------|--------------|
|
||||||
|
| macOS | ARM64 (Apple Silicon) |
|
||||||
|
| Linux | x86_64 |
|
||||||
|
| Windows | x86_64 |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,30 @@
|
||||||
|
|
||||||
const { spawn } = require('child_process');
|
const { spawn } = require('child_process');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
|
|
||||||
const platform = os.platform();
|
const platform = os.platform();
|
||||||
const arch = os.arch();
|
|
||||||
|
|
||||||
const binaryName = platform === 'win32' ? 'vestige-mcp.exe' : 'vestige-mcp';
|
const binaryName = platform === 'win32' ? 'vestige-mcp.exe' : 'vestige-mcp';
|
||||||
const binaryPath = path.join(__dirname, '..', 'bin', binaryName);
|
const binaryPath = path.join(__dirname, binaryName);
|
||||||
|
|
||||||
|
if (!fs.existsSync(binaryPath)) {
|
||||||
|
console.error('Error: vestige-mcp binary not found.');
|
||||||
|
console.error(`Expected at: ${binaryPath}`);
|
||||||
|
console.error('');
|
||||||
|
console.error('Try reinstalling: npm install -g @vestige/mcp');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
const child = spawn(binaryPath, process.argv.slice(2), {
|
const child = spawn(binaryPath, process.argv.slice(2), {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
child.on('error', (err) => {
|
||||||
|
console.error('Failed to start vestige-mcp:', err.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
child.on('exit', (code) => {
|
child.on('exit', (code) => {
|
||||||
process.exit(code ?? 0);
|
process.exit(code ?? 0);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
31
packages/vestige-mcp-npm/bin/vestige.js
Executable file
31
packages/vestige-mcp-npm/bin/vestige.js
Executable file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { spawn } = require('child_process');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
const platform = os.platform();
|
||||||
|
const binaryName = platform === 'win32' ? 'vestige.exe' : 'vestige';
|
||||||
|
const binaryPath = path.join(__dirname, binaryName);
|
||||||
|
|
||||||
|
if (!fs.existsSync(binaryPath)) {
|
||||||
|
console.error('Error: vestige CLI binary not found.');
|
||||||
|
console.error(`Expected at: ${binaryPath}`);
|
||||||
|
console.error('');
|
||||||
|
console.error('Try reinstalling: npm install -g @vestige/mcp');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = spawn(binaryPath, process.argv.slice(2), {
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', (err) => {
|
||||||
|
console.error('Failed to start vestige:', err.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', (code) => {
|
||||||
|
process.exit(code ?? 0);
|
||||||
|
});
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
{
|
{
|
||||||
"name": "@vestige/mcp",
|
"name": "@vestige/mcp",
|
||||||
"version": "0.1.0",
|
"version": "1.1.0",
|
||||||
"description": "Vestige MCP Server - AI Memory System for Claude and other assistants",
|
"description": "Vestige MCP Server - AI Memory System for Claude and other assistants",
|
||||||
"bin": {
|
"bin": {
|
||||||
"vestige-mcp": "./bin/vestige-mcp.js"
|
"vestige-mcp": "./bin/vestige-mcp.js",
|
||||||
|
"vestige": "./bin/vestige.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "node scripts/postinstall.js"
|
"postinstall": "node scripts/postinstall.js"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
@ -24,18 +26,148 @@ const archStr = ARCH_MAP[ARCH];
|
||||||
|
|
||||||
if (!platformStr || !archStr) {
|
if (!platformStr || !archStr) {
|
||||||
console.error(`Unsupported platform: ${PLATFORM}-${ARCH}`);
|
console.error(`Unsupported platform: ${PLATFORM}-${ARCH}`);
|
||||||
|
console.error('Supported: darwin/linux/win32 on x64/arm64');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const binaryName = PLATFORM === 'win32' ? 'vestige-mcp.exe' : 'vestige-mcp';
|
const target = `${archStr}-${platformStr}`;
|
||||||
const targetDir = path.join(__dirname, '..', 'bin');
|
const isWindows = PLATFORM === 'win32';
|
||||||
const targetPath = path.join(targetDir, binaryName);
|
const archiveExt = isWindows ? 'zip' : 'tar.gz';
|
||||||
|
const archiveName = `vestige-mcp-${target}.${archiveExt}`;
|
||||||
|
const downloadUrl = `https://github.com/samvallad33/vestige/releases/download/v${VERSION}/${archiveName}`;
|
||||||
|
|
||||||
// For now, just create a placeholder - real binaries come from GitHub releases
|
const targetDir = path.join(__dirname, '..', 'bin');
|
||||||
console.log(`Vestige MCP v${VERSION} installed for ${archStr}-${platformStr}`);
|
const archivePath = path.join(targetDir, archiveName);
|
||||||
console.log(`Binary location: ${targetPath}`);
|
|
||||||
|
console.log(`Installing Vestige MCP v${VERSION} for ${target}...`);
|
||||||
|
|
||||||
// Ensure bin directory exists
|
// Ensure bin directory exists
|
||||||
if (!fs.existsSync(targetDir)) {
|
if (!fs.existsSync(targetDir)) {
|
||||||
fs.mkdirSync(targetDir, { recursive: true });
|
fs.mkdirSync(targetDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a file following redirects (GitHub releases use redirects)
|
||||||
|
*/
|
||||||
|
function download(url, dest) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const file = fs.createWriteStream(dest);
|
||||||
|
|
||||||
|
const request = (currentUrl) => {
|
||||||
|
https.get(currentUrl, (response) => {
|
||||||
|
// Handle redirects (GitHub uses 302)
|
||||||
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
||||||
|
const redirectUrl = response.headers.location;
|
||||||
|
if (!redirectUrl) {
|
||||||
|
reject(new Error('Redirect without location header'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
request(redirectUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
reject(new Error(`Download failed: HTTP ${response.statusCode}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.pipe(file);
|
||||||
|
file.on('finish', () => {
|
||||||
|
file.close();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}).on('error', (err) => {
|
||||||
|
fs.unlink(dest, () => {}); // Delete partial file
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
request(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract archive based on platform
|
||||||
|
*/
|
||||||
|
function extract(archivePath, destDir) {
|
||||||
|
if (isWindows) {
|
||||||
|
// Use PowerShell to extract zip on Windows
|
||||||
|
execSync(
|
||||||
|
`powershell -Command "Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force"`,
|
||||||
|
{ stdio: 'inherit' }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Use tar on Unix
|
||||||
|
execSync(`tar -xzf "${archivePath}" -C "${destDir}"`, { stdio: 'inherit' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make binaries executable (Unix only)
|
||||||
|
*/
|
||||||
|
function makeExecutable(binDir) {
|
||||||
|
if (isWindows) return;
|
||||||
|
|
||||||
|
const binaries = ['vestige-mcp', 'vestige'];
|
||||||
|
for (const bin of binaries) {
|
||||||
|
const binPath = path.join(binDir, bin);
|
||||||
|
if (fs.existsSync(binPath)) {
|
||||||
|
fs.chmodSync(binPath, 0o755);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
// Download
|
||||||
|
console.log(`Downloading from ${downloadUrl}...`);
|
||||||
|
await download(downloadUrl, archivePath);
|
||||||
|
console.log('Download complete.');
|
||||||
|
|
||||||
|
// Extract
|
||||||
|
console.log('Extracting binaries...');
|
||||||
|
extract(archivePath, targetDir);
|
||||||
|
|
||||||
|
// Cleanup archive
|
||||||
|
fs.unlinkSync(archivePath);
|
||||||
|
|
||||||
|
// Make executable
|
||||||
|
makeExecutable(targetDir);
|
||||||
|
|
||||||
|
// Verify installation
|
||||||
|
const mcpBinary = path.join(targetDir, isWindows ? 'vestige-mcp.exe' : 'vestige-mcp');
|
||||||
|
const cliBinary = path.join(targetDir, isWindows ? 'vestige.exe' : 'vestige');
|
||||||
|
|
||||||
|
if (!fs.existsSync(mcpBinary)) {
|
||||||
|
throw new Error('vestige-mcp binary not found after extraction');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('Vestige MCP installed successfully!');
|
||||||
|
console.log('');
|
||||||
|
console.log('Binaries installed:');
|
||||||
|
console.log(` - vestige-mcp: ${mcpBinary}`);
|
||||||
|
if (fs.existsSync(cliBinary)) {
|
||||||
|
console.log(` - vestige: ${cliBinary}`);
|
||||||
|
}
|
||||||
|
console.log('');
|
||||||
|
console.log('Next steps:');
|
||||||
|
console.log(' 1. Add to Claude: claude mcp add vestige vestige-mcp -s user');
|
||||||
|
console.log(' 2. Restart Claude');
|
||||||
|
console.log(' 3. Test with: "remember that my favorite color is blue"');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error('');
|
||||||
|
console.error('Installation failed:', err.message);
|
||||||
|
console.error('');
|
||||||
|
console.error('Manual installation:');
|
||||||
|
console.error(` 1. Download: ${downloadUrl}`);
|
||||||
|
console.error(` 2. Extract to: ${targetDir}`);
|
||||||
|
console.error(' 3. Ensure binaries are executable (chmod +x on Unix)');
|
||||||
|
console.error('');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue