diff --git a/cursor-hooks/common.ps1 b/cursor-hooks/common.ps1 index 63d802da..629118d5 100644 --- a/cursor-hooks/common.ps1 +++ b/cursor-hooks/common.ps1 @@ -1,7 +1,6 @@ # Common utility functions for Cursor hooks (PowerShell) # Dot-source this file in hook scripts: . "$PSScriptRoot\common.ps1" - -$ErrorActionPreference = "SilentlyContinue" +# Note: ErrorActionPreference should be set in each script, not globally here # Get worker port from settings with validation function Get-WorkerPort { diff --git a/cursor-hooks/install.sh b/cursor-hooks/install.sh index 3f5d60a8..33b1571d 100755 --- a/cursor-hooks/install.sh +++ b/cursor-hooks/install.sh @@ -56,18 +56,23 @@ echo "Copying hooks.json..." cp "$SCRIPT_DIR/hooks.json" "$TARGET_DIR/hooks.json" # Update paths in hooks.json if needed +# Use portable sed approach that works on both BSD (macOS) and GNU (Linux) sed if [ "$INSTALL_TYPE" = "project" ]; then # For project-level, paths should be relative - sed -i.bak 's|\./cursor-hooks/|\./\.cursor/hooks/|g' "$TARGET_DIR/hooks.json" - rm -f "$TARGET_DIR/hooks.json.bak" + # Create temp file, modify, then move (portable across sed variants) + tmp_file=$(mktemp) + sed 's|\./cursor-hooks/|\./\.cursor/hooks/|g' "$TARGET_DIR/hooks.json" > "$tmp_file" + mv "$tmp_file" "$TARGET_DIR/hooks.json" elif [ "$INSTALL_TYPE" = "user" ]; then # For user-level, use absolute paths - sed -i.bak "s|\./cursor-hooks/|${HOOKS_DIR}/|g" "$TARGET_DIR/hooks.json" - rm -f "$TARGET_DIR/hooks.json.bak" + tmp_file=$(mktemp) + sed "s|\./cursor-hooks/|${HOOKS_DIR}/|g" "$TARGET_DIR/hooks.json" > "$tmp_file" + mv "$tmp_file" "$TARGET_DIR/hooks.json" elif [ "$INSTALL_TYPE" = "enterprise" ]; then # For enterprise, use absolute paths - sed -i.bak "s|\./cursor-hooks/|${HOOKS_DIR}/|g" "$TARGET_DIR/hooks.json" - rm -f "$TARGET_DIR/hooks.json.bak" + tmp_file=$(mktemp) + sed "s|\./cursor-hooks/|${HOOKS_DIR}/|g" "$TARGET_DIR/hooks.json" > "$tmp_file" + mv "$tmp_file" "$TARGET_DIR/hooks.json" fi echo "" diff --git a/src/services/worker-service.ts b/src/services/worker-service.ts index 34796e30..95ff6042 100644 --- a/src/services/worker-service.ts +++ b/src/services/worker-service.ts @@ -116,26 +116,28 @@ function unregisterCursorProject(projectName: string): void { export async function updateCursorContextForProject(projectName: string, port: number): Promise { const registry = readCursorRegistry(); const entry = registry[projectName]; - + if (!entry) return; // Project doesn't have Cursor hooks installed - + try { // Fetch fresh context from worker const response = await fetch( `http://127.0.0.1:${port}/api/context/inject?project=${encodeURIComponent(projectName)}` ); - + if (!response.ok) return; - + const context = await response.text(); if (!context || !context.trim()) return; - + // Write to the project's Cursor rules file const rulesDir = path.join(entry.workspacePath, '.cursor', 'rules'); const rulesFile = path.join(rulesDir, 'claude-mem-context.mdc'); - + mkdirSync(rulesDir, { recursive: true }); - + + // Write to temp file first, then atomically move (prevents corruption) + const tempFile = `${rulesFile}.tmp`; const content = `--- alwaysApply: true description: "Claude-mem context from past sessions (auto-updated)" @@ -150,8 +152,9 @@ ${context} --- *Updated after last session. Use claude-mem's MCP search tools for more detailed queries.* `; - - writeFileSync(rulesFile, content); + + writeFileSync(tempFile, content); + fs.renameSync(tempFile, rulesFile); logger.debug('CURSOR', 'Updated context file', { projectName, rulesFile }); } catch (error) { logger.warn('CURSOR', 'Failed to update context file', { projectName, error: (error as Error).message });