lean-spec 0.2.10 → 0.2.15-dev.21022397862

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +100 -8
  2. package/bin/lean-spec-rust.js +116 -0
  3. package/bin/lean-spec.js +9 -1
  4. package/binaries/darwin-arm64/lean-spec +0 -0
  5. package/binaries/darwin-arm64/package.json +20 -0
  6. package/binaries/darwin-x64/lean-spec +0 -0
  7. package/binaries/darwin-x64/package.json +20 -0
  8. package/binaries/linux-arm64/lean-spec +0 -0
  9. package/binaries/linux-arm64/package.json +20 -0
  10. package/binaries/linux-x64/lean-spec +0 -0
  11. package/binaries/linux-x64/package.json +20 -0
  12. package/binaries/windows-x64/lean-spec.exe +0 -0
  13. package/binaries/windows-x64/package.json +20 -0
  14. package/package.json +9 -43
  15. package/templates/detailed/AGENTS.md +18 -1
  16. package/templates/standard/AGENTS.md +18 -1
  17. package/dist/backfill-446GBTBC.js +0 -5
  18. package/dist/backfill-446GBTBC.js.map +0 -1
  19. package/dist/chunk-CJMVV46H.js +0 -2990
  20. package/dist/chunk-CJMVV46H.js.map +0 -1
  21. package/dist/chunk-H5MCUMBK.js +0 -741
  22. package/dist/chunk-H5MCUMBK.js.map +0 -1
  23. package/dist/chunk-KTNU4LUR.js +0 -8214
  24. package/dist/chunk-KTNU4LUR.js.map +0 -1
  25. package/dist/chunk-RF5PKL6L.js +0 -298
  26. package/dist/chunk-RF5PKL6L.js.map +0 -1
  27. package/dist/chunk-VN5BUHTV.js +0 -300
  28. package/dist/chunk-VN5BUHTV.js.map +0 -1
  29. package/dist/cli.d.ts +0 -2
  30. package/dist/cli.js +0 -129
  31. package/dist/cli.js.map +0 -1
  32. package/dist/frontmatter-6ZBAGOEU.js +0 -3
  33. package/dist/frontmatter-6ZBAGOEU.js.map +0 -1
  34. package/dist/mcp-server.d.ts +0 -16
  35. package/dist/mcp-server.js +0 -8
  36. package/dist/mcp-server.js.map +0 -1
  37. package/dist/validate-DIWYTDEF.js +0 -5
  38. package/dist/validate-DIWYTDEF.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/git-timestamps.ts","../src/utils/path-helpers.ts","../src/utils/bootstrap-helpers.ts","../src/commands/backfill.ts"],"names":["result","fs2","path2","path3","matter","fs3"],"mappings":"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","file":"chunk-H5MCUMBK.js","sourcesContent":["import { execSync } from 'node:child_process';\nimport * as path from 'node:path';\nimport type { SpecStatus, StatusTransition } from '../frontmatter.js';\n\nexport interface GitTimestampData {\n created_at?: string;\n updated_at?: string;\n completed_at?: string;\n assignee?: string;\n transitions?: StatusTransition[];\n}\n\n/**\n * Check if the current directory is a git repository\n */\nexport function isGitRepository(): boolean {\n try {\n execSync('git rev-parse --is-inside-work-tree', { \n stdio: 'ignore',\n encoding: 'utf-8' \n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get the timestamp of the first commit that created a file\n */\nexport function getFirstCommitTimestamp(filePath: string): string | null {\n try {\n // Use --follow to track file renames\n // Use --diff-filter=A to find the commit that added the file\n // Format as ISO 8601 timestamp\n const timestamp = execSync(\n `git log --follow --format=\"%aI\" --diff-filter=A -- \"${filePath}\" | tail -1`,\n { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }\n ).trim();\n \n return timestamp || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the timestamp of the most recent commit that modified a file\n */\nexport function getLastCommitTimestamp(filePath: string): string | null {\n try {\n const timestamp = execSync(\n `git log --format=\"%aI\" -n 1 -- \"${filePath}\"`,\n { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }\n ).trim();\n \n return timestamp || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the timestamp when a spec was marked as complete\n * Searches git history for status changes to \"complete\"\n */\nexport function getCompletionTimestamp(filePath: string): string | null {\n try {\n // Get all commits that modified the file, with patch output\n const gitLog = execSync(\n `git log --format=\"%H|%aI\" -p -- \"${filePath}\"`,\n { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }\n );\n \n // Parse commits to find status change to complete\n const commits = gitLog.split('\\ndiff --git').map(section => section.trim());\n \n for (const commit of commits) {\n if (!commit) continue;\n \n // Extract commit hash and timestamp from header\n const headerMatch = commit.match(/^([a-f0-9]{40})\\|([^\\n]+)/);\n if (!headerMatch) continue;\n \n const [, , timestamp] = headerMatch;\n \n // Look for status: complete in the diff\n // Check for both YAML frontmatter and inline status changes\n if (\n /^\\+status:\\s*['\"]?complete['\"]?/m.test(commit) ||\n /^\\+\\*\\*Status\\*\\*:.*complete/mi.test(commit)\n ) {\n return timestamp;\n }\n }\n \n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the author of the first commit (for assignee inference)\n */\nexport function getFirstCommitAuthor(filePath: string): string | null {\n try {\n const author = execSync(\n `git log --follow --format=\"%an\" --diff-filter=A -- \"${filePath}\" | tail -1`,\n { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }\n ).trim();\n \n return author || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse all status transitions from git history\n * Reconstructs the full status change timeline\n */\nexport function parseStatusTransitions(filePath: string): StatusTransition[] {\n const transitions: StatusTransition[] = [];\n \n try {\n // Get all commits that modified the file, with patch output\n const gitLog = execSync(\n `git log --format=\"%H|%aI\" -p --reverse -- \"${filePath}\"`,\n { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] }\n );\n \n // Parse commits in chronological order (--reverse)\n const commits = gitLog.split('\\ndiff --git').map(section => section.trim());\n \n const validStatuses: SpecStatus[] = ['planned', 'in-progress', 'complete', 'archived'];\n \n for (const commit of commits) {\n if (!commit) continue;\n \n // Extract commit hash and timestamp from header\n const headerMatch = commit.match(/^([a-f0-9]{40})\\|([^\\n]+)/);\n if (!headerMatch) continue;\n \n const [, , timestamp] = headerMatch;\n \n // Look for status changes in the diff\n // Match: +status: complete or +status: 'complete'\n const statusMatch = commit.match(/^\\+status:\\s*['\"]?(\\w+(?:-\\w+)?)['\"]?/m);\n if (statusMatch) {\n const status = statusMatch[1] as SpecStatus;\n \n // Only record valid status values\n if (validStatuses.includes(status)) {\n // Avoid duplicate consecutive transitions\n const lastTransition = transitions[transitions.length - 1];\n if (!lastTransition || lastTransition.status !== status) {\n transitions.push({ status, at: timestamp });\n }\n }\n }\n }\n \n return transitions;\n } catch {\n return [];\n }\n}\n\n/**\n * Extract all git timestamp data for a spec file\n */\nexport function extractGitTimestamps(\n filePath: string,\n options: {\n includeAssignee?: boolean;\n includeTransitions?: boolean;\n } = {}\n): GitTimestampData {\n const data: GitTimestampData = {};\n \n // Core timestamps (always extracted)\n data.created_at = getFirstCommitTimestamp(filePath) ?? undefined;\n data.updated_at = getLastCommitTimestamp(filePath) ?? undefined;\n data.completed_at = getCompletionTimestamp(filePath) ?? undefined;\n \n // Optional fields\n if (options.includeAssignee) {\n const author = getFirstCommitAuthor(filePath);\n if (author) {\n data.assignee = author;\n }\n }\n \n if (options.includeTransitions) {\n const transitions = parseStatusTransitions(filePath);\n if (transitions.length > 0) {\n data.transitions = transitions;\n }\n }\n \n return data;\n}\n\n/**\n * Validate that a file exists in git history\n */\nexport function fileExistsInGit(filePath: string): boolean {\n try {\n execSync(\n `git log -n 1 -- \"${filePath}\"`,\n { stdio: 'ignore', encoding: 'utf-8' }\n );\n return true;\n } catch {\n return false;\n }\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Create a regex pattern to match spec directories with sequence numbers\n * Handles optional date prefixes like 20251103-001-name\n */\nexport function createSpecDirPattern(): RegExp {\n // Match spec directories, handling optional date prefix\n // Patterns:\n // - 001-name (simple sequence)\n // - 20251103-001-name (date prefix + sequence)\n // - spec-001-name (custom prefix + sequence)\n // - 001-测试 (Unicode/Chinese name)\n // We look for: optional-prefix + NNN + dash + name\n // The sequence is 2-4 digits (to avoid matching 8-digit dates as sequences)\n // Requires dash followed by non-digit/non-dash character to ensure this is a spec directory name\n // Uses [^0-9-] instead of [a-z] to support Unicode characters (Chinese, Japanese, etc.)\n return /(?:^|\\D)(\\d{2,4})-[^0-9-]/i;\n}\n\n/**\n * Get next global sequence number across entire specs directory\n */\nexport async function getGlobalNextSeq(specsDir: string, digits: number): Promise<string> {\n try {\n // Recursively find all spec directories with sequence numbers\n const seqNumbers: number[] = [];\n const specPattern = createSpecDirPattern();\n \n async function scanDirectory(dir: string): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n \n // Check if this is a spec directory (NNN-name format)\n const match = entry.name.match(specPattern);\n if (match) {\n const seqNum = parseInt(match[1], 10);\n if (!isNaN(seqNum) && seqNum > 0) {\n seqNumbers.push(seqNum);\n }\n }\n \n // Skip archived directory to avoid confusion\n if (entry.name === 'archived') continue;\n \n // Recursively scan subdirectories (for custom pattern grouping)\n const subDir = path.join(dir, entry.name);\n await scanDirectory(subDir);\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n }\n \n await scanDirectory(specsDir);\n \n if (seqNumbers.length === 0) {\n return '1'.padStart(digits, '0');\n }\n \n const maxSeq = Math.max(...seqNumbers);\n return String(maxSeq + 1).padStart(digits, '0');\n } catch {\n return '1'.padStart(digits, '0');\n }\n}\n\n/**\n * Get next sequence number for a date directory (legacy, kept for backward compatibility)\n */\nexport async function getNextSeq(dateDir: string, digits: number): Promise<string> {\n try {\n const specPattern = createSpecDirPattern();\n const entries = await fs.readdir(dateDir, { withFileTypes: true });\n const seqNumbers = entries\n .filter((e) => e.isDirectory() && specPattern.test(e.name))\n .map((e) => {\n const match = e.name.match(specPattern);\n return match ? parseInt(match[1], 10) : NaN;\n })\n .filter((n) => !isNaN(n));\n\n if (seqNumbers.length === 0) {\n return '1'.padStart(digits, '0');\n }\n\n const maxSeq = Math.max(...seqNumbers);\n return String(maxSeq + 1).padStart(digits, '0');\n } catch {\n return '1'.padStart(digits, '0');\n }\n}\n\n/**\n * Resolve spec path in multiple ways:\n * 1. Absolute path as given\n * 2. Relative to current directory\n * 3. Relative to specs directory\n * 4. Search by spec name in all subdirectories (flat or grouped)\n * 5. Search by sequence number only\n */\nexport async function resolveSpecPath(\n specPath: string,\n cwd: string,\n specsDir: string\n): Promise<string | null> {\n // Try absolute path\n if (path.isAbsolute(specPath)) {\n try {\n await fs.access(specPath);\n return specPath;\n } catch {\n return null;\n }\n }\n\n // Try relative to cwd\n const cwdPath = path.resolve(cwd, specPath);\n try {\n await fs.access(cwdPath);\n return cwdPath;\n } catch {\n // Continue to next method\n }\n\n // Try relative to specs directory\n const specsPath = path.join(specsDir, specPath);\n try {\n await fs.access(specsPath);\n return specsPath;\n } catch {\n // Continue to next method\n }\n\n // Search by sequence number only (e.g., \"5\" or \"005\")\n const seqMatch = specPath.match(/^0*(\\d+)$/);\n if (seqMatch) {\n const seqNum = parseInt(seqMatch[1], 10);\n const result = await searchBySequence(specsDir, seqNum);\n if (result) return result;\n }\n\n // Last resort: search for spec name in all subdirectories\n const specName = specPath.replace(/^.*\\//, ''); // Get last part\n const result = await searchInAllDirectories(specsDir, specName);\n return result;\n}\n\n/**\n * Search for a spec by sequence number across all directories\n */\nasync function searchBySequence(specsDir: string, seqNum: number): Promise<string | null> {\n const specPattern = createSpecDirPattern();\n \n async function scanDirectory(dir: string): Promise<string | null> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n \n // Check if this matches the sequence number\n const match = entry.name.match(specPattern);\n if (match) {\n const entrySeq = parseInt(match[1], 10);\n if (entrySeq === seqNum) {\n return path.join(dir, entry.name);\n }\n }\n \n // Recursively search subdirectories (including archived)\n const subDir = path.join(dir, entry.name);\n const result = await scanDirectory(subDir);\n if (result) return result;\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n \n return null;\n }\n \n return scanDirectory(specsDir);\n}\n\n/**\n * Search for a spec by name in all subdirectories\n */\nasync function searchInAllDirectories(specsDir: string, specName: string): Promise<string | null> {\n async function scanDirectory(dir: string): Promise<string | null> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n \n // Check if this matches the spec name\n if (entry.name === specName) {\n return path.join(dir, entry.name);\n }\n \n // Recursively search subdirectories (including archived)\n const subDir = path.join(dir, entry.name);\n const result = await scanDirectory(subDir);\n if (result) return result;\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n \n return null;\n }\n \n return scanDirectory(specsDir);\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport matter from 'gray-matter';\nimport { loadConfig } from '../config.js';\nimport type { SpecStatus, SpecFrontmatter } from '../frontmatter.js';\nimport { \n getFirstCommitTimestamp, \n fileExistsInGit,\n parseStatusTransitions,\n} from './git-timestamps.js';\n\n/**\n * Information about a spec file that may or may not have valid frontmatter\n */\nexport interface BootstrapSpecInfo {\n path: string; // Relative path to spec directory\n fullPath: string; // Absolute path to spec directory\n filePath: string; // Absolute path to spec file (README.md)\n name: string; // Spec directory name\n content: string; // File content\n hasFrontmatter: boolean; // Does file have YAML frontmatter?\n hasValidFrontmatter: boolean; // Does frontmatter have required fields?\n existingFrontmatter?: Partial<SpecFrontmatter>; // Existing frontmatter data\n inferredStatus?: SpecStatus; // Status inferred from content/git\n inferredCreated?: string; // Created date inferred from content/git\n}\n\n/**\n * Load all spec directories, including those without valid frontmatter\n */\nexport async function loadSpecsForBootstrap(\n specsDir: string,\n options: {\n includeArchived?: boolean;\n targetSpecs?: string[];\n } = {}\n): Promise<BootstrapSpecInfo[]> {\n const specs: BootstrapSpecInfo[] = [];\n const config = await loadConfig();\n \n // Pattern to match spec directories (2 or more digits followed by dash)\n const specPattern = /^(\\d{2,})-/;\n \n async function scanDirectory(dir: string, relativePath: string = ''): Promise<void> {\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n \n // Skip archived directory in main scan (handle separately)\n if (entry.name === 'archived' && relativePath === '') continue;\n \n const entryPath = path.join(dir, entry.name);\n const entryRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;\n \n // Check if this is a spec directory (NNN-name format)\n if (specPattern.test(entry.name)) {\n // Filter by target specs if specified\n if (options.targetSpecs && options.targetSpecs.length > 0) {\n const matches = options.targetSpecs.some(target => {\n // Match by name, number, or path\n const targetNum = target.match(/^0*(\\d+)$/)?.[1];\n const entryNum = entry.name.match(/^(\\d+)/)?.[1];\n return entry.name === target || \n entry.name.includes(target) || \n (targetNum && entryNum && parseInt(targetNum, 10) === parseInt(entryNum, 10));\n });\n if (!matches) continue;\n }\n \n const specFile = path.join(entryPath, config.structure.defaultFile);\n \n try {\n await fs.access(specFile);\n const specInfo = await analyzeSpecFile(specFile, entryPath, entryRelativePath, entry.name);\n specs.push(specInfo);\n } catch {\n // No spec file found, skip\n }\n } else {\n // Not a spec directory, scan recursively\n await scanDirectory(entryPath, entryRelativePath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n }\n \n await scanDirectory(specsDir);\n \n // Load archived specs if requested\n if (options.includeArchived) {\n const archivedPath = path.join(specsDir, 'archived');\n await scanDirectory(archivedPath, 'archived');\n }\n \n // Sort by spec number descending\n specs.sort((a, b) => {\n const aNum = parseInt(a.name.match(/^(\\d+)/)?.[1] || '0', 10);\n const bNum = parseInt(b.name.match(/^(\\d+)/)?.[1] || '0', 10);\n return bNum - aNum;\n });\n \n return specs;\n}\n\n/**\n * Analyze a spec file and extract/infer frontmatter data\n */\nasync function analyzeSpecFile(\n filePath: string,\n fullPath: string,\n relativePath: string,\n name: string\n): Promise<BootstrapSpecInfo> {\n const content = await fs.readFile(filePath, 'utf-8');\n \n // Try to parse existing frontmatter\n let hasFrontmatter = false;\n let hasValidFrontmatter = false;\n let existingFrontmatter: Partial<SpecFrontmatter> | undefined;\n \n try {\n const parsed = matter(content);\n if (parsed.data && Object.keys(parsed.data).length > 0) {\n hasFrontmatter = true;\n existingFrontmatter = parsed.data as Partial<SpecFrontmatter>;\n \n // Check if required fields exist\n hasValidFrontmatter = !!(parsed.data.status && parsed.data.created);\n }\n } catch {\n // Failed to parse frontmatter\n }\n \n // Infer status from content or git\n const inferredStatus = inferStatusFromContent(content) || \n inferStatusFromGit(filePath) || \n 'planned';\n \n // Infer created date from content or git\n const inferredCreated = inferCreatedFromContent(content) || \n inferCreatedFromGit(filePath) ||\n new Date().toISOString().split('T')[0];\n \n return {\n path: relativePath,\n fullPath,\n filePath,\n name,\n content,\n hasFrontmatter,\n hasValidFrontmatter,\n existingFrontmatter,\n inferredStatus: existingFrontmatter?.status || inferredStatus,\n inferredCreated: existingFrontmatter?.created || inferredCreated,\n };\n}\n\n/**\n * Infer status from markdown content using common patterns\n */\nexport function inferStatusFromContent(content: string): SpecStatus | null {\n // Pattern 1: **Status**: Complete (inline metadata)\n const inlineMatch = content.match(/\\*\\*Status\\*\\*:\\s*(?:✅\\s*|📅\\s*|⏳\\s*|📦\\s*)?(\\w+(?:-\\w+)?)/i);\n if (inlineMatch) {\n return normalizeStatus(inlineMatch[1]);\n }\n \n // Pattern 2: Status: Complete (simple format)\n const simpleMatch = content.match(/^Status:\\s*(\\w+(?:-\\w+)?)/mi);\n if (simpleMatch) {\n return normalizeStatus(simpleMatch[1]);\n }\n \n // Pattern 3: [x] Done / [ ] In Progress (task list format)\n if (/^\\s*-\\s*\\[x\\]\\s*(done|complete|finished)/mi.test(content)) {\n return 'complete';\n }\n \n // Pattern 4: ADR format - \"Status: Accepted\"\n const adrMatch = content.match(/^##?\\s*Status\\s*\\n+\\s*(\\w+)/mi);\n if (adrMatch) {\n const adrStatus = adrMatch[1].toLowerCase();\n if (['accepted', 'approved', 'done'].includes(adrStatus)) {\n return 'complete';\n }\n if (['proposed', 'pending', 'draft'].includes(adrStatus)) {\n return 'planned';\n }\n if (['superseded', 'deprecated', 'rejected'].includes(adrStatus)) {\n return 'archived';\n }\n }\n \n return null;\n}\n\n/**\n * Infer status from git history (check if ever marked complete)\n */\nexport function inferStatusFromGit(filePath: string): SpecStatus | null {\n if (!fileExistsInGit(filePath)) {\n return null;\n }\n \n try {\n const transitions = parseStatusTransitions(filePath);\n if (transitions.length > 0) {\n // Return the last known status from git history\n return transitions[transitions.length - 1].status;\n }\n } catch {\n // Git parsing failed\n }\n \n return null;\n}\n\n/**\n * Normalize various status strings to valid SpecStatus\n */\nfunction normalizeStatus(status: string): SpecStatus {\n const normalized = status.toLowerCase().trim().replace(/\\s+/g, '-');\n \n const statusMap: Record<string, SpecStatus> = {\n // Standard statuses\n 'planned': 'planned',\n 'in-progress': 'in-progress',\n 'inprogress': 'in-progress',\n 'in_progress': 'in-progress',\n 'wip': 'in-progress',\n 'working': 'in-progress',\n 'active': 'in-progress',\n 'complete': 'complete',\n 'completed': 'complete',\n 'done': 'complete',\n 'finished': 'complete',\n 'implemented': 'complete',\n 'archived': 'archived',\n 'deprecated': 'archived',\n 'superseded': 'archived',\n 'rejected': 'archived',\n // ADR statuses\n 'accepted': 'complete',\n 'approved': 'complete',\n 'proposed': 'planned',\n 'pending': 'planned',\n 'draft': 'planned',\n };\n \n return statusMap[normalized] || 'planned';\n}\n\n/**\n * Infer created date from markdown content\n */\nexport function inferCreatedFromContent(content: string): string | null {\n // Pattern 1: **Created**: 2025-01-15 (inline metadata)\n const inlineMatch = content.match(/\\*\\*Created\\*\\*:\\s*(\\d{4}-\\d{2}-\\d{2})/);\n if (inlineMatch) {\n return inlineMatch[1];\n }\n \n // Pattern 2: Created: 2025-01-15 (simple format)\n const simpleMatch = content.match(/^Created:\\s*(\\d{4}-\\d{2}-\\d{2})/mi);\n if (simpleMatch) {\n return simpleMatch[1];\n }\n \n // Pattern 3: Date: 2025-01-15\n const dateMatch = content.match(/^Date:\\s*(\\d{4}-\\d{2}-\\d{2})/mi);\n if (dateMatch) {\n return dateMatch[1];\n }\n \n // Pattern 4: ADR format - \"Date: January 15, 2025\"\n const adrMatch = content.match(/^##?\\s*Date\\s*\\n+\\s*(\\w+\\s+\\d{1,2},?\\s+\\d{4})/mi);\n if (adrMatch) {\n try {\n const date = new Date(adrMatch[1]);\n if (!isNaN(date.getTime())) {\n return date.toISOString().split('T')[0];\n }\n } catch {\n // Failed to parse date\n }\n }\n \n // Pattern 5: Look for dates in common formats anywhere\n const anyDateMatch = content.match(/(\\d{4}-\\d{2}-\\d{2})/);\n if (anyDateMatch) {\n return anyDateMatch[1];\n }\n \n return null;\n}\n\n/**\n * Infer created date from git history (first commit date)\n */\nexport function inferCreatedFromGit(filePath: string): string | null {\n const timestamp = getFirstCommitTimestamp(filePath);\n if (timestamp) {\n // Extract date part from ISO timestamp\n return timestamp.split('T')[0];\n }\n return null;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { Command } from 'commander';\nimport { loadAllSpecs, getSpec, type SpecInfo } from '../spec-loader.js';\nimport { updateFrontmatter, type SpecFrontmatter, type SpecStatus } from '../frontmatter.js';\nimport { loadConfig } from '../config.js';\nimport { \n isGitRepository,\n extractGitTimestamps,\n fileExistsInGit,\n getFirstCommitTimestamp,\n type GitTimestampData,\n} from '../utils/git-timestamps.js';\nimport { resolveSpecPath } from '../utils/path-helpers.js';\nimport { \n loadSpecsForBootstrap, \n type BootstrapSpecInfo,\n inferStatusFromContent,\n inferCreatedFromContent,\n} from '../utils/bootstrap-helpers.js';\n\nexport interface BackfillResult {\n specPath: string;\n specName: string;\n created_at?: string;\n updated_at?: string;\n completed_at?: string;\n assignee?: string;\n transitionsCount?: number;\n source: 'git' | 'existing' | 'skipped' | 'bootstrapped';\n reason?: string;\n bootstrapped?: boolean; // Was frontmatter created from scratch?\n}\n\nexport interface BackfillOptions {\n dryRun?: boolean;\n force?: boolean;\n includeAssignee?: boolean;\n includeTransitions?: boolean;\n specs?: string[]; // specific specs to target\n json?: boolean;\n bootstrap?: boolean; // Create frontmatter for files without it\n}\n\n/**\n * Backfill command - backfill timestamps from git history\n */\nexport function backfillCommand(): Command {\n return new Command('backfill')\n .description('Backfill timestamps from git history')\n .argument('[specs...]', 'Specific specs to backfill (optional)')\n .option('--dry-run', 'Show what would be updated without making changes')\n .option('--force', 'Overwrite existing timestamp values')\n .option('--assignee', 'Include assignee from first commit author')\n .option('--transitions', 'Include full status transition history')\n .option('--all', 'Include all optional fields (assignee + transitions)')\n .option('--bootstrap', 'Create frontmatter for files without valid frontmatter')\n .option('--json', 'Output as JSON')\n .action(async (specs: string[] | undefined, options: {\n dryRun?: boolean;\n force?: boolean;\n assignee?: boolean;\n transitions?: boolean;\n all?: boolean;\n json?: boolean;\n bootstrap?: boolean;\n }) => {\n await backfillTimestamps({\n dryRun: options.dryRun,\n force: options.force,\n includeAssignee: options.assignee || options.all,\n includeTransitions: options.transitions || options.all,\n specs: specs && specs.length > 0 ? specs : undefined,\n json: options.json,\n bootstrap: options.bootstrap,\n });\n });\n}\n\n/**\n * Backfill timestamps from git history for all or specific specs\n */\nexport async function backfillTimestamps(options: BackfillOptions = {}): Promise<BackfillResult[]> {\n const results: BackfillResult[] = [];\n \n // Check if we're in a git repository\n if (!isGitRepository()) {\n console.error('\\x1b[31mError:\\x1b[0m Not in a git repository');\n console.error('Git history is required for backfilling timestamps');\n process.exit(1);\n }\n \n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n \n // Bootstrap mode: also load specs without valid frontmatter\n if (options.bootstrap) {\n console.log('\\x1b[36m🔧 Bootstrap mode - will create frontmatter for files without it\\x1b[0m\\n');\n \n const bootstrapSpecs = await loadSpecsForBootstrap(specsDir, {\n includeArchived: true,\n targetSpecs: options.specs,\n });\n \n if (bootstrapSpecs.length === 0) {\n console.log('No specs found to bootstrap');\n return results;\n }\n \n console.log(`Analyzing git history for ${bootstrapSpecs.length} spec${bootstrapSpecs.length === 1 ? '' : 's'}...\\n`);\n \n for (const spec of bootstrapSpecs) {\n const result = await bootstrapSpec(spec, options);\n results.push(result);\n }\n \n printSummary(results, options);\n return results;\n }\n \n // Normal mode: load specs with valid frontmatter only\n let specs: SpecInfo[];\n \n if (options.specs && options.specs.length > 0) {\n // Load specific specs\n specs = [];\n \n for (const specPath of options.specs) {\n const resolved = await resolveSpecPath(specPath, cwd, specsDir);\n if (!resolved) {\n console.warn(`\\x1b[33mWarning:\\x1b[0m Spec not found: ${specPath}`);\n continue;\n }\n const spec = await getSpec(resolved);\n if (spec) {\n specs.push(spec);\n }\n }\n } else {\n // Load all specs (including archived)\n specs = await loadAllSpecs({ includeArchived: true });\n }\n \n if (specs.length === 0) {\n console.log('No specs found to backfill');\n console.log('\\x1b[36mℹ\\x1b[0m Use --bootstrap to create frontmatter for files without it');\n return results;\n }\n \n // Show what we're doing\n if (options.dryRun) {\n console.log('\\x1b[36m🔍 Dry run mode - no changes will be made\\x1b[0m\\n');\n }\n \n console.log(`Analyzing git history for ${specs.length} spec${specs.length === 1 ? '' : 's'}...\\n`);\n \n // Process each spec\n for (const spec of specs) {\n const result = await backfillSpecTimestamps(spec, options);\n results.push(result);\n }\n \n // Print summary\n printSummary(results, options);\n \n return results;\n}\n\n/**\n * Backfill timestamps for a single spec\n */\nasync function backfillSpecTimestamps(\n spec: SpecInfo,\n options: BackfillOptions\n): Promise<BackfillResult> {\n const result: BackfillResult = {\n specPath: spec.path,\n specName: spec.name,\n source: 'skipped',\n };\n \n // Skip specs without valid frontmatter (missing required fields)\n if (!spec.frontmatter.status || !spec.frontmatter.created) {\n result.reason = 'Missing required frontmatter (status or created)';\n console.log(`\\x1b[33m⊘\\x1b[0m ${spec.name} - Missing required frontmatter`);\n return result;\n }\n \n // Check if file exists in git history\n if (!fileExistsInGit(spec.filePath)) {\n result.reason = 'Not in git history';\n console.log(`\\x1b[33m⊘\\x1b[0m ${spec.name} - Not in git history`);\n return result;\n }\n \n // Extract git timestamps\n const gitData = extractGitTimestamps(spec.filePath, {\n includeAssignee: options.includeAssignee,\n includeTransitions: options.includeTransitions,\n });\n \n // Determine what needs to be updated\n const updates: Partial<SpecFrontmatter> = {};\n let hasUpdates = false;\n \n // Check created_at\n if (gitData.created_at && (options.force || !spec.frontmatter.created_at)) {\n updates.created_at = gitData.created_at;\n result.created_at = gitData.created_at;\n result.source = 'git';\n hasUpdates = true;\n } else if (spec.frontmatter.created_at) {\n result.created_at = spec.frontmatter.created_at;\n result.source = 'existing';\n }\n \n // Check updated_at\n if (gitData.updated_at && (options.force || !spec.frontmatter.updated_at)) {\n updates.updated_at = gitData.updated_at;\n result.updated_at = gitData.updated_at;\n result.source = 'git';\n hasUpdates = true;\n } else if (spec.frontmatter.updated_at) {\n result.updated_at = spec.frontmatter.updated_at;\n result.source = 'existing';\n }\n \n // Check completed_at\n if (gitData.completed_at && (options.force || !spec.frontmatter.completed_at)) {\n updates.completed_at = gitData.completed_at;\n result.completed_at = gitData.completed_at;\n result.source = 'git';\n hasUpdates = true;\n } else if (spec.frontmatter.completed_at) {\n result.completed_at = spec.frontmatter.completed_at;\n result.source = 'existing';\n }\n \n // Check assignee (optional)\n if (options.includeAssignee && gitData.assignee && (options.force || !spec.frontmatter.assignee)) {\n updates.assignee = gitData.assignee;\n result.assignee = gitData.assignee;\n result.source = 'git';\n hasUpdates = true;\n } else if (spec.frontmatter.assignee) {\n result.assignee = spec.frontmatter.assignee;\n }\n \n // Check transitions (optional)\n if (options.includeTransitions && gitData.transitions && gitData.transitions.length > 0) {\n if (options.force || !spec.frontmatter.transitions || spec.frontmatter.transitions.length === 0) {\n updates.transitions = gitData.transitions;\n result.transitionsCount = gitData.transitions.length;\n result.source = 'git';\n hasUpdates = true;\n } else {\n // Merge with existing transitions (optional: could implement smart merge)\n result.transitionsCount = spec.frontmatter.transitions.length;\n }\n }\n \n // Sync updated date field with updated_at timestamp\n if (updates.updated_at && !updates.updated) {\n updates.updated = updates.updated_at.split('T')[0];\n }\n \n if (!hasUpdates) {\n result.reason = 'Already has complete data';\n console.log(`\\x1b[90m✓\\x1b[0m ${spec.name} - Already complete`);\n return result;\n }\n \n // Apply updates (unless dry run)\n if (!options.dryRun) {\n try {\n await updateFrontmatter(spec.filePath, updates);\n console.log(`\\x1b[32m✓\\x1b[0m ${spec.name} - Updated`);\n } catch (error) {\n result.source = 'skipped';\n result.reason = `Error: ${error instanceof Error ? error.message : String(error)}`;\n console.log(`\\x1b[31m✗\\x1b[0m ${spec.name} - Failed: ${result.reason}`);\n }\n } else {\n console.log(`\\x1b[36m→\\x1b[0m ${spec.name} - Would update`);\n // Show what would be updated\n if (updates.created_at) console.log(` created_at: ${updates.created_at} (git)`);\n if (updates.updated_at) console.log(` updated_at: ${updates.updated_at} (git)`);\n if (updates.completed_at) console.log(` completed_at: ${updates.completed_at} (git)`);\n if (updates.assignee) console.log(` assignee: ${updates.assignee} (git)`);\n if (updates.transitions) console.log(` transitions: ${updates.transitions.length} status changes (git)`);\n }\n \n return result;\n}\n\n/**\n * Bootstrap a spec file with missing or incomplete frontmatter\n */\nasync function bootstrapSpec(\n spec: BootstrapSpecInfo,\n options: BackfillOptions\n): Promise<BackfillResult> {\n const result: BackfillResult = {\n specPath: spec.path,\n specName: spec.name,\n source: 'skipped',\n bootstrapped: false,\n };\n \n // Skip specs that already have valid frontmatter (unless --force)\n if (spec.hasValidFrontmatter && !options.force) {\n // Still run normal backfill logic for timestamps\n result.reason = 'Already has valid frontmatter';\n console.log(`\\x1b[90m✓\\x1b[0m ${spec.name} - Already valid`);\n return result;\n }\n \n // Build frontmatter from existing + inferred data\n const frontmatter: Partial<SpecFrontmatter> = {\n ...(spec.existingFrontmatter || {}),\n status: spec.inferredStatus || 'planned',\n created: spec.inferredCreated || new Date().toISOString().split('T')[0],\n };\n \n // Get git timestamps\n if (fileExistsInGit(spec.filePath)) {\n const gitData = extractGitTimestamps(spec.filePath, {\n includeAssignee: options.includeAssignee,\n includeTransitions: options.includeTransitions,\n });\n \n if (gitData.created_at) {\n frontmatter.created_at = gitData.created_at;\n result.created_at = gitData.created_at;\n }\n if (gitData.updated_at) {\n frontmatter.updated_at = gitData.updated_at;\n result.updated_at = gitData.updated_at;\n }\n if (gitData.completed_at) {\n frontmatter.completed_at = gitData.completed_at;\n result.completed_at = gitData.completed_at;\n }\n if (options.includeAssignee && gitData.assignee) {\n frontmatter.assignee = gitData.assignee;\n result.assignee = gitData.assignee;\n }\n if (options.includeTransitions && gitData.transitions && gitData.transitions.length > 0) {\n frontmatter.transitions = gitData.transitions;\n result.transitionsCount = gitData.transitions.length;\n }\n }\n \n // Determine source labels for output\n const statusSource = spec.existingFrontmatter?.status ? 'existing' : \n (spec.content.match(/\\*\\*Status\\*\\*/i) ? 'content' : 'default');\n const createdSource = spec.existingFrontmatter?.created ? 'existing' :\n (spec.content.match(/\\*\\*Created\\*\\*/i) ? 'content' : \n (fileExistsInGit(spec.filePath) ? 'git' : 'default'));\n \n if (!options.dryRun) {\n try {\n await writeBootstrapFrontmatter(spec.filePath, spec.content, frontmatter);\n result.source = 'bootstrapped';\n result.bootstrapped = true;\n console.log(`\\x1b[32m✓\\x1b[0m ${spec.name} - Bootstrapped`);\n console.log(` status: ${frontmatter.status} (${statusSource})`);\n console.log(` created: ${frontmatter.created} (${createdSource})`);\n } catch (error) {\n result.source = 'skipped';\n result.reason = `Error: ${error instanceof Error ? error.message : String(error)}`;\n console.log(`\\x1b[31m✗\\x1b[0m ${spec.name} - Failed: ${result.reason}`);\n }\n } else {\n result.source = 'bootstrapped';\n result.bootstrapped = true;\n console.log(`\\x1b[36m→\\x1b[0m ${spec.name} - Would bootstrap`);\n console.log(` status: ${frontmatter.status} (${statusSource})`);\n console.log(` created: ${frontmatter.created} (${createdSource})`);\n if (frontmatter.created_at) console.log(` created_at: ${frontmatter.created_at} (git)`);\n if (frontmatter.updated_at) console.log(` updated_at: ${frontmatter.updated_at} (git)`);\n if (frontmatter.completed_at) console.log(` completed_at: ${frontmatter.completed_at} (git)`);\n if (frontmatter.assignee) console.log(` assignee: ${frontmatter.assignee} (git)`);\n if (frontmatter.transitions) console.log(` transitions: ${frontmatter.transitions.length} (git)`);\n }\n \n return result;\n}\n\n/**\n * Write or update frontmatter in a spec file\n */\nasync function writeBootstrapFrontmatter(\n filePath: string,\n originalContent: string,\n frontmatter: Partial<SpecFrontmatter>\n): Promise<void> {\n const matter = await import('gray-matter');\n \n // Parse existing content (may or may not have frontmatter)\n const parsed = matter.default(originalContent);\n \n // Merge new frontmatter with any existing\n const newData = { ...parsed.data, ...frontmatter };\n \n // Write back\n const newContent = matter.default.stringify(parsed.content, newData);\n await fs.writeFile(filePath, newContent, 'utf-8');\n}\n\n/**\n * Print summary of backfill results\n */\nfunction printSummary(results: BackfillResult[], options: BackfillOptions): void {\n console.log('\\n' + '─'.repeat(60));\n console.log('\\x1b[1mSummary:\\x1b[0m\\n');\n \n const total = results.length;\n const updated = results.filter(r => r.source === 'git').length;\n const bootstrapped = results.filter(r => r.source === 'bootstrapped').length;\n const existing = results.filter(r => r.source === 'existing').length;\n const skipped = results.filter(r => r.source === 'skipped').length;\n \n const timestampUpdates = results.filter(r => \n (r.source === 'git' || r.source === 'bootstrapped') && (r.created_at || r.updated_at || r.completed_at)\n ).length;\n \n const assigneeUpdates = results.filter(r => \n (r.source === 'git' || r.source === 'bootstrapped') && r.assignee\n ).length;\n \n const transitionUpdates = results.filter(r => \n (r.source === 'git' || r.source === 'bootstrapped') && r.transitionsCount\n ).length;\n \n console.log(` ${total} specs analyzed`);\n \n if (options.dryRun) {\n if (options.bootstrap) {\n console.log(` ${bootstrapped} would be bootstrapped`);\n }\n console.log(` ${updated} would be updated`);\n if (timestampUpdates > 0) {\n console.log(` └─ ${timestampUpdates} with timestamps`);\n }\n if (options.includeAssignee && assigneeUpdates > 0) {\n console.log(` └─ ${assigneeUpdates} with assignee`);\n }\n if (options.includeTransitions && transitionUpdates > 0) {\n console.log(` └─ ${transitionUpdates} with transitions`);\n }\n } else {\n if (options.bootstrap) {\n console.log(` ${bootstrapped} bootstrapped`);\n }\n console.log(` ${updated} updated`);\n }\n \n console.log(` ${existing} already complete`);\n console.log(` ${skipped} skipped`);\n \n // Show reasons for skipped specs\n const skipReasons = results\n .filter(r => r.source === 'skipped' && r.reason)\n .map(r => r.reason);\n \n if (skipReasons.length > 0) {\n console.log('\\n\\x1b[33mSkipped reasons:\\x1b[0m');\n const uniqueReasons = [...new Set(skipReasons)];\n for (const reason of uniqueReasons) {\n const count = skipReasons.filter(r => r === reason).length;\n console.log(` - ${reason} (${count})`);\n }\n }\n \n // Guidance\n if (options.dryRun) {\n console.log('\\n\\x1b[36mℹ\\x1b[0m Run without --dry-run to apply changes');\n \n if (!options.includeAssignee || !options.includeTransitions) {\n console.log('\\x1b[36mℹ\\x1b[0m Use --all to include optional fields (assignee, transitions)');\n }\n \n if (!options.bootstrap && skipped > 0) {\n console.log('\\x1b[36mℹ\\x1b[0m Use --bootstrap to create frontmatter for files without it');\n }\n } else if (updated > 0 || bootstrapped > 0) {\n console.log('\\n\\x1b[32m✓\\x1b[0m Backfill complete!');\n console.log(' Run \\x1b[36mlean-spec stats\\x1b[0m to see velocity metrics');\n }\n}\n"]}