43 lines
1.5 KiB
Rust
43 lines
1.5 KiB
Rust
//! Workspace directory-tree generation for subagent system prompts.
|
|||
|
|
//!
|
||
|
|
//! Build an ASCII tree of the workspace directory structure so the LLM
|
||
|
|
//! can see the file layout.
|
||
|
|
|
||
|
|
use std::fmt::Write;
|
||
|
|
|
||
|
|
/// Build an ASCII tree of the workspace directory structure for the
|
||
|
|
/// system prompt, so the LLM can see the file layout.
|
||
|
|
///
|
||
|
|
/// Flow: for each root, walk using `ignore::WalkBuilder` (respecting
|
||
|
|
/// `.gitignore` and hidden files) → prefix `[DIR]` for directories →
|
||
|
|
/// truncate after 1000 entries.
|
||
|
|
pub(crate) fn generate_workspace_tree(roots: &[std::path::PathBuf]) -> String {
|
||
|
|
let mut out = String::new();
|
||
|
|
out.push_str("Current Workspace Directory Structure:\n");
|
||
|
|
for root in roots {
|
||
|
|
writeln!(out, "Root: {}", root.display()).unwrap();
|
||
|
|
let walker = ignore::WalkBuilder::new(root)
|
||
|
|
.hidden(true)
|
||
|
|
.git_ignore(true)
|
||
|
|
.build();
|
||
|
|
let mut count = 0;
|
||
|
|
for entry in walker.flatten() {
|
||
|
|
let path = entry.path();
|
||
|
|
if let Ok(rel) = path.strip_prefix(root) {
|
||
|
|
if rel.as_os_str().is_empty() {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
let is_dir = entry.file_type().is_some_and(|ft| ft.is_dir());
|
||
|
|
let prefix = if is_dir { "[DIR] " } else { " " };
|
||
|
|
writeln!(out, " {}{}", prefix, rel.display()).unwrap();
|
||
|
|
count += 1;
|
||
|
|
if count > 1000 {
|
||
|
|
out.push_str(" ... (truncated)\n");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
out
|
||
|
|
}
|