From c80631fc1d6ef5c2507f8b9495243e7e21b9df79 Mon Sep 17 00:00:00 2001 From: Lidang-Jiang Date: Sat, 28 Mar 2026 09:54:35 +0800 Subject: [PATCH 1/5] fix(observer): improve Windows compatibility for temp files and Haiku prompt Address remaining issues from #842 after PR #903 moved temp files to PROJECT_DIR/.observer-tmp: Bug A (path resolution): Use relative paths (.observer-tmp/filename) in the prompt instead of absolute paths from mktemp. On Windows Git Bash/MSYS2, absolute paths use MSYS-style prefixes (/c/Users/...) that the spawned Claude subprocess may fail to resolve. Bug B (asks for permission): Add explicit IMPORTANT instruction block at the prompt start telling the Haiku agent it is in non-interactive --print mode and must use the Write tool directly without asking for confirmation. Additional improvements: - Pass prompt via -p flag instead of stdin redirect for Windows compat - Add .observer-tmp/ to .gitignore to prevent accidental commits Fixes #842 Co-Authored-By: Claude Opus 4.6 Signed-off-by: Lidang-Jiang --- .gitignore | 3 +++ .../continuous-learning-v2/agents/observer-loop.sh | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 68de41d1..88c7755a 100644 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,9 @@ temp/ *.bak *.backup +# Observer temp files (continuous-learning-v2) +.observer-tmp/ + # Rust build artifacts ecc2/target/ diff --git a/skills/continuous-learning-v2/agents/observer-loop.sh b/skills/continuous-learning-v2/agents/observer-loop.sh index c8d02470..e4eb0972 100755 --- a/skills/continuous-learning-v2/agents/observer-loop.sh +++ b/skills/continuous-learning-v2/agents/observer-loop.sh @@ -62,9 +62,16 @@ 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")" + prompt_file="$(mktemp "${observer_tmp_dir}/ecc-observer-prompt.XXXXXX")" cat > "$prompt_file" <.md using the Write tool. Do NOT ask for permission to write files, do NOT describe what you would write, and do NOT stop at analysis when a qualifying pattern exists. @@ -117,10 +124,11 @@ PROMPT max_turns=10 fi - # Prevent observe.sh from recording this automated Haiku session as observations + # Prevent observe.sh from recording this automated Haiku session as observations. + # Pass prompt via -p flag instead of stdin redirect for Windows compatibility (#842). ECC_SKIP_OBSERVE=1 ECC_HOOK_PROFILE=minimal claude --model haiku --max-turns "$max_turns" --print \ --allowedTools "Read,Write" \ - < "$prompt_file" >> "$LOG_FILE" 2>&1 & + -p "$(cat "$prompt_file")" >> "$LOG_FILE" 2>&1 & claude_pid=$! ( From 31af1adcc84287a58dd5a30c7d2d1e1803aa1455 Mon Sep 17 00:00:00 2001 From: Lidang-Jiang Date: Sat, 28 Mar 2026 10:34:40 +0800 Subject: [PATCH 2/5] fix(observer): anchor CWD to PROJECT_DIR before Claude invocation Reviewers correctly identified that the relative analysis_relpath (.observer-tmp/) only resolves when CWD equals PROJECT_DIR. Without an explicit cd, non-Windows users launching the observer from a different directory would fail to read the analysis file. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Lidang-Jiang --- skills/continuous-learning-v2/agents/observer-loop.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/skills/continuous-learning-v2/agents/observer-loop.sh b/skills/continuous-learning-v2/agents/observer-loop.sh index e4eb0972..a0c289b1 100755 --- a/skills/continuous-learning-v2/agents/observer-loop.sh +++ b/skills/continuous-learning-v2/agents/observer-loop.sh @@ -124,6 +124,10 @@ PROMPT max_turns=10 fi + # Ensure CWD is PROJECT_DIR so the relative analysis_relpath resolves correctly + # on all platforms, not just when the observer happens to be launched from the project root. + cd "$PROJECT_DIR" + # Prevent observe.sh from recording this automated Haiku session as observations. # Pass prompt via -p flag instead of stdin redirect for Windows compatibility (#842). ECC_SKIP_OBSERVE=1 ECC_HOOK_PROFILE=minimal claude --model haiku --max-turns "$max_turns" --print \ From 194bc0000b88645b98236b5ebb6c834c19c1b504 Mon Sep 17 00:00:00 2001 From: Lidang-Jiang Date: Sat, 28 Mar 2026 10:45:41 +0800 Subject: [PATCH 3/5] fix(observer): guard cd failure with early return and log message Address reviewer feedback: under set +e, a failing cd would silently leave CWD unchanged, causing the relative analysis path to break. Add || return with a diagnostic log entry. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Lidang-Jiang --- skills/continuous-learning-v2/agents/observer-loop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/continuous-learning-v2/agents/observer-loop.sh b/skills/continuous-learning-v2/agents/observer-loop.sh index a0c289b1..51de4f61 100755 --- a/skills/continuous-learning-v2/agents/observer-loop.sh +++ b/skills/continuous-learning-v2/agents/observer-loop.sh @@ -126,7 +126,7 @@ PROMPT # Ensure CWD is PROJECT_DIR so the relative analysis_relpath resolves correctly # on all platforms, not just when the observer happens to be launched from the project root. - cd "$PROJECT_DIR" + cd "$PROJECT_DIR" || { echo "[$(date)] Failed to cd to PROJECT_DIR ($PROJECT_DIR), skipping analysis" >> "$LOG_FILE"; return; } # Prevent observe.sh from recording this automated Haiku session as observations. # Pass prompt via -p flag instead of stdin redirect for Windows compatibility (#842). From 451732164fa9486686dff5a616b1a90acf739ee1 Mon Sep 17 00:00:00 2001 From: Lidang-Jiang Date: Sat, 28 Mar 2026 11:38:10 +0800 Subject: [PATCH 4/5] fix(observer): clean up temp files on cd failure early return The cd "$PROJECT_DIR" failure path returned without removing prompt_file and analysis_file, leaving stale temp files in .observer-tmp/. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Lidang-Jiang --- skills/continuous-learning-v2/agents/observer-loop.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/continuous-learning-v2/agents/observer-loop.sh b/skills/continuous-learning-v2/agents/observer-loop.sh index 51de4f61..5df24140 100755 --- a/skills/continuous-learning-v2/agents/observer-loop.sh +++ b/skills/continuous-learning-v2/agents/observer-loop.sh @@ -126,7 +126,7 @@ PROMPT # Ensure CWD is PROJECT_DIR so the relative analysis_relpath resolves correctly # on all platforms, not just when the observer happens to be launched from the project root. - cd "$PROJECT_DIR" || { echo "[$(date)] Failed to cd to PROJECT_DIR ($PROJECT_DIR), skipping analysis" >> "$LOG_FILE"; return; } + cd "$PROJECT_DIR" || { echo "[$(date)] Failed to cd to PROJECT_DIR ($PROJECT_DIR), skipping analysis" >> "$LOG_FILE"; rm -f "$prompt_file" "$analysis_file"; return; } # Prevent observe.sh from recording this automated Haiku session as observations. # Pass prompt via -p flag instead of stdin redirect for Windows compatibility (#842). From 7a4cb8c57030ad5d0b4e6b166bb07a29a6ab034a Mon Sep 17 00:00:00 2001 From: Lidang-Jiang Date: Sat, 28 Mar 2026 23:32:44 +0800 Subject: [PATCH 5/5] fix(observer): clean up prompt_file early and fix test for analysis_relpath - Remove prompt_file immediately after shell expansion into -p arg, avoiding stale temp files during long analysis windows (greptile feedback) - Update test assertion to check analysis_relpath instead of analysis_file, matching the cross-platform relative path change from earlier commits Signed-off-by: Lidang-Jiang --- skills/continuous-learning-v2/agents/observer-loop.sh | 5 ++++- tests/hooks/observer-memory.test.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/skills/continuous-learning-v2/agents/observer-loop.sh b/skills/continuous-learning-v2/agents/observer-loop.sh index 5df24140..e2cad9af 100755 --- a/skills/continuous-learning-v2/agents/observer-loop.sh +++ b/skills/continuous-learning-v2/agents/observer-loop.sh @@ -134,6 +134,9 @@ PROMPT --allowedTools "Read,Write" \ -p "$(cat "$prompt_file")" >> "$LOG_FILE" 2>&1 & claude_pid=$! + # prompt_file content was already expanded by the shell; remove early to avoid + # leaving stale temp files during the (potentially long) analysis window. + rm -f "$prompt_file" ( sleep "$timeout_seconds" @@ -147,7 +150,7 @@ PROMPT wait "$claude_pid" exit_code=$? kill "$watchdog_pid" 2>/dev/null || true - rm -f "$prompt_file" "$analysis_file" + rm -f "$analysis_file" if [ "$exit_code" -ne 0 ]; then echo "[$(date)] Claude analysis failed (exit $exit_code)" >> "$LOG_FILE" diff --git a/tests/hooks/observer-memory.test.js b/tests/hooks/observer-memory.test.js index 47ffe61d..8f91df40 100644 --- a/tests/hooks/observer-memory.test.js +++ b/tests/hooks/observer-memory.test.js @@ -175,7 +175,7 @@ test('prompt references analysis_file not full OBSERVATIONS_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_file}'), 'Prompt should point Claude at the sampled analysis file, not the full observations file'); + assert.ok(promptSection.includes('${analysis_relpath}'), 'Prompt should point Claude at the sampled analysis file (via relative path), not the full observations file'); }); // ──────────────────────────────────────────────────────