ca4f046777
Enhancements: - Added search skill with 10 HTTP API endpoints for memory queries - Refactored version-bump and troubleshoot skills using progressive disclosure pattern - Added operations/ subdirectories for detailed skill documentation - Updated CLAUDE.md with skill-based search architecture - Enhanced worker service with search API endpoints - Updated CHANGELOG.md with v5.4.0 migration details Technical changes: - New plugin/skills/search/ directory with SKILL.md - New .claude/skills/version-bump/operations/ (workflow.md, scenarios.md) - New plugin/skills/troubleshoot/operations/ (common-issues.md, worker.md) - Modified src/services/worker-service.ts (added search endpoints) - Modified plugin/scripts/worker-service.cjs (rebuilt with search API) - Reduced main skill files by 89% using progressive disclosure - Token savings: ~2,250 tokens per session start 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
151 lines
4.6 KiB
JavaScript
151 lines
4.6 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Build script for claude-mem hooks
|
|
* Bundles TypeScript hooks into individual standalone executables using esbuild
|
|
*/
|
|
|
|
import { build } from 'esbuild';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
const HOOKS = [
|
|
{ name: 'context-hook', source: 'src/hooks/context-hook.ts' },
|
|
{ name: 'new-hook', source: 'src/hooks/new-hook.ts' },
|
|
{ name: 'save-hook', source: 'src/hooks/save-hook.ts' },
|
|
{ name: 'summary-hook', source: 'src/hooks/summary-hook.ts' },
|
|
{ name: 'cleanup-hook', source: 'src/hooks/cleanup-hook.ts' },
|
|
{ name: 'user-message-hook', source: 'src/hooks/user-message-hook.ts' }
|
|
];
|
|
|
|
const WORKER_SERVICE = {
|
|
name: 'worker-service',
|
|
source: 'src/services/worker-service.ts'
|
|
};
|
|
|
|
// DEPRECATED: MCP search server replaced by skill-based search
|
|
// Keeping source file for reference: src/servers/search-server.ts
|
|
// const SEARCH_SERVER = {
|
|
// name: 'search-server',
|
|
// source: 'src/servers/search-server.ts'
|
|
// };
|
|
|
|
async function buildHooks() {
|
|
console.log('🔨 Building claude-mem hooks and worker service...\n');
|
|
|
|
try {
|
|
// Read version from package.json
|
|
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
|
const version = packageJson.version;
|
|
console.log(`📌 Version: ${version}`);
|
|
|
|
// Create output directories
|
|
console.log('\n📦 Preparing output directories...');
|
|
const hooksDir = 'plugin/scripts';
|
|
const uiDir = 'plugin/ui';
|
|
|
|
if (!fs.existsSync(hooksDir)) {
|
|
fs.mkdirSync(hooksDir, { recursive: true });
|
|
}
|
|
if (!fs.existsSync(uiDir)) {
|
|
fs.mkdirSync(uiDir, { recursive: true });
|
|
}
|
|
console.log('✓ Output directories ready');
|
|
|
|
// Build React viewer
|
|
console.log('\n📋 Building React viewer...');
|
|
const { spawn } = await import('child_process');
|
|
const viewerBuild = spawn('node', ['scripts/build-viewer.js'], { stdio: 'inherit' });
|
|
await new Promise((resolve, reject) => {
|
|
viewerBuild.on('exit', (code) => {
|
|
if (code === 0) {
|
|
resolve();
|
|
} else {
|
|
reject(new Error(`Viewer build failed with exit code ${code}`));
|
|
}
|
|
});
|
|
});
|
|
|
|
// Build worker service
|
|
console.log(`\n🔧 Building worker service...`);
|
|
await build({
|
|
entryPoints: [WORKER_SERVICE.source],
|
|
bundle: true,
|
|
platform: 'node',
|
|
target: 'node18',
|
|
format: 'cjs',
|
|
outfile: `${hooksDir}/${WORKER_SERVICE.name}.cjs`,
|
|
minify: true,
|
|
logLevel: 'error', // Suppress warnings (import.meta warning is benign)
|
|
external: ['better-sqlite3'],
|
|
define: {
|
|
'__DEFAULT_PACKAGE_VERSION__': `"${version}"`
|
|
},
|
|
banner: {
|
|
js: '#!/usr/bin/env node'
|
|
}
|
|
});
|
|
|
|
// Make worker service executable
|
|
fs.chmodSync(`${hooksDir}/${WORKER_SERVICE.name}.cjs`, 0o755);
|
|
const workerStats = fs.statSync(`${hooksDir}/${WORKER_SERVICE.name}.cjs`);
|
|
console.log(`✓ worker-service built (${(workerStats.size / 1024).toFixed(2)} KB)`);
|
|
|
|
// Build each hook
|
|
for (const hook of HOOKS) {
|
|
console.log(`\n🔧 Building ${hook.name}...`);
|
|
|
|
const outfile = `${hooksDir}/${hook.name}.js`;
|
|
|
|
await build({
|
|
entryPoints: [hook.source],
|
|
bundle: true,
|
|
platform: 'node',
|
|
target: 'node18',
|
|
format: 'esm',
|
|
outfile,
|
|
minify: true,
|
|
external: ['better-sqlite3'],
|
|
define: {
|
|
'__DEFAULT_PACKAGE_VERSION__': `"${version}"`
|
|
},
|
|
banner: {
|
|
js: '#!/usr/bin/env node'
|
|
}
|
|
});
|
|
|
|
// Make executable
|
|
fs.chmodSync(outfile, 0o755);
|
|
|
|
// Check file size
|
|
const stats = fs.statSync(outfile);
|
|
const sizeInKB = (stats.size / 1024).toFixed(2);
|
|
console.log(`✓ ${hook.name} built (${sizeInKB} KB)`);
|
|
}
|
|
|
|
// DEPRECATED: MCP search server no longer built (replaced by skill-based search)
|
|
// Search functionality now provided via HTTP API + search skill
|
|
// Source file kept for reference: src/servers/search-server.ts
|
|
|
|
console.log('\n✅ All hooks and worker service built successfully!');
|
|
console.log(` Output: ${hooksDir}/`);
|
|
console.log(` - Hooks: *-hook.js`);
|
|
console.log(` - Worker: worker-service.cjs`);
|
|
console.log(` - Skills: plugin/skills/`);
|
|
console.log('\n💡 Note: Dependencies will be auto-installed on first hook execution');
|
|
|
|
} catch (error) {
|
|
console.error('\n❌ Build failed:', error.message);
|
|
if (error.errors) {
|
|
console.error('\nBuild errors:');
|
|
error.errors.forEach(err => console.error(` - ${err.text}`));
|
|
}
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
buildHooks();
|