From 3eccc4e11dba30fe431256c3522e3fbaac4631ca Mon Sep 17 00:00:00 2001 From: inchwormz Date: Mon, 20 Apr 2026 13:11:53 +1200 Subject: [PATCH 1/2] Fix proactivity spawn prompt quoting on Windows (0.5.5) The spawn command wrapped inner placeholders like brief_path, job_id, and --error "" in double quotes. quote_for_cmd then doubled them to "" which cmd interpreted as quote-close-then-open, fragmenting the prompt into 28+ separate tokens. Spawned Claude sessions received stray --error / --summary / --job-id args and rejected them. Switch inner placeholders to single quotes. cmd passes ' through verbatim, so the whole prompt reaches the spawned session as one intact argument. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 7 +++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/core/proactivity.rs | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6808f9f..0d12fc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.5.5 - 2026-04-20 + +### Fixed + +- Morning proactivity spawn on Windows no longer fragments the prompt. The spawn command quoted inner paths and placeholders (`"{brief_path}"`, `"{job_id}"`, `--error ""`) with double quotes, which `quote_for_cmd` then doubled to `""..."".` cmd interpreted each `""` as quote-close-then-open and split the prompt into 28+ separate tokens, so the spawned Claude session received stray args like `--error` and `--summary` and rejected them. The prompt now uses single quotes around placeholders, which cmd passes through verbatim, so the whole prompt reaches the spawned session as one intact argument. +- Pairs with a companion fix to the user's `claude.ps1` wrapper (separate file, outside this repo) that dropped `[Parameter(ValueFromRemainingArguments)]` to keep the script a plain script instead of an advanced function — otherwise PowerShell matched `--error` against auto-added common parameters (`-ErrorAction`/`-ErrorVariable`) and crashed with AmbiguousParameter before the prompt ever reached claude.exe. + ## 0.5.4 - 2026-04-20 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 71ef26a..d9549ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -753,7 +753,7 @@ dependencies = [ [[package]] name = "munin-memory" -version = "0.5.4" +version = "0.5.5" dependencies = [ "anyhow", "automod", diff --git a/Cargo.toml b/Cargo.toml index 74f8c67..968ac3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "munin-memory" -version = "0.5.4" +version = "0.5.5" edition = "2021" autobins = false authors = ["John McKeown"] diff --git a/src/core/proactivity.rs b/src/core/proactivity.rs index 64c09e3..95662b0 100644 --- a/src/core/proactivity.rs +++ b/src/core/proactivity.rs @@ -1964,7 +1964,7 @@ fn build_launch_command( }) .unwrap_or_default(); let prompt = format!( - "{token}. The daemon already claimed the job. Read the brief at \"{brief_path}\".{leading_task} When you finish, run: munin proactivity complete --job-id \"{job_id}\" --status complete --summary \"\". On failure run: munin proactivity complete --job-id \"{job_id}\" --status failed --summary \"\" --error \"\". Full instructions are also at \"{launch_path}\".", + "{token}. The daemon already claimed the job. Read the brief at '{brief_path}'.{leading_task} When you finish, run: munin proactivity complete --job-id '{job_id}' --status complete --summary ''. On failure run: munin proactivity complete --job-id '{job_id}' --status failed --summary '' --error ''. Full instructions are also at '{launch_path}'.", token = MORNING_PROMPT_TOKEN, job_id = job.job_id, brief_path = job.brief_path, From 4b3c32cea6dad7ec8f5f0615b1e3174a52a79a64 Mon Sep 17 00:00:00 2001 From: inchwormz Date: Tue, 21 Apr 2026 06:15:55 +1200 Subject: [PATCH 2/2] Fix proactivity launch CI follow-ups --- CHANGELOG.md | 1 + src/analytics/memory_os_cmd.rs | 31 +++++++++++++++++++++++++------ src/core/proactivity.rs | 5 ++++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d12fc5..1b03d7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixed - Morning proactivity spawn on Windows no longer fragments the prompt. The spawn command quoted inner paths and placeholders (`"{brief_path}"`, `"{job_id}"`, `--error ""`) with double quotes, which `quote_for_cmd` then doubled to `""..."".` cmd interpreted each `""` as quote-close-then-open and split the prompt into 28+ separate tokens, so the spawned Claude session received stray args like `--error` and `--summary` and rejected them. The prompt now uses single quotes around placeholders, which cmd passes through verbatim, so the whole prompt reaches the spawned session as one intact argument. +- Claude proactivity launches now preserve the inherited Claude/Anthropic environment instead of clearing `CLAUDECODE`, `ANTHROPIC_API_KEY`, and `ANTHROPIC_AUTH_TOKEN` before starting the spawned session. - Pairs with a companion fix to the user's `claude.ps1` wrapper (separate file, outside this repo) that dropped `[Parameter(ValueFromRemainingArguments)]` to keep the script a plain script instead of an advanced function — otherwise PowerShell matched `--error` against auto-added common parameters (`-ErrorAction`/`-ErrorVariable`) and crashed with AmbiguousParameter before the prompt ever reached claude.exe. ## 0.5.4 - 2026-04-20 diff --git a/src/analytics/memory_os_cmd.rs b/src/analytics/memory_os_cmd.rs index 86c6a84..5a4b6bc 100644 --- a/src/analytics/memory_os_cmd.rs +++ b/src/analytics/memory_os_cmd.rs @@ -3521,9 +3521,19 @@ fn render_correction_patterns_to_codify(patterns: &[MemoryOsCorrectionPatternSum return; } for (index, pattern) in filtered.iter().enumerate() { - let wrong = pattern.wrong_command.split_whitespace().collect::>().join(" "); - let corrected = pattern.corrected_command.split_whitespace().collect::>().join(" "); - let status = if pattern.successful_replays > pattern.failed_replays && pattern.successful_replays >= pattern.count { + let wrong = pattern + .wrong_command + .split_whitespace() + .collect::>() + .join(" "); + let corrected = pattern + .corrected_command + .split_whitespace() + .collect::>() + .join(" "); + let status = if pattern.successful_replays > pattern.failed_replays + && pattern.successful_replays >= pattern.count + { "replaying-clean" } else { "uncodified" @@ -3552,11 +3562,20 @@ fn command_diff_display(wrong: &str, corrected: &str, max_tail: usize) -> (Strin let wrong_tail = tail_from(wrong, common, max_tail); let corrected_tail = tail_from(corrected, common, max_tail); ( - format!("[shared {}ch: `{}...`] ...{}", common, shared_preview, wrong_tail), - format!("[shared {}ch: `{}...`] ...{}", common, shared_preview, corrected_tail), + format!( + "[shared {}ch: `{}...`] ...{}", + common, shared_preview, wrong_tail + ), + format!( + "[shared {}ch: `{}...`] ...{}", + common, shared_preview, corrected_tail + ), ) } else { - (display_text(wrong, max_tail), display_text(corrected, max_tail)) + ( + display_text(wrong, max_tail), + display_text(corrected, max_tail), + ) } } diff --git a/src/core/proactivity.rs b/src/core/proactivity.rs index 95662b0..d838b09 100644 --- a/src/core/proactivity.rs +++ b/src/core/proactivity.rs @@ -1982,7 +1982,7 @@ fn build_launch_command( "claude-opus-4-6", &prompt, ], - &["CLAUDECODE", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"], + &[], ), ProactivityProvider::Codex => build_provider_launch_command( &job.session_name, @@ -2925,6 +2925,9 @@ mod tests { .preview .contains("Start with this intervention: Fix friction")); assert!(launch.preview.contains("Work it until implemented")); + assert!(!launch.preview.contains("set CLAUDECODE=")); + assert!(!launch.preview.contains("set ANTHROPIC_API_KEY=")); + assert!(!launch.preview.contains("set ANTHROPIC_AUTH_TOKEN=")); } #[test]