refactor(cli): show only loaded items in startup status line

Changes the startup status line to only display items that were
actually loaded, instead of showing dots for missing items.

Before: "   · README  · AGENTS.md  ✓ Memory"
After:  "   ✓ Memory"

Also adds include prompt to the status line when specified:
"   ✓ prompt.md  ✓ Memory"

The order matches the load order: README → AGENTS.md → include prompt → Memory
This commit is contained in:
Dhanji R. Prasanna
2026-01-17 15:35:37 +05:30
parent 4877f8ae8a
commit 5622e5b21e
3 changed files with 58 additions and 38 deletions

View File

@@ -139,29 +139,36 @@ pub async fn run_agent_mode(
let readme_content_opt = read_project_readme(&workspace_dir); let readme_content_opt = read_project_readme(&workspace_dir);
let memory_content_opt = read_project_memory(&workspace_dir); let memory_content_opt = read_project_memory(&workspace_dir);
// Show what was loaded // Read include prompt early so we can show it in the status line
let readme_status = if readme_content_opt.is_some() { let include_prompt = read_include_prompt(include_prompt_path.as_deref());
""
} else { // Build status line showing only what was loaded (in load order)
"·" let mut loaded_items: Vec<String> = Vec::new();
}; if readme_content_opt.is_some() {
let agents_status = if agents_content_opt.is_some() { loaded_items.push("README".to_string());
"" }
} else { if agents_content_opt.is_some() {
"·" loaded_items.push("AGENTS.md".to_string());
}; }
let memory_status = if memory_content_opt.is_some() { if let Some(path) = &include_prompt_path {
"" if include_prompt.is_some() {
} else { let filename = path.file_name().map(|s| s.to_string_lossy().to_string()).unwrap_or_else(|| "prompt".to_string());
"·" loaded_items.push(filename);
}; }
// Always print status line (part of minimal output) }
if memory_content_opt.is_some() {
loaded_items.push("Memory".to_string());
}
// Print status line only if something was loaded
if !loaded_items.is_empty() {
let status_str = loaded_items.iter().map(|s| format!("{}", s)).collect::<Vec<_>>().join(" ");
print!( print!(
"{} {} README {} AGENTS.md {} Memory{}\n", "{} {}{}\n",
crossterm::style::SetForegroundColor(crossterm::style::Color::DarkGrey), crossterm::style::SetForegroundColor(crossterm::style::Color::DarkGrey),
readme_status, agents_status, memory_status, status_str,
crossterm::style::ResetColor crossterm::style::ResetColor
); );
}
// Get language-specific prompts (same mechanism as normal mode) // Get language-specific prompts (same mechanism as normal mode)
let language_content = get_language_prompts_for_workspace(&workspace_dir); let language_content = get_language_prompts_for_workspace(&workspace_dir);
@@ -188,9 +195,6 @@ pub async fn run_agent_mode(
system_prompt system_prompt
}; };
// Read include prompt if specified
let include_prompt = read_include_prompt(include_prompt_path.as_deref());
// Combine all content for the agent's context // Combine all content for the agent's context
let combined_content = combine_project_content( let combined_content = combine_project_content(
agents_content_opt, agents_content_opt,

View File

@@ -102,11 +102,8 @@ pub async fn run_interactive<W: UiWriter>(
// Check what was loaded // Check what was loaded
let has_agents = content.contains("Agent Configuration"); let has_agents = content.contains("Agent Configuration");
let has_readme = content.contains("Project README"); let has_readme = content.contains("Project README");
let has_memory = content.contains("Project Memory"); let has_include_prompt = content.contains("Included Prompt");
let has_memory = content.contains("=== Project Memory");
let readme_status = if has_readme { "" } else { "·" };
let agents_status = if has_agents { "" } else { "·" };
let memory_status = if has_memory { "" } else { "·" };
// Extract project name if README is loaded // Extract project name if README is loaded
let project_name = if has_readme { let project_name = if has_readme {
@@ -119,13 +116,32 @@ pub async fn run_interactive<W: UiWriter>(
if let Some(name) = project_name { if let Some(name) = project_name {
print!("{}>> {}{}\n", SetForegroundColor(Color::DarkGrey), name, ResetColor); print!("{}>> {}{}\n", SetForegroundColor(Color::DarkGrey), name, ResetColor);
} }
// Build status line showing only what was loaded (in load order)
let mut loaded_items: Vec<&str> = Vec::new();
if has_readme {
loaded_items.push("README");
}
if has_agents {
loaded_items.push("AGENTS.md");
}
if has_include_prompt {
loaded_items.push("prompt");
}
if has_memory {
loaded_items.push("Memory");
}
// Print status line only if something was loaded
if !loaded_items.is_empty() {
let status_str = loaded_items.iter().map(|s| format!("{}", s)).collect::<Vec<_>>().join(" ");
print!( print!(
"{} {} README | {} AGENTS.md | {} Memory{}\n", "{} {}{}\n",
SetForegroundColor(Color::DarkGrey), SetForegroundColor(Color::DarkGrey),
readme_status, agents_status, memory_status, status_str,
ResetColor ResetColor
); );
} }
}
// Display workspace path // Display workspace path
let workspace_display = { let workspace_display = {

View File

@@ -1910,7 +1910,7 @@ fn test_code_fence_no_trailing_newline() {
let mut fmt = StreamingMarkdownFormatter::new(skin); let mut fmt = StreamingMarkdownFormatter::new(skin);
// Note: no newline after closing ``` // Note: no newline after closing ```
let input = "Done!\n\n```\n>> agent mode | fowler\n-> ~/src/g3\n ✓ README | ✓ AGENTS.md | ✓ Memory\n```"; let input = "Done!\n\n```\n>> agent mode | fowler\n-> ~/src/g3\n ✓ README ✓ AGENTS.md ✓ Memory\n```";
let mut output = String::new(); let mut output = String::new();
for ch in input.chars() { for ch in input.chars() {