diff --git a/scripts/healthcheck.ps1 b/scripts/healthcheck.ps1 index 8aca08c..88fbffc 100644 --- a/scripts/healthcheck.ps1 +++ b/scripts/healthcheck.ps1 @@ -266,7 +266,12 @@ if (Test-Path -LiteralPath $marketplaceReal -PathType Container) { # UserPromptSubmit "printf: write error: Permission denied" symptom. $bashCmd = Get-Command bash -ErrorAction SilentlyContinue if ($bashCmd) { - $cmHookProbe = '_C="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"; _E="${PLUGIN_ROOT:-}"; _P=$({ [ -n "$_E" ] && printf ''%s\n'' "$_E"; ls -dt "$_C/plugins/cache/thedotmack/claude-mem"/[0-9]*/ 2>/dev/null; printf ''%s\n'' "$_C/plugins/marketplaces/thedotmack-claude-mem/plugin"; } | while IFS= read -r _R; do _R="${_R%/}"; [ -d "$_R/plugin/scripts" ] && _Q="$_R/plugin" || _Q="$_R"; [ -f "$_Q/scripts/bun-runner.js" ] && [ -f "$_Q/scripts/worker-service.cjs" ] && { printf ''%s\n'' "$_Q"; break; }; done); [ -n "$_P" ] && printf ''%s'' "$_P" || exit 1' + # BUG-022 (2026-05-21): the probe itself used the same `break; }; done` + # cascade pattern as the upstream hook, hitting the EPIPE race when + # called from setup. Apply the same `head -n1` fix (Option A from + # claude-mem#2607) so the probe is race-free and reports the actual + # state of the install rather than spurious failures. + $cmHookProbe = '_C="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"; _E="${PLUGIN_ROOT:-}"; _P=$({ [ -n "$_E" ] && printf ''%s\n'' "$_E"; ls -dt "$_C/plugins/cache/thedotmack/claude-mem"/[0-9]*/ 2>/dev/null; printf ''%s\n'' "$_C/plugins/marketplaces/thedotmack-claude-mem/plugin"; } | while IFS= read -r _R; do _R="${_R%/}"; [ -d "$_R/plugin/scripts" ] && _Q="$_R/plugin" || _Q="$_R"; [ -f "$_Q/scripts/bun-runner.js" ] && [ -f "$_Q/scripts/worker-service.cjs" ] && printf ''%s\n'' "$_Q"; done | head -n1); [ -n "$_P" ] && printf ''%s'' "$_P" || exit 1' $resolved = & bash -c $cmHookProbe 2>&1 if ($LASTEXITCODE -eq 0 -and $resolved) { Write-Pass "claude-mem hook path resolves to: $resolved (BUG-015)" diff --git a/scripts/healthcheck.sh b/scripts/healthcheck.sh index 0e36c40..888c2dd 100755 --- a/scripts/healthcheck.sh +++ b/scripts/healthcheck.sh @@ -191,6 +191,11 @@ fi # user encounters the intermittent UserPromptSubmit fail. _cmhook_C="${CLAUDE_CONFIG_DIR:-$HOME/.claude}" _cmhook_E="${PLUGIN_ROOT:-}" +# BUG-022 (2026-05-21): probe itself used the same `break; }; done` cascade +# as the upstream hooks (which BUG-017 patched away). Apply the same +# `head -n1` fix locally so the probe is race-free and reports actual state +# instead of spurious failures. On Linux SIGPIPE is silent so the race rarely +# fires here, but cross-OS parity with healthcheck.ps1 matters. _cmhook_P=$({ [ -n "$_cmhook_E" ] && printf '%s\n' "$_cmhook_E" ls -dt "$_cmhook_C/plugins/cache/thedotmack/claude-mem"/[0-9]*/ 2>/dev/null @@ -198,8 +203,8 @@ _cmhook_P=$({ } | while IFS= read -r _r; do _r="${_r%/}" [ -d "$_r/plugin/scripts" ] && _q="$_r/plugin" || _q="$_r" - [ -f "$_q/scripts/bun-runner.js" ] && [ -f "$_q/scripts/worker-service.cjs" ] && { printf '%s\n' "$_q"; break; } -done) + [ -f "$_q/scripts/bun-runner.js" ] && [ -f "$_q/scripts/worker-service.cjs" ] && printf '%s\n' "$_q" +done | head -n1) if [ -n "$_cmhook_P" ]; then pass "claude-mem hook path resolves to: $_cmhook_P (BUG-015)" else diff --git a/setup-linux.sh b/setup-linux.sh index f136593..2e868e3 100755 --- a/setup-linux.sh +++ b/setup-linux.sh @@ -952,6 +952,10 @@ export SCRIPTS_DIR="${SCRIPTS_DIR:-$DOTFILES_DIR/scripts}" export GEMINI_HOME="${GEMINI_HOME:-$HOME/.gemini}" export COPILOT_HOME="${COPILOT_HOME:-$HOME/.copilot}" export OPENCODE_HOME="${OPENCODE_HOME:-$HOME/.config/opencode}" +# BUG-021 (2026-05-21): pre-export DOTFILES_REPO_DIR so doctor + diff-check.sh +# (REFACTOR-003 sec 12) see it set even when the running shell's profile +# hasn't been re-evaluated post-deploy. Mirror of the setup-windows.ps1 fix. +export DOTFILES_REPO_DIR="${DOTFILES_REPO_DIR:-$HOME/Projects/dotfiles}" DOCTOR_SCRIPT="$DOTFILES_DIR/scripts/doctor.sh" if [ -x "$DOCTOR_SCRIPT" ] && command -v jq >/dev/null 2>&1; then diff --git a/setup-windows.ps1 b/setup-windows.ps1 index 9e7d533..77b473d 100644 --- a/setup-windows.ps1 +++ b/setup-windows.ps1 @@ -1164,10 +1164,16 @@ if ($existingTask -and ($existingTaskArgument -eq $expectedTaskArgument)) { # deployed profile entirely. Values must match the corresponding lines in # powershell/profile.ps1. PowerShell propagates parent $env: to child procs. -if (-not $env:SCRIPTS_DIR) { $env:SCRIPTS_DIR = "$env:DOTFILES_DIR\scripts" } -if (-not $env:GEMINI_HOME) { $env:GEMINI_HOME = "$env:USERPROFILE\.gemini" } -if (-not $env:COPILOT_HOME) { $env:COPILOT_HOME = "$env:USERPROFILE\.copilot" } -if (-not $env:OPENCODE_HOME) { $env:OPENCODE_HOME = "$env:USERPROFILE\.config\opencode" } +if (-not $env:SCRIPTS_DIR) { $env:SCRIPTS_DIR = "$env:DOTFILES_DIR\scripts" } +if (-not $env:GEMINI_HOME) { $env:GEMINI_HOME = "$env:USERPROFILE\.gemini" } +if (-not $env:COPILOT_HOME) { $env:COPILOT_HOME = "$env:USERPROFILE\.copilot" } +if (-not $env:OPENCODE_HOME) { $env:OPENCODE_HOME = "$env:USERPROFILE\.config\opencode" } +# BUG-021 (2026-05-21): added DOTFILES_REPO_DIR pre-export -- BUG-020 (PR #86) +# added the export to profile.ps1 but the running shell doesn't reload profile, +# so doctor + diff-check.ps1 (via healthcheck sec 12) still see the var unset +# until next shell restart. Mirror the same pre-export pattern as the other +# 4 vars to surface PASS immediately in the post-setup checks. +if (-not $env:DOTFILES_REPO_DIR) { $env:DOTFILES_REPO_DIR = "$env:USERPROFILE\Projects\dotfiles" } $doctorScript = "$ScriptsDir\doctor.ps1" if (Test-Path $doctorScript) {