MAESTRO: fix(cursor): use bun runtime and fix hooks directory detection
Cherry-picked source changes from PR #721. Fixes two Cursor standalone setup bugs: 1. findCursorHooksDir() now checks for hooks.json (unified CLI mode) in addition to legacy common.sh/common.ps1 scripts 2. installCursorHooks() now uses bun instead of node for hook commands since worker-service.cjs depends on bun:sqlite 3. Added findBunPath() to detect bun executable across platforms Build artifacts skipped (pre-existing dompurify viewer dep issue). Source-only cherry-pick, TypeScript compilation clean for modified file. Co-Authored-By: polux0 <aleksaprosperitylabs@gmail.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -128,7 +128,7 @@ export async function updateCursorContextForProject(projectName: string, port: n
|
|||||||
/**
|
/**
|
||||||
* Find cursor-hooks directory
|
* Find cursor-hooks directory
|
||||||
* Searches in order: marketplace install, source repo
|
* Searches in order: marketplace install, source repo
|
||||||
* Checks for both bash (common.sh) and PowerShell (common.ps1) scripts
|
* Checks for hooks.json (unified CLI mode) or legacy shell scripts
|
||||||
*/
|
*/
|
||||||
export function findCursorHooksDir(): string | null {
|
export function findCursorHooksDir(): string | null {
|
||||||
const possiblePaths = [
|
const possiblePaths = [
|
||||||
@@ -141,8 +141,10 @@ export function findCursorHooksDir(): string | null {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (const p of possiblePaths) {
|
for (const p of possiblePaths) {
|
||||||
// Check for either bash or PowerShell common script
|
// Check for hooks.json (unified CLI mode) or legacy shell scripts
|
||||||
if (existsSync(path.join(p, 'common.sh')) || existsSync(path.join(p, 'common.ps1'))) {
|
if (existsSync(path.join(p, 'hooks.json')) ||
|
||||||
|
existsSync(path.join(p, 'common.sh')) ||
|
||||||
|
existsSync(path.join(p, 'common.ps1'))) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,6 +195,37 @@ export function findWorkerServicePath(): string | null {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the Bun executable path
|
||||||
|
* Required because worker-service.cjs uses bun:sqlite which is Bun-specific
|
||||||
|
* Searches common installation locations across platforms
|
||||||
|
*/
|
||||||
|
export function findBunPath(): string {
|
||||||
|
const possiblePaths = [
|
||||||
|
// Standard user install location (most common)
|
||||||
|
path.join(homedir(), '.bun', 'bin', 'bun'),
|
||||||
|
// Global install locations
|
||||||
|
'/usr/local/bin/bun',
|
||||||
|
'/usr/bin/bun',
|
||||||
|
// Windows locations
|
||||||
|
...(process.platform === 'win32' ? [
|
||||||
|
path.join(homedir(), '.bun', 'bin', 'bun.exe'),
|
||||||
|
path.join(process.env.LOCALAPPDATA || '', 'bun', 'bun.exe'),
|
||||||
|
] : []),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const p of possiblePaths) {
|
||||||
|
if (p && existsSync(p)) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to 'bun' and hope it's in PATH
|
||||||
|
// This allows the installation to proceed even if we can't find bun
|
||||||
|
// The user will get a clear error when the hook runs if bun isn't available
|
||||||
|
return 'bun';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the target directory for Cursor hooks based on install target
|
* Get the target directory for Cursor hooks based on install target
|
||||||
*/
|
*/
|
||||||
@@ -312,15 +345,21 @@ export async function installCursorHooks(_sourceDir: string, target: CursorInsta
|
|||||||
// Generate hooks.json with unified CLI commands
|
// Generate hooks.json with unified CLI commands
|
||||||
const hooksJsonPath = path.join(targetDir, 'hooks.json');
|
const hooksJsonPath = path.join(targetDir, 'hooks.json');
|
||||||
|
|
||||||
|
// Find bun executable - required because worker-service.cjs uses bun:sqlite
|
||||||
|
const bunPath = findBunPath();
|
||||||
|
const escapedBunPath = bunPath.replace(/\\/g, '\\\\');
|
||||||
|
|
||||||
// Use the absolute path to worker-service.cjs
|
// Use the absolute path to worker-service.cjs
|
||||||
// Escape backslashes for JSON on Windows
|
// Escape backslashes for JSON on Windows
|
||||||
const escapedWorkerPath = workerServicePath.replace(/\\/g, '\\\\');
|
const escapedWorkerPath = workerServicePath.replace(/\\/g, '\\\\');
|
||||||
|
|
||||||
// Helper to create hook command using unified CLI
|
// Helper to create hook command using unified CLI with bun runtime
|
||||||
const makeHookCommand = (command: string) => {
|
const makeHookCommand = (command: string) => {
|
||||||
return `node "${escapedWorkerPath}" hook cursor ${command}`;
|
return `"${escapedBunPath}" "${escapedWorkerPath}" hook cursor ${command}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log(` Using Bun runtime: ${bunPath}`);
|
||||||
|
|
||||||
const hooksJson: CursorHooksJson = {
|
const hooksJson: CursorHooksJson = {
|
||||||
version: 1,
|
version: 1,
|
||||||
hooks: {
|
hooks: {
|
||||||
@@ -356,7 +395,7 @@ export async function installCursorHooks(_sourceDir: string, target: CursorInsta
|
|||||||
Installation complete!
|
Installation complete!
|
||||||
|
|
||||||
Hooks installed to: ${targetDir}/hooks.json
|
Hooks installed to: ${targetDir}/hooks.json
|
||||||
Using unified CLI: node worker-service.cjs hook cursor <command>
|
Using unified CLI: bun worker-service.cjs hook cursor <command>
|
||||||
|
|
||||||
Next steps:
|
Next steps:
|
||||||
1. Start claude-mem worker: claude-mem start
|
1. Start claude-mem worker: claude-mem start
|
||||||
@@ -532,7 +571,7 @@ export function checkCursorHooksStatus(): number {
|
|||||||
const firstCommand = hooksContent?.hooks?.beforeSubmitPrompt?.[0]?.command || '';
|
const firstCommand = hooksContent?.hooks?.beforeSubmitPrompt?.[0]?.command || '';
|
||||||
|
|
||||||
if (firstCommand.includes('worker-service.cjs') && firstCommand.includes('hook cursor')) {
|
if (firstCommand.includes('worker-service.cjs') && firstCommand.includes('hook cursor')) {
|
||||||
console.log(` Mode: Unified CLI (node worker-service.cjs)`);
|
console.log(` Mode: Unified CLI (bun worker-service.cjs)`);
|
||||||
} else {
|
} else {
|
||||||
// Detect legacy shell scripts
|
// Detect legacy shell scripts
|
||||||
const bashScripts = ['session-init.sh', 'context-inject.sh', 'save-observation.sh'];
|
const bashScripts = ['session-init.sh', 'context-inject.sh', 'save-observation.sh'];
|
||||||
|
|||||||
Reference in New Issue
Block a user