Simplify Windows fix: use idempotent npm install instead of custom installer
Co-authored-by: thedotmack <683968+thedotmack@users.noreply.github.com>
This commit is contained in:
+1
-2
@@ -7,5 +7,4 @@ node_modules/
|
||||
*.temp
|
||||
.claude/settings.local.json
|
||||
plugin/data/
|
||||
plugin/data.backup/
|
||||
plugin/scripts/package-lock.json
|
||||
plugin/data.backup/
|
||||
+7
-11
@@ -9,19 +9,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
### Fixed
|
||||
- **Windows PowerShell compatibility**: Fixed SessionStart hook error on Windows systems
|
||||
- Replaced bash-specific command (`[`, `&&`, `||`) with cross-platform Node.js installer
|
||||
- Created `ensure-dependencies.js` script for automatic dependency installation
|
||||
- Dependencies (`better-sqlite3`) now install correctly on Windows, macOS, and Linux
|
||||
|
||||
### Added
|
||||
- **Cross-platform dependency installer**: New `ensure-dependencies.js` script handles runtime dependency installation
|
||||
- **Automatic package.json generation**: Build process now creates `package.json` in `plugin/scripts/` directory
|
||||
- **Enhanced build output**: Build script now generates installer alongside hooks and services
|
||||
- Replaced bash-specific test command `[` with standard cross-platform npm install
|
||||
- Simplified hook command to use idempotent npm install (fast when dependencies exist)
|
||||
- Dependencies install from root package.json in marketplace folder
|
||||
|
||||
### Changed
|
||||
- **SessionStart hook command**: Now uses `node ensure-dependencies.js && node context-hook.js` instead of bash syntax
|
||||
- **Build process**: Added installer script bundling and package.json generation steps
|
||||
- **.gitignore**: Added `plugin/scripts/package-lock.json` to prevent version control conflicts
|
||||
- **SessionStart hook command**: Now uses `cd ... && npm install --prefer-offline --no-audit --no-fund --loglevel=error && node context-hook.js`
|
||||
- Removed bash-specific conditional check
|
||||
- npm install is fast (~500ms) and idempotent when dependencies already exist
|
||||
- Works cross-platform on Windows, macOS, and Linux
|
||||
|
||||
|
||||
## [4.2.1] - 2025-10-22
|
||||
|
||||
@@ -26,7 +26,7 @@ This creates a continuous memory system where Claude can learn from past session
|
||||
Claude-mem integrates with Claude Code through 5 lifecycle hooks:
|
||||
|
||||
1. **SessionStart Hook** (`context-hook`)
|
||||
- Auto-installs dependencies on first run (cross-platform Node.js installer)
|
||||
- Ensures dependencies are installed (runs fast idempotent npm install)
|
||||
- Injects context from previous sessions
|
||||
- Auto-starts PM2 worker service
|
||||
- Retrieves last 10 session summaries with three-tier verbosity (v4.2.0)
|
||||
@@ -201,16 +201,12 @@ npm run build && git commit -a -m "Build and update" && git push && cd ~/.claude
|
||||
```
|
||||
|
||||
1) Compiles TypeScript and outputs hook executables to `plugin/scripts/`
|
||||
2) Generates `ensure-dependencies.js` - cross-platform installer script
|
||||
3) Creates `package.json` in `plugin/scripts/` with runtime dependencies
|
||||
4) Does all the things needed to update and test since plugin-based installs are out of the .claude/ folder
|
||||
2) Does all the things needed to update and test since plugin-based installs are out of the .claude/ folder
|
||||
|
||||
**Build Outputs**:
|
||||
- Hook executables: `*-hook.js` (ESM format)
|
||||
- Worker service: `worker-service.cjs` (CJS format)
|
||||
- Search server: `search-server.js` (ESM format)
|
||||
- Dependency installer: `ensure-dependencies.js` (ESM format)
|
||||
- Runtime manifest: `package.json` (includes `better-sqlite3` dependency)
|
||||
|
||||
## Version History
|
||||
|
||||
@@ -219,15 +215,14 @@ npm run build && git commit -a -m "Build and update" && git push && cd ~/.claude
|
||||
|
||||
**Fixes**:
|
||||
- Fixed Windows PowerShell compatibility issue with SessionStart hook
|
||||
- Replaced bash-specific installation command with cross-platform Node.js installer
|
||||
- Added `ensure-dependencies.js` script for automatic dependency installation
|
||||
- Build process now generates `package.json` with runtime dependencies in `plugin/scripts/`
|
||||
- Replaced bash-specific test command `[` with cross-platform npm install command
|
||||
- Hook now runs `npm install` with quiet flags (fast and idempotent when dependencies exist)
|
||||
|
||||
**Technical Details**:
|
||||
- Created `src/bin/ensure-dependencies.ts` for cross-platform dependency management
|
||||
- Updated `plugin/hooks/hooks.json` to use Node.js command chain instead of shell syntax
|
||||
- Dependencies (`better-sqlite3`) are now installed automatically on first run across all platforms
|
||||
- Added `.gitignore` rule for `plugin/scripts/package-lock.json`
|
||||
- Updated `plugin/hooks/hooks.json` SessionStart command to use standard shell syntax
|
||||
- Changed from: `[ ! -d ... ] && cd ... && npm install && node ... || node ...`
|
||||
- Changed to: `cd ... && npm install --prefer-offline --no-audit --no-fund --loglevel=error && node ...`
|
||||
- Dependencies are installed in marketplace folder (parent of CLAUDE_PLUGIN_ROOT) where root package.json exists
|
||||
|
||||
### v4.2.0
|
||||
**Breaking Changes**: None (minor version)
|
||||
|
||||
@@ -255,7 +255,7 @@ npm install -g claude-mem
|
||||
|
||||
1. **Automatic Dependency Installation**
|
||||
|
||||
The plugin automatically installs required dependencies (`better-sqlite3`) on first run. This happens when you first start Claude Code after installation. The process is cross-platform and works on Windows, macOS, and Linux.
|
||||
Dependencies are installed automatically during plugin installation. The SessionStart hook also ensures dependencies are up-to-date on each session start (this is fast and idempotent). Works cross-platform on Windows, macOS, and Linux.
|
||||
|
||||
2. **Verify Plugin Installation**
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/ensure-dependencies.js && node ${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js",
|
||||
"command": "cd \"${CLAUDE_PLUGIN_ROOT}/..\" && npm install --prefer-offline --no-audit --no-fund --loglevel=error && node ${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js",
|
||||
"timeout": 120
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// src/bin/ensure-dependencies.ts
|
||||
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
||||
import { join, dirname } from "path";
|
||||
import { execSync } from "child_process";
|
||||
import { fileURLToPath } from "url";
|
||||
function getDirname() {
|
||||
return typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
|
||||
}
|
||||
var scriptDir = getDirname();
|
||||
var isBuilt = scriptDir.includes("plugin/scripts") || scriptDir.includes("plugin\\scripts");
|
||||
var targetDir = isBuilt ? scriptDir : join(scriptDir, "../../plugin/scripts");
|
||||
var nodeModulesPath = join(targetDir, "node_modules");
|
||||
var packageJsonPath = join(targetDir, "package.json");
|
||||
if (existsSync(nodeModulesPath)) {
|
||||
const betterSqlitePath = join(nodeModulesPath, "better-sqlite3");
|
||||
if (existsSync(betterSqlitePath)) {
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
if (!existsSync(targetDir)) {
|
||||
mkdirSync(targetDir, { recursive: true });
|
||||
}
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
const packageJson = {
|
||||
name: "claude-mem-scripts",
|
||||
version: "4.2.1",
|
||||
description: "Runtime dependencies for claude-mem plugin hooks",
|
||||
private: true,
|
||||
type: "module",
|
||||
dependencies: {
|
||||
"better-sqlite3": "^11.0.0"
|
||||
}
|
||||
};
|
||||
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
}
|
||||
try {
|
||||
console.log("Installing claude-mem dependencies...");
|
||||
execSync("npm install --prefer-offline --no-audit --no-fund --loglevel error", {
|
||||
cwd: targetDir,
|
||||
stdio: "inherit"
|
||||
});
|
||||
console.log("Dependencies installed successfully.");
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error("Failed to install dependencies:", error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "claude-mem-scripts",
|
||||
"version": "4.2.1",
|
||||
"description": "Runtime dependencies for claude-mem plugin hooks",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^11.0.0"
|
||||
}
|
||||
}
|
||||
@@ -30,11 +30,6 @@ const SEARCH_SERVER = {
|
||||
source: 'src/servers/search-server.ts'
|
||||
};
|
||||
|
||||
const INSTALLER = {
|
||||
name: 'ensure-dependencies',
|
||||
source: 'src/bin/ensure-dependencies.ts'
|
||||
};
|
||||
|
||||
async function buildHooks() {
|
||||
console.log('🔨 Building claude-mem hooks, worker service, and search server...\n');
|
||||
|
||||
@@ -133,52 +128,11 @@ async function buildHooks() {
|
||||
const searchStats = fs.statSync(`${hooksDir}/${SEARCH_SERVER.name}.js`);
|
||||
console.log(`✓ search-server built (${(searchStats.size / 1024).toFixed(2)} KB)`);
|
||||
|
||||
// Build dependency installer
|
||||
console.log(`\n🔧 Building dependency installer...`);
|
||||
await build({
|
||||
entryPoints: [INSTALLER.source],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
target: 'node18',
|
||||
format: 'esm',
|
||||
outfile: `${hooksDir}/${INSTALLER.name}.js`,
|
||||
minify: false, // Keep readable for debugging
|
||||
banner: {
|
||||
js: '#!/usr/bin/env node'
|
||||
}
|
||||
});
|
||||
|
||||
// Make installer executable
|
||||
fs.chmodSync(`${hooksDir}/${INSTALLER.name}.js`, 0o755);
|
||||
const installerStats = fs.statSync(`${hooksDir}/${INSTALLER.name}.js`);
|
||||
console.log(`✓ installer built (${(installerStats.size / 1024).toFixed(2)} KB)`);
|
||||
|
||||
// Create package.json for plugin/scripts
|
||||
console.log('\n📦 Creating package.json...');
|
||||
const scriptsPackageJson = {
|
||||
name: 'claude-mem-scripts',
|
||||
version: version,
|
||||
description: 'Runtime dependencies for claude-mem plugin hooks',
|
||||
private: true,
|
||||
type: 'module',
|
||||
dependencies: {
|
||||
'better-sqlite3': '^11.0.0'
|
||||
}
|
||||
};
|
||||
|
||||
fs.writeFileSync(
|
||||
`${hooksDir}/package.json`,
|
||||
JSON.stringify(scriptsPackageJson, null, 2)
|
||||
);
|
||||
console.log('✓ package.json created');
|
||||
|
||||
console.log('\n✅ All hooks, worker service, and search server built successfully!');
|
||||
console.log(` Output: ${hooksDir}/`);
|
||||
console.log(` - Hooks: *-hook.js`);
|
||||
console.log(` - Worker: worker-service.cjs`);
|
||||
console.log(` - Search: search-server.js`);
|
||||
console.log(` - Installer: ensure-dependencies.js`);
|
||||
console.log(` - Dependencies: package.json`);
|
||||
console.log('\n💡 Note: Dependencies will be auto-installed on first hook execution');
|
||||
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
* Cross-platform dependency installer for claude-mem plugin hooks
|
||||
* Ensures better-sqlite3 is installed in the plugin/scripts directory
|
||||
*/
|
||||
|
||||
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { execSync } from 'child_process';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
function getDirname() {
|
||||
return typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url));
|
||||
}
|
||||
|
||||
const scriptDir = getDirname();
|
||||
|
||||
// Determine if we're in the built plugin/scripts directory or src/bin
|
||||
const isBuilt = scriptDir.includes('plugin/scripts') || scriptDir.includes('plugin\\scripts');
|
||||
const targetDir = isBuilt ? scriptDir : join(scriptDir, '../../plugin/scripts');
|
||||
|
||||
const nodeModulesPath = join(targetDir, 'node_modules');
|
||||
const packageJsonPath = join(targetDir, 'package.json');
|
||||
|
||||
// Check if better-sqlite3 is already installed
|
||||
if (existsSync(nodeModulesPath)) {
|
||||
const betterSqlitePath = join(nodeModulesPath, 'better-sqlite3');
|
||||
if (existsSync(betterSqlitePath)) {
|
||||
// Dependencies already installed
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure target directory exists
|
||||
if (!existsSync(targetDir)) {
|
||||
mkdirSync(targetDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Create minimal package.json if it doesn't exist
|
||||
if (!existsSync(packageJsonPath)) {
|
||||
const packageJson = {
|
||||
name: 'claude-mem-scripts',
|
||||
version: '4.2.1',
|
||||
description: 'Runtime dependencies for claude-mem plugin hooks',
|
||||
private: true,
|
||||
type: 'module',
|
||||
dependencies: {
|
||||
'better-sqlite3': '^11.0.0'
|
||||
}
|
||||
};
|
||||
|
||||
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
||||
}
|
||||
|
||||
// Install dependencies
|
||||
try {
|
||||
console.log('Installing claude-mem dependencies...');
|
||||
execSync('npm install --prefer-offline --no-audit --no-fund --loglevel error', {
|
||||
cwd: targetDir,
|
||||
stdio: 'inherit'
|
||||
});
|
||||
console.log('Dependencies installed successfully.');
|
||||
process.exit(0);
|
||||
} catch (error: any) {
|
||||
console.error('Failed to install dependencies:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user