@@ -117,6 +117,48 @@ const SLASH_COMMAND_SPECS: &[SlashCommandSpec] = &[
117117 argument_hint : None ,
118118 resume_supported : true ,
119119 } ,
120+ SlashCommandSpec {
121+ name : "bughunter" ,
122+ summary : "Inspect the codebase for likely bugs" ,
123+ argument_hint : Some ( "[scope]" ) ,
124+ resume_supported : false ,
125+ } ,
126+ SlashCommandSpec {
127+ name : "commit" ,
128+ summary : "Generate a commit message and create a git commit" ,
129+ argument_hint : None ,
130+ resume_supported : false ,
131+ } ,
132+ SlashCommandSpec {
133+ name : "pr" ,
134+ summary : "Draft or create a pull request from the conversation" ,
135+ argument_hint : Some ( "[context]" ) ,
136+ resume_supported : false ,
137+ } ,
138+ SlashCommandSpec {
139+ name : "issue" ,
140+ summary : "Draft or create a GitHub issue from the conversation" ,
141+ argument_hint : Some ( "[context]" ) ,
142+ resume_supported : false ,
143+ } ,
144+ SlashCommandSpec {
145+ name : "ultraplan" ,
146+ summary : "Run a deep planning prompt with multi-step reasoning" ,
147+ argument_hint : Some ( "[task]" ) ,
148+ resume_supported : false ,
149+ } ,
150+ SlashCommandSpec {
151+ name : "teleport" ,
152+ summary : "Jump to a file or symbol by searching the workspace" ,
153+ argument_hint : Some ( "<symbol-or-path>" ) ,
154+ resume_supported : false ,
155+ } ,
156+ SlashCommandSpec {
157+ name : "debug-tool-call" ,
158+ summary : "Replay the last tool call with debug details" ,
159+ argument_hint : None ,
160+ resume_supported : false ,
161+ } ,
120162 SlashCommandSpec {
121163 name : "export" ,
122164 summary : "Export the current conversation to a file" ,
@@ -136,6 +178,23 @@ pub enum SlashCommand {
136178 Help ,
137179 Status ,
138180 Compact ,
181+ Bughunter {
182+ scope : Option < String > ,
183+ } ,
184+ Commit ,
185+ Pr {
186+ context : Option < String > ,
187+ } ,
188+ Issue {
189+ context : Option < String > ,
190+ } ,
191+ Ultraplan {
192+ task : Option < String > ,
193+ } ,
194+ Teleport {
195+ target : Option < String > ,
196+ } ,
197+ DebugToolCall ,
139198 Model {
140199 model : Option < String > ,
141200 } ,
@@ -180,6 +239,23 @@ impl SlashCommand {
180239 "help" => Self :: Help ,
181240 "status" => Self :: Status ,
182241 "compact" => Self :: Compact ,
242+ "bughunter" => Self :: Bughunter {
243+ scope : remainder_after_command ( trimmed, command) ,
244+ } ,
245+ "commit" => Self :: Commit ,
246+ "pr" => Self :: Pr {
247+ context : remainder_after_command ( trimmed, command) ,
248+ } ,
249+ "issue" => Self :: Issue {
250+ context : remainder_after_command ( trimmed, command) ,
251+ } ,
252+ "ultraplan" => Self :: Ultraplan {
253+ task : remainder_after_command ( trimmed, command) ,
254+ } ,
255+ "teleport" => Self :: Teleport {
256+ target : remainder_after_command ( trimmed, command) ,
257+ } ,
258+ "debug-tool-call" => Self :: DebugToolCall ,
183259 "model" => Self :: Model {
184260 model : parts. next ( ) . map ( ToOwned :: to_owned) ,
185261 } ,
@@ -212,6 +288,15 @@ impl SlashCommand {
212288 }
213289}
214290
291+ fn remainder_after_command ( input : & str , command : & str ) -> Option < String > {
292+ input
293+ . trim ( )
294+ . strip_prefix ( & format ! ( "/{command}" ) )
295+ . map ( str:: trim)
296+ . filter ( |value| !value. is_empty ( ) )
297+ . map ( ToOwned :: to_owned)
298+ }
299+
215300#[ must_use]
216301pub fn slash_command_specs ( ) -> & ' static [ SlashCommandSpec ] {
217302 SLASH_COMMAND_SPECS
@@ -279,6 +364,13 @@ pub fn handle_slash_command(
279364 session : session. clone ( ) ,
280365 } ) ,
281366 SlashCommand :: Status
367+ | SlashCommand :: Bughunter { .. }
368+ | SlashCommand :: Commit
369+ | SlashCommand :: Pr { .. }
370+ | SlashCommand :: Issue { .. }
371+ | SlashCommand :: Ultraplan { .. }
372+ | SlashCommand :: Teleport { .. }
373+ | SlashCommand :: DebugToolCall
282374 | SlashCommand :: Model { .. }
283375 | SlashCommand :: Permissions { .. }
284376 | SlashCommand :: Clear { .. }
@@ -307,6 +399,41 @@ mod tests {
307399 fn parses_supported_slash_commands ( ) {
308400 assert_eq ! ( SlashCommand :: parse( "/help" ) , Some ( SlashCommand :: Help ) ) ;
309401 assert_eq ! ( SlashCommand :: parse( " /status " ) , Some ( SlashCommand :: Status ) ) ;
402+ assert_eq ! (
403+ SlashCommand :: parse( "/bughunter runtime" ) ,
404+ Some ( SlashCommand :: Bughunter {
405+ scope: Some ( "runtime" . to_string( ) )
406+ } )
407+ ) ;
408+ assert_eq ! ( SlashCommand :: parse( "/commit" ) , Some ( SlashCommand :: Commit ) ) ;
409+ assert_eq ! (
410+ SlashCommand :: parse( "/pr ready for review" ) ,
411+ Some ( SlashCommand :: Pr {
412+ context: Some ( "ready for review" . to_string( ) )
413+ } )
414+ ) ;
415+ assert_eq ! (
416+ SlashCommand :: parse( "/issue flaky test" ) ,
417+ Some ( SlashCommand :: Issue {
418+ context: Some ( "flaky test" . to_string( ) )
419+ } )
420+ ) ;
421+ assert_eq ! (
422+ SlashCommand :: parse( "/ultraplan ship both features" ) ,
423+ Some ( SlashCommand :: Ultraplan {
424+ task: Some ( "ship both features" . to_string( ) )
425+ } )
426+ ) ;
427+ assert_eq ! (
428+ SlashCommand :: parse( "/teleport conversation.rs" ) ,
429+ Some ( SlashCommand :: Teleport {
430+ target: Some ( "conversation.rs" . to_string( ) )
431+ } )
432+ ) ;
433+ assert_eq ! (
434+ SlashCommand :: parse( "/debug-tool-call" ) ,
435+ Some ( SlashCommand :: DebugToolCall )
436+ ) ;
310437 assert_eq ! (
311438 SlashCommand :: parse( "/model claude-opus" ) ,
312439 Some ( SlashCommand :: Model {
@@ -374,6 +501,13 @@ mod tests {
374501 assert ! ( help. contains( "/help" ) ) ;
375502 assert ! ( help. contains( "/status" ) ) ;
376503 assert ! ( help. contains( "/compact" ) ) ;
504+ assert ! ( help. contains( "/bughunter [scope]" ) ) ;
505+ assert ! ( help. contains( "/commit" ) ) ;
506+ assert ! ( help. contains( "/pr [context]" ) ) ;
507+ assert ! ( help. contains( "/issue [context]" ) ) ;
508+ assert ! ( help. contains( "/ultraplan [task]" ) ) ;
509+ assert ! ( help. contains( "/teleport <symbol-or-path>" ) ) ;
510+ assert ! ( help. contains( "/debug-tool-call" ) ) ;
377511 assert ! ( help. contains( "/model [model]" ) ) ;
378512 assert ! ( help. contains( "/permissions [read-only|workspace-write|danger-full-access]" ) ) ;
379513 assert ! ( help. contains( "/clear [--confirm]" ) ) ;
@@ -386,7 +520,7 @@ mod tests {
386520 assert ! ( help. contains( "/version" ) ) ;
387521 assert ! ( help. contains( "/export [file]" ) ) ;
388522 assert ! ( help. contains( "/session [list|switch <session-id>]" ) ) ;
389- assert_eq ! ( slash_command_specs( ) . len( ) , 15 ) ;
523+ assert_eq ! ( slash_command_specs( ) . len( ) , 22 ) ;
390524 assert_eq ! ( resume_supported_slash_commands( ) . len( ) , 11 ) ;
391525 }
392526
@@ -434,6 +568,22 @@ mod tests {
434568 let session = Session :: new ( ) ;
435569 assert ! ( handle_slash_command( "/unknown" , & session, CompactionConfig :: default ( ) ) . is_none( ) ) ;
436570 assert ! ( handle_slash_command( "/status" , & session, CompactionConfig :: default ( ) ) . is_none( ) ) ;
571+ assert ! (
572+ handle_slash_command( "/bughunter" , & session, CompactionConfig :: default ( ) ) . is_none( )
573+ ) ;
574+ assert ! ( handle_slash_command( "/commit" , & session, CompactionConfig :: default ( ) ) . is_none( ) ) ;
575+ assert ! ( handle_slash_command( "/pr" , & session, CompactionConfig :: default ( ) ) . is_none( ) ) ;
576+ assert ! ( handle_slash_command( "/issue" , & session, CompactionConfig :: default ( ) ) . is_none( ) ) ;
577+ assert ! (
578+ handle_slash_command( "/ultraplan" , & session, CompactionConfig :: default ( ) ) . is_none( )
579+ ) ;
580+ assert ! (
581+ handle_slash_command( "/teleport foo" , & session, CompactionConfig :: default ( ) ) . is_none( )
582+ ) ;
583+ assert ! (
584+ handle_slash_command( "/debug-tool-call" , & session, CompactionConfig :: default ( ) )
585+ . is_none( )
586+ ) ;
437587 assert ! (
438588 handle_slash_command( "/model claude" , & session, CompactionConfig :: default ( ) ) . is_none( )
439589 ) ;
0 commit comments