Enhance logging and documentation across utility tools and TUI overlays
- Added tracing instrumentation and improved logging messages in the Pong, Todofinish, and Todowrite tools for better debugging and monitoring. - Enhanced documentation comments for clarity on tool functionalities and workflows. - Implemented tracing in WorkflowRun, NoteFinding, ReadFindings, and HiveMind tools to track execution phases and findings. - Updated TUI overlays (e.g., Bash, Clear Confirm, Editor, Effort Level, Help, Key Input, Learning, Loading, MCP, Model Selector, Plan, Quit Confirm, Rewind, Settings, Todo, Usage) with debug logging to capture rendering details. - Improved the status bar and workflow panel rendering with additional debug information. - Added tracing to various utility functions to facilitate better performance monitoring and error tracking.
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
//! Change the working directory for subsequent commands.
|
||||
//!
|
||||
//! Resolves the requested directory against the workspace list and
|
||||
//! sets the process-wide current directory via `std::env::set_current_dir`.
|
||||
|
||||
use crate::tools::{resolve_path, Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use tracing::{info, instrument};
|
||||
|
||||
/// Tool that sets the working directory for subsequent tool calls.
|
||||
///
|
||||
/// Flow: parse directory argument → resolve against configured workspaces
|
||||
/// → call `std::env::set_current_dir` → confirm the new directory.
|
||||
pub struct Cd;
|
||||
|
||||
impl Tool for Cd {
|
||||
@@ -28,9 +36,11 @@ impl Tool for Cd {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, ctx, args))]
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let dir = crate::tools::arg_str(args, "directory")?;
|
||||
let resolved = resolve_path(&ctx.workspaces, &dir)?;
|
||||
info!(from = %std::env::current_dir().unwrap_or_default().display(), to = %resolved.display(), "cd invoked");
|
||||
std::env::set_current_dir(&resolved)?;
|
||||
Ok(format!("Changed directory to '{}'", resolved.display()))
|
||||
}
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
//! Update the shared directory cache by resolving each path against
|
||||
//! workspaces and storing the resolved paths in `ctx.dir_cache`.
|
||||
//!
|
||||
//! The cache is an `Arc<RwLock<DirCache>>` shared with the TUI and
|
||||
//! other components so they can read the cached listing without
|
||||
//! re-scanning the filesystem.
|
||||
|
||||
use crate::tools::{resolve_path, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use std::path::PathBuf;
|
||||
use tracing::{info, instrument};
|
||||
|
||||
/// Tool that updates the cached directory listing.
|
||||
///
|
||||
/// Flow: parse `paths` array → resolve each against workspaces →
|
||||
/// persist resolved paths into the shared `DirCache` via an
|
||||
/// async write → confirm with the entry count.
|
||||
pub struct DirCacheUpdate;
|
||||
|
||||
impl crate::tools::Tool for DirCacheUpdate {
|
||||
@@ -30,6 +40,7 @@ impl crate::tools::Tool for DirCacheUpdate {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, ctx, args))]
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let paths: Vec<String> = args
|
||||
.get("paths")
|
||||
@@ -47,6 +58,7 @@ impl crate::tools::Tool for DirCacheUpdate {
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let count = resolved.len();
|
||||
info!(count, "directory cache update requested");
|
||||
|
||||
// Persist the resolved paths into the shared DirCache so the TUI
|
||||
// and other tools can read the cached listing without re-scanning.
|
||||
@@ -54,6 +66,7 @@ impl crate::tools::Tool for DirCacheUpdate {
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
rt.block_on(async { dc.write().await.set(resolved).await });
|
||||
|
||||
info!(count, "directory cache updated");
|
||||
Ok(format!("Directory cache updated with {} entries", count))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
//! List directory contents.
|
||||
//!
|
||||
//! Resolves a relative path against the workspace list, validates
|
||||
//! it exists and is a directory, then reads and returns sorted entries.
|
||||
|
||||
use crate::tools::{resolve_path, Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use tracing::{info, instrument};
|
||||
|
||||
/// Tool that lists files and directories in a given path.
|
||||
///
|
||||
/// Flow: parse path → resolve against workspaces → validate existence
|
||||
/// and type → read directory entries → format with trailing `/` for
|
||||
/// subdirectories → return sorted, newline-separated listing.
|
||||
pub struct DirList;
|
||||
|
||||
impl Tool for DirList {
|
||||
@@ -28,10 +37,13 @@ impl Tool for DirList {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, ctx, args))]
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel = crate::tools::arg_str(args, "path")?;
|
||||
let path = resolve_path(&ctx.workspaces, &rel)?;
|
||||
|
||||
info!(?path, "dir_list invoked");
|
||||
|
||||
if !path.exists() {
|
||||
anyhow::bail!("path '{rel}' does not exist");
|
||||
}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
//! Simple ping/pong tool for connectivity testing.
|
||||
//!
|
||||
//! Always returns the string `"pong"`. Used by LLM agents to verify
|
||||
//! that the tool harness is reachable and responsive.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use tracing::{info, instrument};
|
||||
|
||||
/// Tool that responds to a ping — useful for testing connectivity.
|
||||
///
|
||||
/// Accepts no parameters and always returns `"pong"`.
|
||||
pub struct Pong;
|
||||
|
||||
impl Tool for Pong {
|
||||
@@ -22,7 +29,9 @@ impl Tool for Pong {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, _ctx, _args))]
|
||||
fn run(&self, _ctx: &ToolCtx, _args: &Value) -> Result<String> {
|
||||
info!("pong invoked — responding with 'pong'");
|
||||
Ok("pong".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
//! Mark a TODO item as finished.
|
||||
//!
|
||||
//! Reads the session's `TODO.md`, replaces the matching unchecked
|
||||
//! item with a checked `[x]` entry, writes the file back, and emits
|
||||
//! a `TurnEvent::TodoUpdate` for the TUI.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use tracing::{info, instrument};
|
||||
|
||||
/// Tool that marks a TODO item as completed in the session TODO file.
|
||||
///
|
||||
/// Flow: parse item text → read `TODO.md` → find matching line →
|
||||
/// replace `[ ]` / `[high]` / `[medium]` / `[low]` with `[x]` →
|
||||
/// write file → push `TurnEvent::TodoUpdate` if events channel exists.
|
||||
pub struct Todofinish;
|
||||
|
||||
impl Tool for Todofinish {
|
||||
@@ -28,8 +38,10 @@ impl Tool for Todofinish {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, ctx, args))]
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let item = crate::tools::arg_str(args, "item")?;
|
||||
info!(item, "todofinish invoked");
|
||||
|
||||
let todo_path = ctx.session_dir.join("TODO.md");
|
||||
let mut content = std::fs::read_to_string(&todo_path).unwrap_or_default();
|
||||
@@ -59,6 +71,9 @@ impl Tool for Todofinish {
|
||||
let mut q = events.lock().unwrap();
|
||||
q.push_back(crate::TurnEvent::TodoUpdate(content));
|
||||
}
|
||||
info!(item, "TODO item completed and written back");
|
||||
} else {
|
||||
info!(item, "TODO item not found in TODO.md — nothing to mark");
|
||||
}
|
||||
|
||||
Ok(format!("TODO completed: {}", item))
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
//! Write a TODO item.
|
||||
//!
|
||||
//! Appends a new unchecked TODO entry to the session's `TODO.md`
|
||||
//! file with an optional priority marker and emits a
|
||||
//! `TurnEvent::TodoUpdate` for the TUI.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
use tracing::{info, instrument};
|
||||
|
||||
/// Tool that adds an item to the session TODO list.
|
||||
///
|
||||
/// Flow: parse item + optional priority → append `- [priority] item\n`
|
||||
/// to `TODO.md` → write file → push `TurnEvent::TodoUpdate` if events
|
||||
/// channel exists → confirm addition.
|
||||
pub struct Todowrite;
|
||||
|
||||
impl Tool for Todowrite {
|
||||
@@ -33,6 +43,7 @@ impl Tool for Todowrite {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, ctx, args))]
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let item = crate::tools::arg_str(args, "item")?;
|
||||
let priority = args
|
||||
@@ -40,6 +51,8 @@ impl Tool for Todowrite {
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("medium");
|
||||
|
||||
info!(item, priority, "todowrite invoked");
|
||||
|
||||
let todo_line = format!("- [{}] {}\n", priority, item);
|
||||
|
||||
let todo_path = ctx.session_dir.join("TODO.md");
|
||||
@@ -53,6 +66,7 @@ impl Tool for Todowrite {
|
||||
q.push_back(crate::TurnEvent::TodoUpdate(content));
|
||||
}
|
||||
|
||||
info!(item, priority, "TODO item added");
|
||||
Ok(format!("[{}] TODO added: {}", priority, item))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user