From b7faf3d70eb926671309fc4ef65e4e0f092ace76 Mon Sep 17 00:00:00 2001 From: Suliman Abdulrazzaq Date: Mon, 10 Aug 2026 23:02:41 +0300 Subject: [PATCH] fix: pass observer analysis path explicitly --- .../agents/observer-loop.sh | 15 +++++++++++---- tests/hooks/observer-memory.test.js | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/skills/continuous-learning-v2/agents/observer-loop.sh b/skills/continuous-learning-v2/agents/observer-loop.sh index f75365920..74b8f5110 100755 --- a/skills/continuous-learning-v2/agents/observer-loop.sh +++ b/skills/continuous-learning-v2/agents/observer-loop.sh @@ -153,10 +153,17 @@ analyze_observations() { analysis_count=$(wc -l < "$analysis_file" 2>/dev/null || echo 0) echo "[$(date)] Using last $analysis_count of $obs_count observations for analysis" >> "$LOG_FILE" - # Use relative path from PROJECT_DIR for cross-platform compatibility (#842). - # On Windows (Git Bash/MSYS2), absolute paths from mktemp may use MSYS-style - # prefixes (e.g. /c/Users/...) that the Claude subprocess cannot resolve. - analysis_relpath=".observer-tmp/$(basename "$analysis_file")" + # Claude Code resolves relative paths against the user's home directory on + # macOS/Linux, even though the observer changes to PROJECT_DIR first. Use + # the absolute path there so the analyzer reads the file that was sampled. + # Keep the relative path on Windows (Git Bash/MSYS2), where absolute paths + # from mktemp can contain /c/ prefixes that the Claude subprocess cannot + # resolve (#842, #2673). + if [ "${CLV2_IS_WINDOWS:-false}" = "true" ]; then + analysis_relpath=".observer-tmp/$(basename "$analysis_file")" + else + analysis_relpath="$analysis_file" + fi prompt_file="$(mktemp "${observer_tmp_dir}/ecc-observer-prompt.XXXXXX")" cat > "$prompt_file" < { assert.ok(heredocStart > 0, 'Should find prompt heredoc start'); assert.ok(heredocEnd > heredocStart, 'Should find prompt heredoc end'); const promptSection = content.substring(heredocStart, heredocEnd); - assert.ok(promptSection.includes('${analysis_relpath}'), 'Prompt should point Claude at the sampled analysis file (via relative path), not the full observations file'); + assert.ok(promptSection.includes('${analysis_relpath}'), 'Prompt should point Claude at the sampled analysis file, not the full observations file'); +}); + +test('observer uses an absolute analysis path outside Windows', () => { + const content = fs.readFileSync(observerLoopPath, 'utf8'); + assert.ok( + content.includes('if [ "${CLV2_IS_WINDOWS:-false}" = "true" ]') && + content.includes('analysis_relpath="$analysis_file"'), + 'macOS and Linux must pass the absolute analysis path to Claude' + ); + assert.ok( + content.includes('analysis_relpath=".observer-tmp/$(basename "$analysis_file")"'), + 'Windows must retain the MSYS-compatible relative analysis path' + ); }); test('observer-loop wait helper retries SIGUSR1-interrupted waits while claude child is alive', () => {