@@ -759,6 +759,24 @@ enum LearnSub {
759759 #[ arg( long) ]
760760 correction : String ,
761761 } ,
762+ /// Record a user correction (tool preference, naming, workflow, etc.)
763+ Correction {
764+ /// What the agent said/did originally
765+ #[ arg( long) ]
766+ original : String ,
767+ /// What the user said instead
768+ #[ arg( long) ]
769+ corrected : String ,
770+ /// Type of correction
771+ #[ arg( long, default_value = "other" ) ]
772+ correction_type : String ,
773+ /// Context description
774+ #[ arg( long, default_value = "" ) ]
775+ context : String ,
776+ /// Session ID for traceability
777+ #[ arg( long) ]
778+ session_id : Option < String > ,
779+ } ,
762780 /// Process hook input from AI agents (reads JSON from stdin)
763781 Hook {
764782 /// AI agent format
@@ -1936,8 +1954,8 @@ async fn run_offline_command(
19361954
19371955async fn run_learn_command ( sub : LearnSub ) -> Result < ( ) > {
19381956 use learnings:: {
1939- LearningCaptureConfig , capture_failed_command , correct_learning , list_learnings ,
1940- query_learnings ,
1957+ CorrectionType , LearningCaptureConfig , capture_correction , capture_failed_command ,
1958+ correct_learning , list_all_entries , query_all_entries ,
19411959 } ;
19421960 let config = LearningCaptureConfig :: default ( ) ;
19431961
@@ -1974,25 +1992,19 @@ async fn run_learn_command(sub: LearnSub) -> Result<()> {
19741992 } else {
19751993 & storage_loc
19761994 } ;
1977- match list_learnings ( storage_dir, recent) {
1978- Ok ( learnings ) => {
1979- if learnings . is_empty ( ) {
1995+ match list_all_entries ( storage_dir, recent) {
1996+ Ok ( entries ) => {
1997+ if entries . is_empty ( ) {
19801998 println ! ( "No learnings found." ) ;
19811999 } else {
19822000 println ! ( "Recent learnings:" ) ;
1983- for ( i, learning ) in learnings . iter ( ) . enumerate ( ) {
1984- let source_indicator = match learning . source {
2001+ for ( i, entry ) in entries . iter ( ) . enumerate ( ) {
2002+ let source_indicator = match entry . source ( ) {
19852003 learnings:: LearningSource :: Project => "[P]" ,
19862004 learnings:: LearningSource :: Global => "[G]" ,
19872005 } ;
1988- println ! (
1989- " {}. {} {} (exit: {})" ,
1990- i + 1 ,
1991- source_indicator,
1992- learning. command,
1993- learning. exit_code
1994- ) ;
1995- if let Some ( ref correction) = learning. correction {
2006+ println ! ( " {}. {} {}" , i + 1 , source_indicator, entry. summary( ) ) ;
2007+ if let Some ( correction) = entry. correction_text ( ) {
19962008 println ! ( " Correction: {}" , correction) ;
19972009 }
19982010 }
@@ -2013,22 +2025,19 @@ async fn run_learn_command(sub: LearnSub) -> Result<()> {
20132025 } else {
20142026 & storage_loc
20152027 } ;
2016- match query_learnings ( storage_dir, & pattern, exact) {
2017- Ok ( learnings ) => {
2018- if learnings . is_empty ( ) {
2028+ match query_all_entries ( storage_dir, & pattern, exact) {
2029+ Ok ( entries ) => {
2030+ if entries . is_empty ( ) {
20192031 println ! ( "No learnings matching '{}'." , pattern) ;
20202032 } else {
2021- println ! ( "Learnings matching '{}': " , pattern) ;
2022- for learning in learnings {
2023- let source_indicator = match learning . source {
2033+ println ! ( "Learnings matching '{}'. " , pattern) ;
2034+ for entry in entries {
2035+ let source_indicator = match entry . source ( ) {
20242036 learnings:: LearningSource :: Project => "[P]" ,
20252037 learnings:: LearningSource :: Global => "[G]" ,
20262038 } ;
2027- println ! (
2028- " {} {} (exit: {})" ,
2029- source_indicator, learning. command, learning. exit_code
2030- ) ;
2031- if let Some ( ref correction) = learning. correction {
2039+ println ! ( " {} {}" , source_indicator, entry. summary( ) ) ;
2040+ if let Some ( correction) = entry. correction_text ( ) {
20322041 println ! ( " Correction: {}" , correction) ;
20332042 }
20342043 }
@@ -2051,6 +2060,33 @@ async fn run_learn_command(sub: LearnSub) -> Result<()> {
20512060 }
20522061 }
20532062 }
2063+ LearnSub :: Correction {
2064+ original,
2065+ corrected,
2066+ correction_type,
2067+ context,
2068+ session_id,
2069+ } => {
2070+ let ct: CorrectionType = correction_type
2071+ . parse ( )
2072+ . unwrap_or ( CorrectionType :: Other ( correction_type. clone ( ) ) ) ;
2073+ let correction = capture_correction ( ct, & original, & corrected, & context, & config) ;
2074+ if let Some ( ref sid) = session_id {
2075+ // We need to read the file and update it with session_id
2076+ // For now, just print the session_id
2077+ log:: info!( "Session ID: {}" , sid) ;
2078+ }
2079+ match correction {
2080+ Ok ( path) => {
2081+ println ! ( "Captured correction: {}" , path. display( ) ) ;
2082+ Ok ( ( ) )
2083+ }
2084+ Err ( e) => {
2085+ eprintln ! ( "Failed to capture correction: {}" , e) ;
2086+ Err ( e. into ( ) )
2087+ }
2088+ }
2089+ }
20542090 LearnSub :: Hook { format } => learnings:: process_hook_input ( format)
20552091 . await
20562092 . map_err ( |e| e. into ( ) ) ,
0 commit comments