@@ -366,7 +366,8 @@ async fn process_path(
366366///
367367/// This method:
368368/// 1. Reads the content of the file
369- /// 2. Adds the (filename, content) pair to the context collection
369+ /// 2. Checks front matter inclusion rules for steering files
370+ /// 3. Adds the (filename, content) pair to the context collection if allowed
370371///
371372/// # Arguments
372373/// * `path` - The path to the file
@@ -377,10 +378,71 @@ async fn process_path(
377378async fn add_file_to_context ( os : & Os , path : & Path , context_files : & mut Vec < ( String , String ) > ) -> Result < ( ) > {
378379 let filename = path. to_string_lossy ( ) . to_string ( ) ;
379380 let content = os. fs . read_to_string ( path) . await ?;
381+
382+ // Check if this is a steering file that needs front matter filtering
383+ if filename. contains ( ".kiro/steering" ) && filename. ends_with ( ".md" ) {
384+ if !should_include_steering_file ( & content) ? {
385+ return Ok ( ( ) ) ;
386+ }
387+ }
388+
380389 context_files. push ( ( filename, content) ) ;
381390 Ok ( ( ) )
382391}
383392
393+ #[ derive( Debug , Deserialize ) ]
394+ struct FrontMatter {
395+ inclusion : Option < String > ,
396+ }
397+
398+ /// Check if a steering file should be included based on its front matter
399+ fn should_include_steering_file ( content : & str ) -> Result < bool > {
400+ // Check if file has YAML front matter
401+ if !content. starts_with ( "---\n " ) {
402+ // No front matter - include the file
403+ return Ok ( true ) ;
404+ }
405+
406+ // Find the end of the front matter
407+ let lines: Vec < & str > = content. lines ( ) . collect ( ) ;
408+ let mut end_index = None ;
409+
410+ for ( i, line) in lines. iter ( ) . enumerate ( ) . skip ( 1 ) {
411+ if line. trim ( ) == "---" {
412+ end_index = Some ( i) ;
413+ break ;
414+ }
415+ }
416+
417+ let end_index = match end_index {
418+ Some ( idx) => idx,
419+ None => {
420+ // Malformed front matter - include the file
421+ return Ok ( true ) ;
422+ }
423+ } ;
424+
425+ // Extract and parse the front matter
426+ let front_matter_lines = & lines[ 1 ..end_index] ;
427+ let front_matter_yaml = front_matter_lines. join ( "\n " ) ;
428+
429+ match serde_yaml:: from_str :: < FrontMatter > ( & front_matter_yaml) {
430+ Ok ( front_matter) => {
431+ match front_matter. inclusion . as_deref ( ) {
432+ Some ( "always" ) => Ok ( true ) ,
433+ Some ( "fileMatch" ) => Ok ( false ) , // Exclude fileMatch files
434+ Some ( "manual" ) => Ok ( false ) , // Exclude manual files
435+ None => Ok ( true ) , // No inclusion field - include
436+ Some ( _) => Ok ( true ) , // Unknown inclusion value - include
437+ }
438+ }
439+ Err ( _) => {
440+ // Failed to parse front matter - include the file
441+ Ok ( true )
442+ }
443+ }
444+ }
445+
384446#[ cfg( test) ]
385447mod tests {
386448 use super :: * ;
@@ -458,4 +520,35 @@ mod tests {
458520 96_000
459521 ) ;
460522 }
523+
524+ #[ test]
525+ fn test_should_include_steering_file ( ) {
526+ // Test file without front matter - should be included
527+ let content_no_frontmatter = "# Regular markdown file\n Some content here." ;
528+ assert ! ( should_include_steering_file( content_no_frontmatter) . unwrap( ) ) ;
529+
530+ // Test file with inclusion: always - should be included
531+ let content_always = "---\n inclusion: always\n ---\n # Always included\n Content here." ;
532+ assert ! ( should_include_steering_file( content_always) . unwrap( ) ) ;
533+
534+ // Test file with inclusion: fileMatch - should be excluded
535+ let content_filematch = "---\n inclusion: fileMatch\n ---\n # File match only\n Content here." ;
536+ assert ! ( !should_include_steering_file( content_filematch) . unwrap( ) ) ;
537+
538+ // Test file with inclusion: manual - should be excluded
539+ let content_manual = "---\n inclusion: manual\n ---\n # Manual only\n Content here." ;
540+ assert ! ( !should_include_steering_file( content_manual) . unwrap( ) ) ;
541+
542+ // Test file with no inclusion field - should be included
543+ let content_no_inclusion = "---\n title: Some Title\n ---\n # No inclusion field\n Content here." ;
544+ assert ! ( should_include_steering_file( content_no_inclusion) . unwrap( ) ) ;
545+
546+ // Test file with malformed front matter - should be included
547+ let content_malformed = "---\n invalid yaml: [\n ---\n # Malformed\n Content here." ;
548+ assert ! ( should_include_steering_file( content_malformed) . unwrap( ) ) ;
549+
550+ // Test file with incomplete front matter - should be included
551+ let content_incomplete = "---\n inclusion: always\n # Missing closing ---\n Content here." ;
552+ assert ! ( should_include_steering_file( content_incomplete) . unwrap( ) ) ;
553+ }
461554}
0 commit comments