Skip to content
3 changes: 2 additions & 1 deletion crates/chat-cli/src/cli/chat/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ impl ContextSubcommand {
<em>help</em> <black!>Show an explanation for the context command</black!>

<em>show [--expand]</em> <black!>Display the context rule configuration and matched files</black!>
<black!>--expand: Print out each matched file's content</black!>
<black!>--expand: Print out each matched file's content, hook</black!>
<black!> configurations and last conversation summary </black!>

<em>add [--global] [--force] <<paths...>></em>
<black!>Add context rules (filenames or glob patterns)</black!>
Expand Down
4 changes: 4 additions & 0 deletions crates/chat-cli/src/cli/chat/conversation_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ impl ConversationState {
}
}

pub fn latest_summary(&self) -> Option<&str> {
self.latest_summary.as_deref()
}

pub fn history(&self) -> &VecDeque<(UserMessage, AssistantMessage)> {
&self.history
}
Expand Down
150 changes: 108 additions & 42 deletions crates/chat-cli/src/cli/chat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1584,6 +1584,9 @@ impl ChatContext {
if let Some(context_manager) = &mut self.conversation_state.context_manager {
match subcommand {
command::ContextSubcommand::Show { expand } => {
fn map_chat_error(e: ErrReport) -> ChatError {
ChatError::Custom(e.to_string().into())
}
// Display global context
execute!(
self.output,
Expand Down Expand Up @@ -1621,6 +1624,28 @@ impl ChatContext {
}
}

if expand {
queue!(
self.output,
style::SetAttribute(Attribute::Bold),
style::SetForegroundColor(Color::DarkYellow),
style::Print("\n 🔧 Hooks:\n")
)?;
print_hook_section(
&mut self.output,
&context_manager.global_config.hooks,
HookTrigger::ConversationStart,
)
.map_err(map_chat_error)?;

print_hook_section(
&mut self.output,
&context_manager.global_config.hooks,
HookTrigger::PerPrompt,
)
.map_err(map_chat_error)?;
}

// Display profile context
execute!(
self.output,
Expand Down Expand Up @@ -1658,6 +1683,28 @@ impl ChatContext {
execute!(self.output, style::Print("\n"))?;
}

if expand {
queue!(
self.output,
style::SetAttribute(Attribute::Bold),
style::SetForegroundColor(Color::DarkYellow),
style::Print(" 🔧 Hooks:\n")
)?;
print_hook_section(
&mut self.output,
&context_manager.profile_config.hooks,
HookTrigger::ConversationStart,
)
.map_err(map_chat_error)?;
print_hook_section(
&mut self.output,
&context_manager.profile_config.hooks,
HookTrigger::PerPrompt,
)
.map_err(map_chat_error)?;
execute!(self.output, style::Print("\n"))?;
}

if global_context_files.is_empty() && profile_context_files.is_empty() {
execute!(
self.output,
Expand Down Expand Up @@ -1781,6 +1828,28 @@ impl ChatContext {

execute!(self.output, style::Print("\n"))?;
}

// Show last cached conversation summary if available, otherwise regenerate it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - remove the "regenerate it" comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure will remove this comment in future pr

if expand {
if let Some(summary) = self.conversation_state.latest_summary() {
let border = "═".repeat(self.terminal_width().min(80));
execute!(
self.output,
style::Print("\n"),
style::SetForegroundColor(Color::Cyan),
style::Print(&border),
style::Print("\n"),
style::SetAttribute(Attribute::Bold),
style::Print(" CONVERSATION SUMMARY"),
style::Print("\n"),
style::Print(&border),
style::SetAttribute(Attribute::Reset),
style::Print("\n\n"),
style::Print(&summary),
style::Print("\n\n\n")
)?;
}
}
},
command::ContextSubcommand::Add { global, force, paths } => {
match context_manager.add_paths(paths.clone(), global, force).await {
Expand Down Expand Up @@ -2030,48 +2099,6 @@ impl ChatContext {
},
}
} else {
fn print_hook_section(
output: &mut impl Write,
hooks: &HashMap<String, Hook>,
trigger: HookTrigger,
) -> Result<()> {
let section = match trigger {
HookTrigger::ConversationStart => "Conversation Start",
HookTrigger::PerPrompt => "Per Prompt",
};
let hooks: Vec<(&String, &Hook)> =
hooks.iter().filter(|(_, h)| h.trigger == trigger).collect();

queue!(
output,
style::SetForegroundColor(Color::Cyan),
style::Print(format!(" {section}:\n")),
style::SetForegroundColor(Color::Reset),
)?;

if hooks.is_empty() {
queue!(
output,
style::SetForegroundColor(Color::DarkGrey),
style::Print(" <none>\n"),
style::SetForegroundColor(Color::Reset)
)?;
} else {
for (name, hook) in hooks {
if hook.disabled {
queue!(
output,
style::SetForegroundColor(Color::DarkGrey),
style::Print(format!(" {} (disabled)\n", name)),
style::SetForegroundColor(Color::Reset)
)?;
} else {
queue!(output, style::Print(format!(" {}\n", name)),)?;
}
}
}
Ok(())
}
queue!(
self.output,
style::SetAttribute(Attribute::Bold),
Expand Down Expand Up @@ -3357,6 +3384,45 @@ impl ChatContext {
}
}

/// Prints hook configuration grouped by trigger: conversation session start or per user message
fn print_hook_section(output: &mut impl Write, hooks: &HashMap<String, Hook>, trigger: HookTrigger) -> Result<()> {
let section = match trigger {
HookTrigger::ConversationStart => "On Session Start",
HookTrigger::PerPrompt => "Per User Message",
};
let hooks: Vec<(&String, &Hook)> = hooks.iter().filter(|(_, h)| h.trigger == trigger).collect();

queue!(
output,
style::SetForegroundColor(Color::Cyan),
style::Print(format!(" {section}:\n")),
style::SetForegroundColor(Color::Reset),
)?;

if hooks.is_empty() {
queue!(
output,
style::SetForegroundColor(Color::DarkGrey),
style::Print(" <none>\n"),
style::SetForegroundColor(Color::Reset)
)?;
} else {
for (name, hook) in hooks {
if hook.disabled {
queue!(
output,
style::SetForegroundColor(Color::DarkGrey),
style::Print(format!(" {} (disabled)\n", name)),
style::SetForegroundColor(Color::Reset)
)?;
} else {
queue!(output, style::Print(format!(" {}\n", name)),)?;
}
}
}
Ok(())
}

#[derive(Debug)]
struct ToolUseEventBuilder {
pub conversation_id: String,
Expand Down
Loading