@@ -132,6 +132,32 @@ for (const metadata of requiredHelpMetadata) {
132132 throw new Error ( `help.html is missing SEO/AEO metadata: ${ metadata } ` ) ;
133133 }
134134}
135+ const helpStructuredDataMatch = helpPage . match ( / < s c r i p t t y p e = " a p p l i c a t i o n \/ l d \+ j s o n " > ( [ \s \S ] * ?) < \/ s c r i p t > / ) ;
136+ if ( ! helpStructuredDataMatch ) {
137+ throw new Error ( 'help.html must contain JSON-LD structured data' ) ;
138+ }
139+ const helpStructuredData = JSON . parse ( helpStructuredDataMatch [ 1 ] ) ;
140+ const helpFaqPage = helpStructuredData [ '@graph' ] . find ( item => (
141+ Array . isArray ( item [ '@type' ] ) && item [ '@type' ] . includes ( 'FAQPage' )
142+ ) ) ;
143+ const helpVisibleText = helpPage
144+ . replace ( / < s c r i p t [ \s \S ] * ?< \/ s c r i p t > / g, ' ' )
145+ . replace ( / < [ ^ > ] + > / g, '' )
146+ . replaceAll ( '&' , '&' )
147+ . replaceAll ( '"' , '"' )
148+ . replaceAll ( ''' , "'" )
149+ . replaceAll ( '<' , '<' )
150+ . replaceAll ( '>' , '>' )
151+ . replaceAll ( ' ' , ' ' )
152+ . replace ( / \s + / g, ' ' ) ;
153+ for ( const question of helpFaqPage ?. mainEntity || [ ] ) {
154+ if ( ! helpVisibleText . includes ( question . name ) || ! helpVisibleText . includes ( question . acceptedAnswer ?. text ) ) {
155+ throw new Error ( `help.html FAQ content must be visible and exact: ${ question . name } ` ) ;
156+ }
157+ }
158+ if ( ( helpPage . match ( / c l a s s = " s u p p o r t - c a r d s u p p o r t - a n c h o r - s e c t i o n s u p p o r t - a c c o r d i o n " / g) || [ ] ) . length < 10 ) {
159+ throw new Error ( 'help.html must keep advanced and troubleshooting sections compact with native accordions' ) ;
160+ }
135161if ( ! llmsText . includes ( '[Help Center](https://sync.koalastuff.net/help)' )
136162 || ! llmsText . includes ( '[Website access guide](https://sync.koalastuff.net/site-access-help)' ) ) {
137163 throw new Error ( 'llms.txt must expose the Help Center and website-access guide' ) ;
0 commit comments