Skip to content

Commit a3f93f3

Browse files
authored
fix: resolve bugs in bugbash for slash command refactor (#324)
1 parent 047180c commit a3f93f3

File tree

7 files changed

+106
-44
lines changed

7 files changed

+106
-44
lines changed

crates/chat-cli/src/cli/chat/cli/context.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ use crossterm::{
1010
style,
1111
};
1212

13+
use crate::cli::chat::cli::hooks::{
14+
HookTrigger,
15+
map_chat_error,
16+
print_hook_section,
17+
};
1318
use crate::cli::chat::consts::CONTEXT_FILES_MAX_SIZE;
1419
use crate::cli::chat::token_counter::TokenCounter;
1520
use crate::cli::chat::util::drop_matched_context_files;
@@ -125,6 +130,28 @@ impl ContextSubcommand {
125130
}
126131
}
127132

133+
if expand {
134+
execute!(
135+
session.stderr,
136+
style::SetAttribute(Attribute::Bold),
137+
style::SetForegroundColor(Color::DarkYellow),
138+
style::Print("\n 🔧 Hooks:\n")
139+
)?;
140+
print_hook_section(
141+
&mut session.stderr,
142+
&context_manager.global_config.hooks,
143+
HookTrigger::ConversationStart,
144+
)
145+
.map_err(map_chat_error)?;
146+
147+
print_hook_section(
148+
&mut session.stderr,
149+
&context_manager.global_config.hooks,
150+
HookTrigger::PerPrompt,
151+
)
152+
.map_err(map_chat_error)?;
153+
}
154+
128155
// Display profile context
129156
execute!(
130157
session.stderr,
@@ -162,6 +189,28 @@ impl ContextSubcommand {
162189
execute!(session.stderr, style::Print("\n"))?;
163190
}
164191

192+
if expand {
193+
execute!(
194+
session.stderr,
195+
style::SetAttribute(Attribute::Bold),
196+
style::SetForegroundColor(Color::DarkYellow),
197+
style::Print(" 🔧 Hooks:\n")
198+
)?;
199+
print_hook_section(
200+
&mut session.stderr,
201+
&context_manager.profile_config.hooks,
202+
HookTrigger::ConversationStart,
203+
)
204+
.map_err(map_chat_error)?;
205+
print_hook_section(
206+
&mut session.stderr,
207+
&context_manager.profile_config.hooks,
208+
HookTrigger::PerPrompt,
209+
)
210+
.map_err(map_chat_error)?;
211+
execute!(session.stderr, style::Print("\n"))?;
212+
}
213+
165214
if global_context_files.is_empty() && profile_context_files.is_empty() {
166215
execute!(
167216
session.stderr,

crates/chat-cli/src/cli/chat/cli/hooks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ impl HooksSubcommand {
716716
}
717717

718718
/// Prints hook configuration grouped by trigger: conversation session start or per user message
719-
fn print_hook_section(output: &mut impl Write, hooks: &HashMap<String, Hook>, trigger: HookTrigger) -> Result<()> {
719+
pub fn print_hook_section(output: &mut impl Write, hooks: &HashMap<String, Hook>, trigger: HookTrigger) -> Result<()> {
720720
let section = match trigger {
721721
HookTrigger::ConversationStart => "On Session Start",
722722
HookTrigger::PerPrompt => "Per User Message",
@@ -754,7 +754,7 @@ fn print_hook_section(output: &mut impl Write, hooks: &HashMap<String, Hook>, tr
754754
Ok(())
755755
}
756756

757-
fn map_chat_error(e: ErrReport) -> ChatError {
757+
pub fn map_chat_error(e: ErrReport) -> ChatError {
758758
ChatError::Custom(e.to_string().into())
759759
}
760760

crates/chat-cli/src/cli/chat/cli/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::os::Os;
4040

4141
/// q (Amazon Q Chat)
4242
#[derive(Debug, PartialEq, Parser)]
43-
#[command(color = clap::ColorChoice::Always, after_long_help = EXTRA_HELP)]
43+
#[command(color = clap::ColorChoice::Always, term_width = 0, after_long_help = EXTRA_HELP)]
4444
pub enum SlashCommand {
4545
/// Quit the application
4646
#[command(aliases = ["q", "exit"])]

crates/chat-cli/src/cli/chat/cli/prompts.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ pub enum GetPromptError {
4848

4949
#[deny(missing_docs)]
5050
#[derive(Debug, PartialEq, Args)]
51-
#[command(
52-
before_long_help = "Prompts are reusable templates that help you quickly access common workflows and tasks.
51+
#[command(color = clap::ColorChoice::Always,
52+
before_long_help = color_print::cstr!{"Prompts are reusable templates that help you quickly access common workflows and tasks.
5353
These templates are provided by the mcp servers you have installed and configured.
5454
5555
To actually retrieve a prompt, directly start with the following command (without prepending /prompt get):
56-
<em>@<<prompt name>> [arg]</em> <black!>Retrieve prompt specified</black!>
56+
<em>@<<prompt name>> [arg]</em> <black!>Retrieve prompt specified</black!>
5757
Or if you prefer the long way:
58-
<em>/prompts get <<prompt name>> [arg]</em> <black!>Retrieve prompt specified</black!>"
59-
)]
58+
<em>/prompts get <<prompt name>> [arg]</em> <black!>Retrieve prompt specified</black!>"
59+
})]
6060
pub struct PromptsArgs {
6161
#[command(subcommand)]
6262
subcommand: Option<PromptsSubcommand>,

crates/chat-cli/src/cli/chat/mod.rs

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ pub struct ChatArgs {
170170
#[arg(long, value_delimiter = ',', value_name = "TOOL_NAMES")]
171171
pub trust_tools: Option<Vec<String>>,
172172
/// Whether the command should run without expecting user input
173-
#[arg(long)]
173+
#[arg(long, alias = "no-interactive")]
174174
pub non_interactive: bool,
175175
/// The first question to ask
176176
pub input: Option<String>,
@@ -179,7 +179,7 @@ pub struct ChatArgs {
179179
impl ChatArgs {
180180
pub async fn execute(self, os: &mut Os) -> Result<ExitCode> {
181181
if self.non_interactive && self.input.is_none() {
182-
bail!("Input must be supplied when --non-interactive is set");
182+
bail!("Input must be supplied when running in non-interactive mode");
183183
}
184184

185185
let stdout = std::io::stdout();
@@ -353,11 +353,9 @@ const ROTATING_TIPS: [&str; 16] = [
353353

354354
const GREETING_BREAK_POINT: usize = 80;
355355

356-
const POPULAR_SHORTCUTS: &str = color_print::cstr! {"<black!><green!>/help</green!> all commands <em>•</em>
357-
<green!>ctrl + j</green!> new lines <em>•</em>
358-
<green!>ctrl + s</green!> fuzzy search <em>•</em>
359-
<green!>ctrl + f</green!> accept completion
360-
</black!>"};
356+
const POPULAR_SHORTCUTS: &str = color_print::cstr! {
357+
"<black!><green!>/help</green!> all commands <em>•</em> <green!>ctrl + j</green!> new lines
358+
<green!>ctrl + s</green!> fuzzy search <em>•</em> <green!>ctrl + f</green!> accept completion</black!>"};
361359
const SMALL_SCREEN_POPULAR_SHORTCUTS: &str = color_print::cstr! {"<black!><green!>/help</green!> all commands
362360
<green!>ctrl + j</green!> new lines
363361
<green!>ctrl + s</green!> fuzzy search
@@ -650,7 +648,7 @@ impl ChatSession {
650648
)?;
651649
}
652650

653-
let (context, report) = match err {
651+
let (context, report, display_err_message) = match err {
654652
ChatError::Interrupted { tool_uses: ref inter } => {
655653
execute!(self.stderr, style::Print("\n\n"))?;
656654

@@ -675,7 +673,7 @@ impl ChatSession {
675673
_ => (),
676674
}
677675

678-
("Tool use was interrupted", Report::from(err))
676+
("Tool use was interrupted", Report::from(err), false)
679677
},
680678
ChatError::Client(err) => match *err {
681679
// Errors from attempting to send too large of a conversation history. In
@@ -709,9 +707,10 @@ impl ChatSession {
709707
(
710708
"The context window has overflowed, summarizing the history...",
711709
Report::from(err),
710+
true,
712711
)
713712
},
714-
ApiClientError::QuotaBreach { message, .. } => (message, Report::from(err)),
713+
ApiClientError::QuotaBreach { message, .. } => (message, Report::from(err), true),
715714
ApiClientError::ModelOverloadedError { request_id, .. } => {
716715
let err = format!(
717716
"The model you've selected is temporarily unavailable. Please use '/model' to select a different model and try again.{}\n\n",
@@ -721,7 +720,7 @@ impl ChatSession {
721720
}
722721
);
723722
self.conversation.append_transcript(err.clone());
724-
("Amazon Q is having trouble responding right now", eyre!(err))
723+
("Amazon Q is having trouble responding right now", eyre!(err), true)
725724
},
726725
ApiClientError::MonthlyLimitReached { .. } => {
727726
let subscription_status = get_subscription_status(os).await;
@@ -778,33 +777,44 @@ impl ChatSession {
778777

779778
return Ok(());
780779
},
781-
_ => ("Amazon Q is having trouble responding right now", Report::from(err)),
780+
_ => (
781+
"Amazon Q is having trouble responding right now",
782+
Report::from(err),
783+
true,
784+
),
782785
},
783-
_ => ("Amazon Q is having trouble responding right now", Report::from(err)),
786+
_ => (
787+
"Amazon Q is having trouble responding right now",
788+
Report::from(err),
789+
true,
790+
),
784791
};
785792

786-
// Remove non-ASCII and ANSI characters.
787-
let re = Regex::new(r"((\x9B|\x1B\[)[0-?]*[ -\/]*[@-~])|([^\x00-\x7F]+)").unwrap();
793+
if display_err_message {
794+
// Remove non-ASCII and ANSI characters.
795+
let re = Regex::new(r"((\x9B|\x1B\[)[0-?]*[ -\/]*[@-~])|([^\x00-\x7F]+)").unwrap();
788796

789-
queue!(
790-
self.stderr,
791-
style::SetAttribute(Attribute::Bold),
792-
style::SetForegroundColor(Color::Red),
793-
)?;
797+
queue!(
798+
self.stderr,
799+
style::SetAttribute(Attribute::Bold),
800+
style::SetForegroundColor(Color::Red),
801+
)?;
794802

795-
let text = re.replace_all(&format!("{}: {:?}\n", context, report), "").into_owned();
803+
let text = re.replace_all(&format!("{}: {:?}\n", context, report), "").into_owned();
796804

797-
queue!(self.stderr, style::Print(&text),)?;
798-
self.conversation.append_transcript(text);
805+
queue!(self.stderr, style::Print(&text),)?;
806+
self.conversation.append_transcript(text);
799807

800-
execute!(
801-
self.stderr,
802-
style::SetAttribute(Attribute::Reset),
803-
style::SetForegroundColor(Color::Reset),
804-
)?;
808+
execute!(
809+
self.stderr,
810+
style::SetAttribute(Attribute::Reset),
811+
style::SetForegroundColor(Color::Reset),
812+
)?;
813+
}
805814

806815
self.conversation.enforce_conversation_invariants();
807816
self.conversation.reset_next_user_message();
817+
self.pending_tool_index = None;
808818

809819
self.inner = Some(ChatState::PromptUser {
810820
skip_printing_tools: false,

crates/chat-cli/src/cli/chat/prompt.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ pub const COMMANDS: &[&str] = &[
6161
"/profile delete",
6262
"/profile rename",
6363
"/profile set",
64+
"/prompts",
65+
"/context",
6466
"/context help",
6567
"/context show",
6668
"/context show --expand",
@@ -70,13 +72,14 @@ pub const COMMANDS: &[&str] = &[
7072
"/context rm --global",
7173
"/context clear",
7274
"/context clear --global",
73-
"/context hooks help",
74-
"/context hooks add",
75-
"/context hooks rm",
76-
"/context hooks enable",
77-
"/context hooks disable",
78-
"/context hooks enable-all",
79-
"/context hooks disable-all",
75+
"/hooks",
76+
"/hooks help",
77+
"/hooks add",
78+
"/hooks rm",
79+
"/hooks enable",
80+
"/hooks disable",
81+
"/hooks enable-all",
82+
"/hooks disable-all",
8083
"/compact",
8184
"/compact help",
8285
"/usage",

crates/chat-cli/src/cli/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ mod test {
434434
#[test]
435435
fn test_chat_with_no_interactive_and_resume() {
436436
assert_parse!(
437-
["chat", "--non-interactive", "--resume"],
437+
["chat", "--no-interactive", "--resume"],
438438
RootSubcommand::Chat(ChatArgs {
439439
resume: true,
440440
input: None,

0 commit comments

Comments
 (0)