feat(story-93): expose server logs to agents via get_server_logs MCP tool

- Add log_buffer module: bounded 1000-line ring buffer with push/get_recent API
- Add slog! macro: drop-in for eprintln! that also captures to ring buffer
- Replace all eprintln! calls across agents, watcher, search, chat, worktree, claude_code with slog!
- Add get_server_logs MCP tool: accepts count (1-500) and optional filter params
- 5 unit tests for log_buffer covering push/retrieve, eviction, filtering, count limits, empty buffer
- 262 tests passing, clippy clean

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-23 20:38:19 +00:00
parent 3d480e7c22
commit 8c6bd4cf74
10 changed files with 243 additions and 66 deletions

View File

@@ -1,3 +1,4 @@
use crate::slog;
use crate::config::ProjectConfig;
use std::path::{Path, PathBuf};
use std::process::Command;
@@ -245,7 +246,7 @@ fn remove_worktree_sync(
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
eprintln!("[worktree] remove warning: {stderr}");
slog!("[worktree] remove warning: {stderr}");
}
// Delete branch (best effort)
@@ -273,7 +274,7 @@ async fn run_teardown_commands(wt_path: &Path, config: &ProjectConfig) -> Result
for cmd in &component.teardown {
// Best effort — don't fail teardown
if let Err(e) = run_shell_command(cmd, &cmd_dir).await {
eprintln!("[worktree] teardown warning for {}: {e}", component.name);
slog!("[worktree] teardown warning for {}: {e}", component.name);
}
}
}
@@ -285,7 +286,7 @@ async fn run_shell_command(cmd: &str, cwd: &Path) -> Result<(), String> {
let cwd = cwd.to_path_buf();
tokio::task::spawn_blocking(move || {
eprintln!("[worktree] Running: {cmd} in {}", cwd.display());
slog!("[worktree] Running: {cmd} in {}", cwd.display());
let output = Command::new("sh")
.args(["-c", &cmd])
.current_dir(&cwd)