@@ -283,20 +283,28 @@ export class DemoValidationService {
283283 continue ;
284284 }
285285
286- // Detect start of a new demo
286+ // Detect start of a new demo object
287287 let isNewDemo = false ;
288288 if ( isYaml ) {
289- // YAML: look for "- id:" or "- title:" or just "- " at start of line (accounting for indentation)
290- if (
291- trimmedLine . startsWith ( '- ' ) &&
292- ( trimmedLine . includes ( 'id:' ) || trimmedLine . includes ( 'title:' ) || trimmedLine === '-' )
293- ) {
294- isNewDemo = true ;
289+ // YAML: look for lines that start with "- " but be more specific
290+ // We need to ensure we're detecting actual demo items, not sub-items like steps
291+ if ( trimmedLine . startsWith ( '- ' ) ) {
292+ // Check if this is likely a demo object by looking for demo properties
293+ const isLikelyDemo = this . isLikelyYamlDemoObject ( lines , lineNum ) ;
294+ if ( isLikelyDemo ) {
295+ isNewDemo = true ;
296+ }
295297 }
296298 } else {
297- // JSON: look for opening brace that starts a demo object
298- if ( trimmedLine === '{' ) {
299- isNewDemo = true ;
299+ // JSON: We need to be very specific about demo objects
300+ // A demo object should be a direct child of the demos array
301+ // Look for opening braces that are likely demo objects by checking the next few lines
302+ if ( trimmedLine === '{' && line . indexOf ( '{' ) > 0 ) {
303+ // Check if this brace is followed by demo-like properties within a reasonable distance
304+ const isLikelyDemo = this . isLikelyDemoObject ( lines , lineNum ) ;
305+ if ( isLikelyDemo ) {
306+ isNewDemo = true ;
307+ }
300308 }
301309 }
302310
@@ -314,6 +322,75 @@ export class DemoValidationService {
314322 return new Position ( 0 , 0 ) ;
315323 }
316324
325+ /**
326+ * Check if an opening brace is likely the start of a demo object
327+ */
328+ private static isLikelyDemoObject ( lines : string [ ] , braceLineNum : number ) : boolean {
329+ // Look for typical demo properties in the next few lines
330+ const searchLimit = Math . min ( braceLineNum + 10 , lines . length ) ;
331+
332+ for ( let i = braceLineNum + 1 ; i < searchLimit ; i ++ ) {
333+ const line = lines [ i ] ;
334+ const trimmedLine = line . trim ( ) ;
335+
336+ // Stop if we hit a closing brace at the same level
337+ if ( trimmedLine === '}' || trimmedLine === '},' ) {
338+ break ;
339+ }
340+
341+ // Look for demo-specific properties
342+ if (
343+ trimmedLine . includes ( '"id"' ) ||
344+ trimmedLine . includes ( '"title"' ) ||
345+ trimmedLine . includes ( '"description"' ) ||
346+ trimmedLine . includes ( '"steps"' )
347+ ) {
348+ return true ;
349+ }
350+ }
351+
352+ return false ;
353+ }
354+
355+ /**
356+ * Check if a YAML "- " line is likely the start of a demo object
357+ */
358+ private static isLikelyYamlDemoObject ( lines : string [ ] , dashLineNum : number ) : boolean {
359+ const startLine = lines [ dashLineNum ] ;
360+ const startIndentation = startLine . length - startLine . trimStart ( ) . length ;
361+ const searchLimit = Math . min ( dashLineNum + 15 , lines . length ) ;
362+
363+ // Look for demo-specific properties at the right indentation level
364+ for ( let i = dashLineNum ; i < searchLimit ; i ++ ) {
365+ const line = lines [ i ] ;
366+ const trimmedLine = line . trim ( ) ;
367+ const currentIndentation = line . length - line . trimStart ( ) . length ;
368+
369+ // Stop if we hit another "- " at the same indentation level (next demo)
370+ if (
371+ i > dashLineNum &&
372+ trimmedLine . startsWith ( '- ' ) &&
373+ currentIndentation <= startIndentation
374+ ) {
375+ break ;
376+ }
377+
378+ // Look for demo-specific properties
379+ if (
380+ trimmedLine . startsWith ( 'id:' ) ||
381+ trimmedLine . startsWith ( 'title:' ) ||
382+ trimmedLine . startsWith ( 'description:' ) ||
383+ trimmedLine . startsWith ( 'steps:' ) ||
384+ // Also check for inline format: "- id: value"
385+ ( i === dashLineNum && ( trimmedLine . includes ( 'id:' ) || trimmedLine . includes ( 'title:' ) ) )
386+ ) {
387+ return true ;
388+ }
389+ }
390+
391+ return false ;
392+ }
393+
317394 /**
318395 * Find a specific property within a demo object
319396 */
@@ -323,21 +400,26 @@ export class DemoValidationService {
323400 property : string ,
324401 isYaml : boolean ,
325402 ) : Position {
403+ const startIndentation = lines [ startLine ] . length - lines [ startLine ] . trimStart ( ) . length ;
404+
326405 for ( let lineNum = startLine ; lineNum < lines . length ; lineNum ++ ) {
327406 const line = lines [ lineNum ] ;
328407 const trimmedLine = line . trim ( ) ;
408+ const currentIndentation = line . length - line . trimStart ( ) . length ;
329409
330410 // Stop searching if we hit the next demo or end of current demo
331411 if ( lineNum > startLine ) {
332412 if ( isYaml ) {
333- if (
334- trimmedLine . startsWith ( '- ' ) &&
335- ( trimmedLine . includes ( 'id:' ) || trimmedLine . includes ( 'title:' ) )
336- ) {
413+ // In YAML, if we encounter another item at the same level or less indented, we've left this demo
414+ if ( trimmedLine . startsWith ( '- ' ) && currentIndentation <= startIndentation ) {
337415 break ; // Start of next demo
338416 }
339417 } else {
340- if ( trimmedLine === '}' || trimmedLine === '},' ) {
418+ // In JSON, look for closing brace at the same indentation level as the opening brace
419+ if (
420+ ( trimmedLine === '}' || trimmedLine === '},' ) &&
421+ currentIndentation <= startIndentation
422+ ) {
341423 break ; // End of current demo
342424 }
343425 }
@@ -358,8 +440,7 @@ export class DemoValidationService {
358440 }
359441
360442 // If property not found, return the demo start position
361- const indentation = lines [ startLine ] . length - lines [ startLine ] . trimStart ( ) . length ;
362- return new Position ( startLine , indentation ) ;
443+ return new Position ( startLine , startIndentation ) ;
363444 }
364445
365446 /**
0 commit comments