Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# 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 "<concrete 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

### Changed
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "munin-memory"
version = "0.5.4"
version = "0.5.5"
edition = "2021"
autobins = false
authors = ["John McKeown"]
Expand Down
31 changes: 25 additions & 6 deletions src/analytics/memory_os_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>().join(" ");
let corrected = pattern.corrected_command.split_whitespace().collect::<Vec<_>>().join(" ");
let status = if pattern.successful_replays > pattern.failed_replays && pattern.successful_replays >= pattern.count {
let wrong = pattern
.wrong_command
.split_whitespace()
.collect::<Vec<_>>()
.join(" ");
let corrected = pattern
.corrected_command
.split_whitespace()
.collect::<Vec<_>>()
.join(" ");
let status = if pattern.successful_replays > pattern.failed_replays
&& pattern.successful_replays >= pattern.count
{
"replaying-clean"
} else {
"uncodified"
Expand Down Expand Up @@ -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),
)
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/core/proactivity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 \"<one sentence summary>\". On failure run: munin proactivity complete --job-id \"{job_id}\" --status failed --summary \"<short failure summary>\" --error \"<concrete 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 '<one sentence summary>'. On failure run: munin proactivity complete --job-id '{job_id}' --status failed --summary '<short failure summary>' --error '<concrete error>'. Full instructions are also at '{launch_path}'.",
token = MORNING_PROMPT_TOKEN,
job_id = job.job_id,
brief_path = job.brief_path,
Expand All @@ -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,
Expand Down Expand Up @@ -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]
Expand Down
Loading