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