@@ -37,6 +37,13 @@ export interface DocItem {
3737 label ?: string ;
3838 description ?: string ;
3939 content : string ;
40+ /**
41+ * Sort key + explicit book-group placement (ADR-0046 §6), read from
42+ * frontmatter `order:`/`group:`. The book resolver honors both; absent
43+ * leaves them out so the schema defaults apply.
44+ */
45+ order ?: number ;
46+ group ?: string ;
4047 /**
4148 * Per-locale variants (ADR-0046 i18n), compiled from sibling
4249 * `<name>.<locale>.md` files. The base file is the default + fallback.
@@ -68,19 +75,30 @@ function frontmatterScalar(block: string, key: string): string | undefined {
6875}
6976
7077/**
71- * Strip a leading `---` frontmatter block; extract `title:` and
72- * `description:` if present (both optional, single-line scalars).
78+ * Strip a leading `---` frontmatter block; extract `title:`, `description:`,
79+ * `order:`, and `group:` if present (all optional, single-line scalars).
80+ * `order:` is parsed to a number and dropped when non-numeric.
7381 */
74- function parseFrontmatter ( raw : string ) : { title ?: string ; description ?: string ; body : string } {
82+ function parseFrontmatter ( raw : string ) : {
83+ title ?: string ;
84+ description ?: string ;
85+ order ?: number ;
86+ group ?: string ;
87+ body : string ;
88+ } {
7589 if ( ! raw . startsWith ( '---\n' ) && ! raw . startsWith ( '---\r\n' ) ) return { body : raw } ;
7690 const end = raw . indexOf ( '\n---' , 3 ) ;
7791 if ( end === - 1 ) return { body : raw } ;
7892 const block = raw . slice ( raw . indexOf ( '\n' ) + 1 , end ) ;
7993 const bodyStart = raw . indexOf ( '\n' , end + 1 ) ;
8094 const body = bodyStart === - 1 ? '' : raw . slice ( bodyStart + 1 ) ;
95+ const orderRaw = frontmatterScalar ( block , 'order' ) ;
96+ const order = orderRaw !== undefined ? Number ( orderRaw ) : undefined ;
8197 return {
8298 title : frontmatterScalar ( block , 'title' ) ,
8399 description : frontmatterScalar ( block , 'description' ) ,
100+ ...( order !== undefined && ! Number . isNaN ( order ) ? { order } : { } ) ,
101+ group : frontmatterScalar ( block , 'group' ) ,
84102 body,
85103 } ;
86104}
@@ -126,7 +144,7 @@ export function collectDocsFromSrc(configPath: string): { docs: DocItem[]; issue
126144
127145 const stem = entry . name . slice ( 0 , - 3 ) ;
128146 const raw = fs . readFileSync ( path . join ( docsDir , entry . name ) , 'utf-8' ) ;
129- const { title, description, body } = parseFrontmatter ( raw ) ;
147+ const { title, description, order , group , body } = parseFrontmatter ( raw ) ;
130148
131149 // Locale variant `<base>.<locale>.md` (ADR-0046 i18n) — checked before the
132150 // bare-name rule, since a variant stem legitimately contains a dot.
@@ -156,6 +174,8 @@ export function collectDocsFromSrc(configPath: string): { docs: DocItem[]; issue
156174 label : title ?? firstHeading ( body ) ,
157175 ...( description ? { description } : { } ) ,
158176 content : body ,
177+ ...( order !== undefined ? { order } : { } ) ,
178+ ...( group ? { group } : { } ) ,
159179 } ) ;
160180 }
161181
0 commit comments