| 475 | } |
| 476 | |
| 477 | private parseTasks(content: string): Task[] { |
| 478 | debug('Parsing tasks from content...'); |
| 479 | const tasks: Task[] = []; |
| 480 | const lines = content.split('\n'); |
| 481 | debug('Total lines:', lines.length); |
| 482 | |
| 483 | // Let's test what the actual lines look like |
| 484 | lines.slice(0, 20).forEach((line, i) => { |
| 485 | if (line.includes('[') && line.includes(']')) { |
| 486 | debug(`Line ${i}: "${line}"`); |
| 487 | } |
| 488 | }); |
| 489 | |
| 490 | // Match the actual format: "- [x] 1. Create GraphQL queries..." or "- [ ] **1. Task description**" |
| 491 | const taskRegex = /^(\s*)- \[([ x])\] (?:\*\*)?(\d+(?:\.\d+)*)\. (.+?)(?:\*\*)?$/; |
| 492 | const requirementsRegex = /_Requirements: ([\d., ]+)/; |
| 493 | const leverageRegex = /_Leverage: (.+)$/; |
| 494 | // Removed _In Progress: parsing - now automatically using first uncompleted task |
| 495 | |
| 496 | let currentTask: Task | null = null; |
| 497 | let parentStack: { level: number; task: Task }[] = []; |
| 498 | |
| 499 | for (const line of lines) { |
| 500 | const match = line.match(taskRegex); |
| 501 | if (match) { |
| 502 | const indent = match[1] || ''; |
| 503 | const checked = match[2] || ''; |
| 504 | const id = match[3] || ''; |
| 505 | const description = match[4] || ''; |
| 506 | const level = indent.length / 2; |
| 507 | |
| 508 | currentTask = { |
| 509 | id, |
| 510 | description: description?.trim() || '', |
| 511 | completed: checked === 'x', |
| 512 | requirements: [], |
| 513 | }; |
| 514 | |
| 515 | // Find parent based on level |
| 516 | while (parentStack.length > 0 && parentStack[parentStack.length - 1]!.level >= level) { |
| 517 | parentStack.pop(); |
| 518 | } |
| 519 | |
| 520 | if (parentStack.length > 0) { |
| 521 | const parent = parentStack[parentStack.length - 1]!.task; |
| 522 | if (!parent.subtasks) parent.subtasks = []; |
| 523 | parent.subtasks.push(currentTask); |
| 524 | } else { |
| 525 | tasks.push(currentTask); |
| 526 | } |
| 527 | |
| 528 | parentStack.push({ level, task: currentTask }); |
| 529 | } else if (currentTask) { |
| 530 | // Check for requirements |
| 531 | const reqMatch = line.match(requirementsRegex); |
| 532 | if (reqMatch?.[1]) { |
| 533 | currentTask.requirements = reqMatch[1].split(',').map((r) => r.trim()); |
| 534 | } |