@@ -408,6 +408,41 @@ fn get_mention_snippet(params: &ContextParams, file_id: i64, name: &str) -> Stri
408408 String :: new ( )
409409}
410410
411+ // ---------------------------------------------------------------------------
412+ // Section reading
413+ // ---------------------------------------------------------------------------
414+
415+ #[ derive( Debug , Serialize ) ]
416+ pub struct SectionResult {
417+ pub path : String ,
418+ pub heading : String ,
419+ pub content : String ,
420+ pub line_start : usize ,
421+ pub line_end : usize ,
422+ }
423+
424+ pub fn read_section (
425+ store : & Store ,
426+ vault_root : & Path ,
427+ file : & str ,
428+ heading : & str ,
429+ ) -> Result < SectionResult > {
430+ let record = store
431+ . resolve_file ( file) ?
432+ . ok_or_else ( || anyhow:: anyhow!( "Not found: {file}" ) ) ?;
433+ let path = vault_root. join ( & record. path ) ;
434+ let content = std:: fs:: read_to_string ( & path) ?;
435+ let section = crate :: markdown:: find_section ( & content, heading)
436+ . ok_or_else ( || anyhow:: anyhow!( "Section not found: {heading}" ) ) ?;
437+ Ok ( SectionResult {
438+ path : record. path ,
439+ heading : section. heading . text ,
440+ content : section. content ,
441+ line_start : section. body_start ,
442+ line_end : section. body_end ,
443+ } )
444+ }
445+
411446/// Build a project context bundle: note, child notes, tasks, team, recent mentions.
412447pub fn context_project ( params : & ContextParams , name : & str ) -> Result < ProjectContext > {
413448 let ( note, project_id, project_folder) = if let Some ( pf) = resolve_file ( params, name) ? {
@@ -1112,4 +1147,20 @@ mod tests {
11121147 assert ! ( s. is_char_boundary( snap) ) ;
11131148 assert ! ( snap <= 6 ) ;
11141149 }
1150+
1151+ #[ test]
1152+ fn test_read_section ( ) {
1153+ let tmp = TempDir :: new ( ) . unwrap ( ) ;
1154+ let root = tmp. path ( ) . to_path_buf ( ) ;
1155+ let store = Store :: open_memory ( ) . unwrap ( ) ;
1156+ let content = "# Person\n \n ## Role\n \n Engineer\n \n ## Interactions\n \n Met on 2026-03-26\n " ;
1157+ std:: fs:: write ( root. join ( "person.md" ) , content) . unwrap ( ) ;
1158+ store
1159+ . insert_file ( "person.md" , "hash" , 100 , & [ ] , "per123" , None )
1160+ . unwrap ( ) ;
1161+
1162+ let result = read_section ( & store, & root, "person.md" , "Interactions" ) . unwrap ( ) ;
1163+ assert ! ( result. content. contains( "Met on 2026-03-26" ) ) ;
1164+ assert ! ( !result. content. contains( "Engineer" ) ) ;
1165+ }
11151166}
0 commit comments