lean-spec 0.1.0 → 0.1.1

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.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/create.ts","../src/config.ts","../src/utils/path-helpers.ts","../src/commands/archive.ts","../src/commands/list.ts","../src/utils/ui.ts","../src/spec-loader.ts","../src/frontmatter.ts","../src/utils/spec-helpers.ts","../src/commands/update.ts","../src/commands/templates.ts","../src/commands/init.ts","../src/utils/template-helpers.ts","../src/commands/files.ts","../src/commands/board.ts","../src/components/Board.tsx","../src/commands/stats.ts","../src/components/StatsDisplay.tsx","../src/commands/search.ts","../src/commands/deps.ts","../src/commands/timeline.ts","../src/commands/gantt.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n createSpec,\n archiveSpec,\n listSpecs,\n updateSpec,\n listTemplates,\n showTemplate,\n addTemplate,\n removeTemplate,\n copyTemplate,\n initProject,\n statsCommand,\n boardCommand,\n timelineCommand,\n depsCommand,\n searchCommand,\n ganttCommand,\n filesCommand,\n} from './commands/index.js';\nimport type { SpecStatus, SpecPriority } from './frontmatter.js';\n\nconst program = new Command();\n\nprogram\n .name('lspec')\n .description('Manage LeanSpec documents')\n .version('0.1.0');\n\n// init command\nprogram\n .command('init')\n .description('Initialize LeanSpec in current directory')\n .action(async () => {\n await initProject();\n });\n\n// create command\nprogram\n .command('create <name>')\n .description('Create new spec in folder structure')\n .option('--title <title>', 'Set custom title')\n .option('--description <desc>', 'Set initial description')\n .option('--tags <tags>', 'Set tags (comma-separated)')\n .option('--priority <priority>', 'Set priority (low, medium, high, critical)')\n .option('--assignee <name>', 'Set assignee')\n .option('--template <template>', 'Use a specific template')\n .action(async (name: string, options: {\n title?: string;\n description?: string;\n tags?: string;\n priority?: SpecPriority;\n assignee?: string;\n template?: string;\n }) => {\n const createOptions: {\n title?: string;\n description?: string;\n tags?: string[];\n priority?: SpecPriority;\n assignee?: string;\n template?: string;\n } = {\n title: options.title,\n description: options.description,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n priority: options.priority,\n assignee: options.assignee,\n template: options.template,\n };\n await createSpec(name, createOptions);\n });\n\n// archive command\nprogram\n .command('archive <spec-path>')\n .description('Move spec to archived/')\n .action(async (specPath: string) => {\n await archiveSpec(specPath);\n });\n\n// list command\nprogram\n .command('list')\n .description('List all specs')\n .option('--archived', 'Include archived specs')\n .option('--status <status>', 'Filter by status (planned, in-progress, complete, archived)')\n .option('--tag <tag...>', 'Filter by tag (can specify multiple)')\n .option('--priority <priority>', 'Filter by priority (low, medium, high, critical)')\n .option('--assignee <name>', 'Filter by assignee')\n .action(async (options: {\n archived?: boolean;\n status?: SpecStatus;\n tag?: string[];\n priority?: SpecPriority;\n assignee?: string;\n }) => {\n const listOptions: {\n showArchived?: boolean;\n status?: SpecStatus;\n tags?: string[];\n priority?: SpecPriority;\n assignee?: string;\n } = {\n showArchived: options.archived,\n status: options.status,\n tags: options.tag,\n priority: options.priority,\n assignee: options.assignee,\n };\n await listSpecs(listOptions);\n });\n\n// update command\nprogram\n .command('update <spec-path>')\n .description('Update spec metadata')\n .option('--status <status>', 'Set status (planned, in-progress, complete, archived)')\n .option('--priority <priority>', 'Set priority (low, medium, high, critical)')\n .option('--tags <tags>', 'Set tags (comma-separated)')\n .option('--assignee <name>', 'Set assignee')\n .action(async (specPath: string, options: {\n status?: SpecStatus;\n priority?: SpecPriority;\n tags?: string;\n assignee?: string;\n }) => {\n const updates: {\n status?: SpecStatus;\n priority?: SpecPriority;\n tags?: string[];\n assignee?: string;\n } = {\n status: options.status,\n priority: options.priority,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n assignee: options.assignee,\n };\n \n // Filter out undefined values\n Object.keys(updates).forEach(key => {\n if (updates[key as keyof typeof updates] === undefined) {\n delete updates[key as keyof typeof updates];\n }\n });\n \n if (Object.keys(updates).length === 0) {\n console.error('Error: At least one update option required (--status, --priority, --tags, --assignee)');\n process.exit(1);\n }\n \n await updateSpec(specPath, updates);\n });\n\n// templates command and subcommands\nconst templatesCmd = program\n .command('templates')\n .description('Manage spec templates');\n\ntemplatesCmd\n .command('list')\n .description('List available templates')\n .action(async () => {\n await listTemplates();\n });\n\ntemplatesCmd\n .command('show <name>')\n .description('Show template content')\n .action(async (name: string) => {\n await showTemplate(name);\n });\n\ntemplatesCmd\n .command('add <name> <file>')\n .description('Register a template')\n .action(async (name: string, file: string) => {\n await addTemplate(name, file);\n });\n\ntemplatesCmd\n .command('remove <name>')\n .description('Unregister a template')\n .action(async (name: string) => {\n await removeTemplate(name);\n });\n\ntemplatesCmd\n .command('copy <source> <target>')\n .description('Copy a template to create a new one')\n .action(async (source: string, target: string) => {\n await copyTemplate(source, target);\n });\n\n// Default action for templates (list)\ntemplatesCmd\n .action(async () => {\n await listTemplates();\n });\n\n// stats command\nprogram\n .command('stats')\n .description('Show aggregate statistics')\n .option('--tag <tag>', 'Filter by tag')\n .option('--assignee <name>', 'Filter by assignee')\n .option('--json', 'Output as JSON')\n .action(async (options: {\n tag?: string;\n assignee?: string;\n json?: boolean;\n }) => {\n await statsCommand(options);\n });\n\n// board command\nprogram\n .command('board')\n .description('Show Kanban-style board view')\n .option('--show-complete', 'Expand complete column')\n .option('--tag <tag>', 'Filter by tag')\n .option('--assignee <name>', 'Filter by assignee')\n .action(async (options: {\n showComplete?: boolean;\n tag?: string;\n assignee?: string;\n }) => {\n await boardCommand(options);\n });\n\n// timeline command\nprogram\n .command('timeline')\n .description('Show creation/completion over time')\n .option('--days <n>', 'Show last N days (default: 30)', parseInt)\n .option('--by-tag', 'Group by tag')\n .option('--by-assignee', 'Group by assignee')\n .action(async (options: {\n days?: number;\n byTag?: boolean;\n byAssignee?: boolean;\n }) => {\n await timelineCommand(options);\n });\n\n// deps command\nprogram\n .command('deps <spec-path>')\n .description('Show dependency graph for a spec')\n .option('--depth <n>', 'Show N levels deep (default: 3)', parseInt)\n .option('--graph', 'ASCII graph visualization')\n .option('--json', 'Output as JSON')\n .action(async (specPath: string, options: {\n depth?: number;\n graph?: boolean;\n json?: boolean;\n }) => {\n await depsCommand(specPath, options);\n });\n\n// search command\nprogram\n .command('search <query>')\n .description('Full-text search with metadata filters')\n .option('--status <status>', 'Filter by status')\n .option('--tag <tag>', 'Filter by tag')\n .option('--priority <priority>', 'Filter by priority')\n .option('--assignee <name>', 'Filter by assignee')\n .action(async (query: string, options: {\n status?: SpecStatus;\n tag?: string;\n priority?: SpecPriority;\n assignee?: string;\n }) => {\n await searchCommand(query, options);\n });\n\n// files command\nprogram\n .command('files <spec-path>')\n .description('List files in a spec')\n .option('--type <type>', 'Filter by type: docs, assets')\n .option('--tree', 'Show tree structure')\n .action(async (specPath: string, options: {\n type?: 'docs' | 'assets';\n tree?: boolean;\n }) => {\n await filesCommand(specPath, options);\n });\n\n// gantt command\nprogram\n .command('gantt')\n .description('Show timeline with dependencies')\n .option('--weeks <n>', 'Show N weeks (default: 4)', parseInt)\n .option('--show-complete', 'Include completed specs')\n .option('--critical-path', 'Highlight critical path')\n .action(async (options: {\n weeks?: number;\n showComplete?: boolean;\n criticalPath?: boolean;\n }) => {\n await ganttCommand(options);\n });\n\n// Parse and execute\nprogram.parse();\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport chalk from 'chalk';\nimport { loadConfig, getToday } from '../config.js';\nimport { getNextSeq } from '../utils/path-helpers.js';\nimport type { SpecPriority } from '../frontmatter.js';\n\nexport async function createSpec(name: string, options: { \n title?: string; \n description?: string;\n tags?: string[];\n priority?: SpecPriority;\n assignee?: string;\n template?: string;\n} = {}): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n \n const today = getToday(config.structure.dateFormat);\n const specsDir = path.join(cwd, config.specsDir);\n const dateDir = path.join(specsDir, today);\n\n await fs.mkdir(dateDir, { recursive: true });\n\n const seq = await getNextSeq(dateDir, config.structure.sequenceDigits);\n const specDir = path.join(dateDir, `${seq}-${name}`);\n const specFile = path.join(specDir, config.structure.defaultFile);\n\n // Check if directory exists\n try {\n await fs.access(specDir);\n console.log(chalk.yellow(`Warning: Spec already exists: ${specDir}`));\n process.exit(1);\n } catch {\n // Directory doesn't exist, continue\n }\n\n // Create spec directory\n await fs.mkdir(specDir, { recursive: true });\n\n // Resolve template path from .lspec/templates/\n const templatesDir = path.join(cwd, '.lspec', 'templates');\n let templateName: string;\n \n // Determine which template to use\n if (options.template) {\n // User specified a template\n if (config.templates?.[options.template]) {\n templateName = config.templates[options.template];\n } else {\n console.error(chalk.red(`Template not found: ${options.template}`));\n console.error(chalk.gray(`Available templates: ${Object.keys(config.templates || {}).join(', ')}`));\n process.exit(1);\n }\n } else {\n // Use default template\n templateName = config.template || 'spec-template.md';\n }\n \n const templatePath = path.join(templatesDir, templateName);\n\n // Load spec template from .lspec/templates/\n let content: string;\n \n try {\n const template = await fs.readFile(templatePath, 'utf-8');\n const date = new Date().toISOString().split('T')[0];\n const title = options.title || name;\n \n content = template\n .replace(/{name}/g, title)\n .replace(/{date}/g, date);\n \n // Update frontmatter with provided metadata\n if (options.tags || options.priority || options.assignee) {\n // Parse existing frontmatter\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (frontmatterMatch) {\n let frontmatter = frontmatterMatch[1];\n \n // Add tags if provided\n if (options.tags && options.tags.length > 0) {\n // Replace empty tags array\n frontmatter = frontmatter.replace(/tags: \\[\\]/, `tags: [${options.tags.join(', ')}]`);\n }\n \n // Add priority if provided\n if (options.priority) {\n frontmatter = frontmatter.replace(/priority: medium/, `priority: ${options.priority}`);\n }\n \n // Add assignee if provided\n if (options.assignee) {\n // Add assignee field after priority\n frontmatter = frontmatter.replace(/(priority: \\w+)/, `$1\\nassignee: ${options.assignee}`);\n }\n \n content = content.replace(/^---\\n[\\s\\S]*?\\n---/, `---\\n${frontmatter}\\n---`);\n }\n }\n \n // Add description to Overview section if provided\n if (options.description) {\n content = content.replace(\n /## Overview\\s+<!-- What are we solving\\? Why now\\? -->/,\n `## Overview\\n\\n${options.description}`\n );\n }\n } catch (error) {\n console.error(chalk.red('Error: Template not found!'));\n console.error(chalk.gray(`Expected: ${templatePath}`));\n console.error(chalk.yellow('Run: lspec init'));\n process.exit(1);\n }\n\n await fs.writeFile(specFile, content, 'utf-8');\n\n console.log(chalk.green(`✓ Created: ${specDir}/`));\n console.log(chalk.gray(` Edit: ${specFile}`));\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\nexport interface LeanSpecConfig {\n template: string;\n templates?: Record<string, string>; // Maps template name to filename\n specsDir: string;\n structure: {\n pattern: string;\n dateFormat: string;\n sequenceDigits: number;\n defaultFile: string;\n };\n features?: {\n aiAgents?: boolean;\n examples?: boolean;\n collaboration?: boolean;\n compliance?: boolean;\n approvals?: boolean;\n apiDocs?: boolean;\n };\n}\n\nconst DEFAULT_CONFIG: LeanSpecConfig = {\n template: 'spec-template.md',\n templates: {\n default: 'spec-template.md',\n },\n specsDir: 'specs',\n structure: {\n pattern: '{date}/{seq}-{name}/',\n dateFormat: 'YYYYMMDD',\n sequenceDigits: 3,\n defaultFile: 'README.md',\n },\n features: {\n aiAgents: true,\n examples: true,\n },\n};\n\nexport async function loadConfig(cwd: string = process.cwd()): Promise<LeanSpecConfig> {\n const configPath = path.join(cwd, '.lspec', 'config.json');\n\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n const userConfig = JSON.parse(content);\n return { ...DEFAULT_CONFIG, ...userConfig };\n } catch {\n // No config file, use defaults\n return DEFAULT_CONFIG;\n }\n}\n\nexport async function saveConfig(\n config: LeanSpecConfig,\n cwd: string = process.cwd(),\n): Promise<void> {\n const configDir = path.join(cwd, '.lspec');\n const configPath = path.join(configDir, 'config.json');\n\n await fs.mkdir(configDir, { recursive: true });\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');\n}\n\nexport function getToday(format: string = 'YYYYMMDD'): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n\n switch (format) {\n case 'YYYYMMDD':\n return `${year}${month}${day}`;\n case 'YYYY-MM-DD':\n return `${year}-${month}-${day}`;\n case 'YYYY/MM':\n return `${year}/${month}`;\n default:\n return `${year}${month}${day}`;\n }\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Get next sequence number for a date directory\n */\nexport async function getNextSeq(dateDir: string, digits: number): Promise<string> {\n try {\n const entries = await fs.readdir(dateDir, { withFileTypes: true });\n const seqNumbers = entries\n .filter((e) => e.isDirectory() && /^\\d{2,3}-.+/.test(e.name))\n .map((e) => parseInt(e.name.split('-')[0], 10))\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 date directories\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 // Last resort: search for spec name in date directories\n const specName = specPath.replace(/^.*\\//, ''); // Get last part\n try {\n const entries = await fs.readdir(specsDir, { withFileTypes: true });\n const dateDirs = entries.filter(e => e.isDirectory() && e.name !== 'archived');\n\n for (const dateDir of dateDirs) {\n const testPath = path.join(specsDir, dateDir.name, specName);\n try {\n await fs.access(testPath);\n return testPath;\n } catch {\n // Keep searching\n }\n }\n } catch {\n // Specs dir doesn't exist\n }\n\n return null;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport chalk from 'chalk';\nimport { loadConfig } from '../config.js';\n\nexport async function archiveSpec(specPath: string): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n \n const resolvedPath = path.resolve(specPath);\n\n // Check if directory exists\n try {\n await fs.access(resolvedPath);\n } catch {\n console.error(chalk.red(`Error: Spec not found: ${specPath}`));\n process.exit(1);\n }\n\n // Get parent directory (date folder)\n const parentDir = path.dirname(resolvedPath);\n const dateFolder = path.basename(parentDir);\n const archiveDir = path.join(specsDir, 'archived', dateFolder);\n\n await fs.mkdir(archiveDir, { recursive: true });\n\n const specName = path.basename(resolvedPath);\n const archivePath = path.join(archiveDir, specName);\n\n await fs.rename(resolvedPath, archivePath);\n\n console.log(chalk.green(`✓ Archived: ${archivePath}`));\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport chalk from 'chalk';\nimport { loadConfig } from '../config.js';\nimport { withSpinner } from '../utils/ui.js';\nimport { loadAllSpecs } from '../spec-loader.js';\nimport { getStatusEmoji, getPriorityLabel } from '../utils/spec-helpers.js';\nimport type { SpecFilterOptions, SpecStatus, SpecPriority } from '../frontmatter.js';\n\nexport async function listSpecs(options: {\n showArchived?: boolean;\n status?: SpecStatus | SpecStatus[];\n tags?: string[];\n priority?: SpecPriority | SpecPriority[];\n assignee?: string;\n} = {}): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n \n try {\n await fs.access(specsDir);\n } catch {\n console.log('');\n console.log('No specs directory found. Initialize with: lspec init');\n console.log('');\n return;\n }\n\n // Build filter options\n const filter: SpecFilterOptions = {};\n if (options.status) filter.status = options.status;\n if (options.tags) filter.tags = options.tags;\n if (options.priority) filter.priority = options.priority;\n if (options.assignee) filter.assignee = options.assignee;\n\n const specs = await withSpinner(\n 'Loading specs...',\n () => loadAllSpecs({\n includeArchived: options.showArchived || false,\n filter,\n })\n );\n\n console.log('');\n console.log(chalk.green('=== Specs ==='));\n console.log('');\n\n if (specs.length === 0) {\n if (Object.keys(filter).length > 0) {\n console.log('No specs match the specified filters.');\n } else {\n console.log('No specs found. Create one with: lspec create <name>');\n }\n console.log('');\n return;\n }\n\n // Group specs by date directory\n const byDate = new Map<string, typeof specs>();\n for (const spec of specs) {\n const dateMatch = spec.path.match(/^(\\d{8})\\//);\n const dateKey = dateMatch ? dateMatch[1] : 'unknown';\n if (!byDate.has(dateKey)) {\n byDate.set(dateKey, []);\n }\n byDate.get(dateKey)!.push(spec);\n }\n\n // Display grouped by date (newest first)\n const sortedDates = Array.from(byDate.keys()).sort((a, b) => b.localeCompare(a));\n \n for (const date of sortedDates) {\n const dateSpecs = byDate.get(date)!;\n console.log(chalk.cyan(`${date}/`));\n \n for (const spec of dateSpecs) {\n const specName = spec.path.replace(/^\\d{8}\\//, '').replace(/\\/$/, '');\n let line = ` ${specName}/`;\n \n // Add metadata\n const meta: string[] = [];\n meta.push(getStatusEmoji(spec.frontmatter.status));\n if (spec.frontmatter.priority) {\n meta.push(getPriorityLabel(spec.frontmatter.priority));\n }\n if (spec.frontmatter.tags && spec.frontmatter.tags.length > 0) {\n meta.push(chalk.gray(`[${spec.frontmatter.tags.join(', ')}]`));\n }\n \n if (meta.length > 0) {\n line += ` ${meta.join(' ')}`;\n }\n \n console.log(line);\n }\n console.log('');\n }\n\n console.log('');\n}\n","import ora, { Ora } from 'ora';\nimport chalk from 'chalk';\n\n/**\n * Show a spinner while executing an async operation\n */\nexport async function withSpinner<T>(\n text: string,\n fn: () => Promise<T>,\n options?: {\n successText?: string;\n failText?: string;\n }\n): Promise<T> {\n const spinner = ora(text).start();\n \n try {\n const result = await fn();\n spinner.succeed(options?.successText || text);\n return result;\n } catch (error) {\n spinner.fail(options?.failText || `${text} failed`);\n throw error;\n }\n}\n\n/**\n * Create a spinner instance for manual control\n */\nexport function createSpinner(text: string): Ora {\n return ora(text);\n}\n\n/**\n * Display a success message\n */\nexport function success(message: string): void {\n console.log(chalk.green(`✓ ${message}`));\n}\n\n/**\n * Display an error message\n */\nexport function error(message: string): void {\n console.error(chalk.red(`✗ ${message}`));\n}\n\n/**\n * Display a warning message\n */\nexport function warning(message: string): void {\n console.log(chalk.yellow(`⚠ ${message}`));\n}\n\n/**\n * Display an info message\n */\nexport function info(message: string): void {\n console.log(chalk.blue(`ℹ ${message}`));\n}\n\n/**\n * Display a heading\n */\nexport function heading(text: string): void {\n console.log('');\n console.log(chalk.green.bold(text));\n console.log('');\n}\n\n/**\n * Display a subheading\n */\nexport function subheading(text: string): void {\n console.log(chalk.cyan.bold(text));\n}\n\n/**\n * Display a hint/tip\n */\nexport function hint(message: string): void {\n console.log(chalk.gray(`💡 Tip: ${message}`));\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { loadConfig } from './config.js';\nimport { parseFrontmatter, getSpecFile, matchesFilter, type SpecFrontmatter, type SpecFilterOptions } from './frontmatter.js';\n\nexport interface SpecInfo {\n path: string; // Relative path like \"20251101/003-pm-visualization-tools\"\n fullPath: string; // Absolute path to spec directory\n filePath: string; // Absolute path to spec file (README.md)\n name: string; // Just the spec name like \"003-pm-visualization-tools\"\n date: string; // Date folder like \"20251101\"\n frontmatter: SpecFrontmatter;\n content?: string; // Full file content (optional, for search)\n subFiles?: SubFileInfo[]; // Sub-documents and assets\n}\n\nexport interface SubFileInfo {\n name: string; // e.g., \"TESTING.md\" or \"diagram.png\"\n path: string; // Absolute path to the file\n size: number; // File size in bytes\n type: 'document' | 'asset'; // Classification based on file type\n content?: string; // Optional content for documents\n}\n\n// Load sub-files for a spec (all files except README.md)\nexport async function loadSubFiles(\n specDir: string,\n options: { includeContent?: boolean } = {}\n): Promise<SubFileInfo[]> {\n const subFiles: SubFileInfo[] = [];\n\n try {\n const entries = await fs.readdir(specDir, { withFileTypes: true });\n\n for (const entry of entries) {\n // Skip README.md (main spec file)\n if (entry.name === 'README.md') continue;\n\n // Skip directories for now (could be assets folder)\n if (entry.isDirectory()) continue;\n\n const filePath = path.join(specDir, entry.name);\n const stat = await fs.stat(filePath);\n\n // Determine type based on extension\n const ext = path.extname(entry.name).toLowerCase();\n const isDocument = ext === '.md';\n\n const subFile: SubFileInfo = {\n name: entry.name,\n path: filePath,\n size: stat.size,\n type: isDocument ? 'document' : 'asset',\n };\n\n // Load content for documents if requested\n if (isDocument && options.includeContent) {\n subFile.content = await fs.readFile(filePath, 'utf-8');\n }\n\n subFiles.push(subFile);\n }\n } catch (error) {\n // Directory doesn't exist or can't be read - return empty array\n // This is expected for specs without sub-files\n return [];\n }\n\n // Sort: documents first, then alphabetically\n return subFiles.sort((a, b) => {\n if (a.type !== b.type) {\n return a.type === 'document' ? -1 : 1;\n }\n return a.name.localeCompare(b.name);\n });\n}\n\n// Load all specs from the specs directory\nexport async function loadAllSpecs(options: {\n includeArchived?: boolean;\n includeContent?: boolean;\n includeSubFiles?: boolean;\n filter?: SpecFilterOptions;\n} = {}): Promise<SpecInfo[]> {\n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n\n const specs: SpecInfo[] = [];\n\n // Check if specs directory exists\n try {\n await fs.access(specsDir);\n } catch {\n return [];\n }\n\n // Load active specs\n const entries = await fs.readdir(specsDir, { withFileTypes: true });\n const dateDirs = entries\n .filter((e) => e.isDirectory() && e.name !== 'archived')\n .sort((a, b) => b.name.localeCompare(a.name)); // Reverse chronological\n\n for (const dir of dateDirs) {\n const dateDir = path.join(specsDir, dir.name);\n const specEntries = await fs.readdir(dateDir, { withFileTypes: true });\n const specDirs = specEntries.filter((s) => s.isDirectory());\n\n for (const spec of specDirs) {\n const specDir = path.join(dateDir, spec.name);\n const specFile = await getSpecFile(specDir, config.structure.defaultFile);\n\n if (!specFile) continue;\n\n const frontmatter = await parseFrontmatter(specFile);\n if (!frontmatter) continue;\n\n // Apply filter if provided\n if (options.filter && !matchesFilter(frontmatter, options.filter)) {\n continue;\n }\n\n const specInfo: SpecInfo = {\n path: `${dir.name}/${spec.name}`,\n fullPath: specDir,\n filePath: specFile,\n name: spec.name,\n date: dir.name,\n frontmatter,\n };\n\n // Load content if requested\n if (options.includeContent) {\n specInfo.content = await fs.readFile(specFile, 'utf-8');\n }\n\n // Load sub-files if requested\n if (options.includeSubFiles) {\n specInfo.subFiles = await loadSubFiles(specDir, {\n includeContent: options.includeContent,\n });\n }\n\n specs.push(specInfo);\n }\n }\n\n // Load archived specs if requested\n if (options.includeArchived) {\n const archivedPath = path.join(specsDir, 'archived');\n try {\n await fs.access(archivedPath);\n\n const archivedEntries = await fs.readdir(archivedPath, { withFileTypes: true });\n const archivedDirs = archivedEntries\n .filter((e) => e.isDirectory())\n .sort((a, b) => b.name.localeCompare(a.name));\n\n for (const dir of archivedDirs) {\n const dateDir = path.join(archivedPath, dir.name);\n const specEntries = await fs.readdir(dateDir, { withFileTypes: true });\n const specDirs = specEntries.filter((s) => s.isDirectory());\n\n for (const spec of specDirs) {\n const specDir = path.join(dateDir, spec.name);\n const specFile = await getSpecFile(specDir, config.structure.defaultFile);\n\n if (!specFile) continue;\n\n const frontmatter = await parseFrontmatter(specFile);\n if (!frontmatter) continue;\n\n // Apply filter if provided\n if (options.filter && !matchesFilter(frontmatter, options.filter)) {\n continue;\n }\n\n const specInfo: SpecInfo = {\n path: `archived/${dir.name}/${spec.name}`,\n fullPath: specDir,\n filePath: specFile,\n name: spec.name,\n date: dir.name,\n frontmatter,\n };\n\n // Load content if requested\n if (options.includeContent) {\n specInfo.content = await fs.readFile(specFile, 'utf-8');\n }\n\n // Load sub-files if requested\n if (options.includeSubFiles) {\n specInfo.subFiles = await loadSubFiles(specDir, {\n includeContent: options.includeContent,\n });\n }\n\n specs.push(specInfo);\n }\n }\n } catch {\n // No archived directory\n }\n }\n\n return specs;\n}\n\n// Get a specific spec by path\nexport async function getSpec(specPath: string): Promise<SpecInfo | null> {\n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n\n // Resolve the full path\n let fullPath: string;\n if (path.isAbsolute(specPath)) {\n fullPath = specPath;\n } else {\n fullPath = path.join(specsDir, specPath);\n }\n\n // Check if directory exists\n try {\n await fs.access(fullPath);\n } catch {\n return null;\n }\n\n const specFile = await getSpecFile(fullPath, config.structure.defaultFile);\n if (!specFile) return null;\n\n const frontmatter = await parseFrontmatter(specFile);\n if (!frontmatter) return null;\n\n const content = await fs.readFile(specFile, 'utf-8');\n\n // Parse path components\n const relativePath = path.relative(specsDir, fullPath);\n const parts = relativePath.split(path.sep);\n const date = parts[0] === 'archived' ? parts[1] : parts[0];\n const name = parts[parts.length - 1];\n\n return {\n path: relativePath,\n fullPath,\n filePath: specFile,\n name,\n date,\n frontmatter,\n content,\n };\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport matter from 'gray-matter';\nimport dayjs from 'dayjs';\n\n// Valid status values\nexport type SpecStatus = 'planned' | 'in-progress' | 'complete' | 'archived';\n\n// Valid priority values\nexport type SpecPriority = 'low' | 'medium' | 'high' | 'critical';\n\n// Core frontmatter fields\nexport interface SpecFrontmatter {\n // Required fields\n status: SpecStatus;\n created: string; // YYYY-MM-DD format\n\n // Recommended fields\n tags?: string[];\n priority?: SpecPriority;\n\n // Power user fields\n related?: string[];\n depends_on?: string[];\n updated?: string;\n completed?: string;\n assignee?: string;\n reviewer?: string;\n issue?: string;\n pr?: string;\n epic?: string;\n breaking?: boolean;\n due?: string; // YYYY-MM-DD format\n\n // Allow any additional fields (for extensibility)\n [key: string]: unknown;\n}\n\n// Parse frontmatter from a spec file\nexport async function parseFrontmatter(filePath: string): Promise<SpecFrontmatter | null> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const parsed = matter(content);\n\n if (!parsed.data || Object.keys(parsed.data).length === 0) {\n // No frontmatter found, try fallback to inline fields\n return parseFallbackFields(content);\n }\n\n // Validate required fields\n if (!parsed.data.status) {\n console.warn(`Warning: Missing required field 'status' in ${filePath}`);\n return null;\n }\n\n if (!parsed.data.created) {\n console.warn(`Warning: Missing required field 'created' in ${filePath}`);\n return null;\n }\n\n // Validate status enum\n const validStatuses: SpecStatus[] = ['planned', 'in-progress', 'complete', 'archived'];\n if (!validStatuses.includes(parsed.data.status)) {\n console.warn(`Warning: Invalid status '${parsed.data.status}' in ${filePath}. Valid values: ${validStatuses.join(', ')}`);\n }\n\n // Validate priority enum if present\n if (parsed.data.priority) {\n const validPriorities: SpecPriority[] = ['low', 'medium', 'high', 'critical'];\n if (!validPriorities.includes(parsed.data.priority)) {\n console.warn(`Warning: Invalid priority '${parsed.data.priority}' in ${filePath}. Valid values: ${validPriorities.join(', ')}`);\n }\n }\n\n // Warn about unknown fields (informational only)\n const knownFields = [\n 'status', 'created', 'tags', 'priority', 'related', 'depends_on',\n 'updated', 'completed', 'assignee', 'reviewer', 'issue', 'pr', 'epic', 'breaking'\n ];\n const unknownFields = Object.keys(parsed.data).filter(k => !knownFields.includes(k));\n if (unknownFields.length > 0) {\n console.warn(`Info: Unknown fields in ${filePath}: ${unknownFields.join(', ')}`);\n }\n\n return parsed.data as SpecFrontmatter;\n } catch (error) {\n console.error(`Error parsing frontmatter from ${filePath}:`, error);\n return null;\n }\n}\n\n// Fallback: Parse inline fields from older specs\nfunction parseFallbackFields(content: string): SpecFrontmatter | null {\n const statusMatch = content.match(/\\*\\*Status\\*\\*:\\s*(?:📅\\s*)?(\\w+(?:-\\w+)?)/i);\n const createdMatch = content.match(/\\*\\*Created\\*\\*:\\s*(\\d{4}-\\d{2}-\\d{2})/);\n\n if (statusMatch && createdMatch) {\n const status = statusMatch[1].toLowerCase().replace(/\\s+/g, '-') as SpecStatus;\n const created = createdMatch[1];\n\n return {\n status,\n created,\n };\n }\n\n return null;\n}\n\n// Update frontmatter in a spec file\nexport async function updateFrontmatter(\n filePath: string,\n updates: Partial<SpecFrontmatter>\n): Promise<void> {\n const content = await fs.readFile(filePath, 'utf-8');\n const parsed = matter(content);\n\n // Merge updates with existing data\n const newData = { ...parsed.data, ...updates };\n\n // Auto-update timestamps if fields exist\n if (updates.status === 'complete' && !newData.completed) {\n newData.completed = dayjs().format('YYYY-MM-DD');\n }\n\n if ('updated' in parsed.data) {\n newData.updated = dayjs().format('YYYY-MM-DD');\n }\n\n // Update visual metadata badges in content\n let updatedContent = parsed.content;\n updatedContent = updateVisualMetadata(updatedContent, newData as SpecFrontmatter);\n\n // Stringify back to file\n const newContent = matter.stringify(updatedContent, newData);\n await fs.writeFile(filePath, newContent, 'utf-8');\n}\n\n// Update visual metadata badges in content\nfunction updateVisualMetadata(content: string, frontmatter: SpecFrontmatter): string {\n const statusEmoji = getStatusEmojiPlain(frontmatter.status);\n const statusLabel = frontmatter.status.charAt(0).toUpperCase() + frontmatter.status.slice(1).replace('-', ' ');\n \n // Parse created date with dayjs - handles all formats consistently\n const created = dayjs(frontmatter.created).format('YYYY-MM-DD');\n \n // Build metadata line\n let metadataLine = `> **Status**: ${statusEmoji} ${statusLabel}`;\n \n if (frontmatter.priority) {\n const priorityLabel = frontmatter.priority.charAt(0).toUpperCase() + frontmatter.priority.slice(1);\n metadataLine += ` · **Priority**: ${priorityLabel}`;\n }\n \n metadataLine += ` · **Created**: ${created}`;\n \n if (frontmatter.tags && frontmatter.tags.length > 0) {\n metadataLine += ` · **Tags**: ${frontmatter.tags.join(', ')}`;\n }\n \n // For enterprise template with assignee/reviewer\n let secondLine = '';\n if (frontmatter.assignee || frontmatter.reviewer) {\n const assignee = frontmatter.assignee || 'TBD';\n const reviewer = frontmatter.reviewer || 'TBD';\n secondLine = `\\n> **Assignee**: ${assignee} · **Reviewer**: ${reviewer}`;\n }\n \n // Replace existing metadata block or add after title\n const metadataPattern = /^>\\s+\\*\\*Status\\*\\*:.*(?:\\n>\\s+\\*\\*Assignee\\*\\*:.*)?/m;\n \n if (metadataPattern.test(content)) {\n // Replace existing metadata\n return content.replace(metadataPattern, metadataLine + secondLine);\n } else {\n // Add after title (# title)\n const titleMatch = content.match(/^#\\s+.+$/m);\n if (titleMatch) {\n const insertPos = titleMatch.index! + titleMatch[0].length;\n return content.slice(0, insertPos) + '\\n\\n' + metadataLine + secondLine + '\\n' + content.slice(insertPos);\n }\n }\n \n return content;\n}\n\nfunction getStatusEmojiPlain(status: string): string {\n switch (status) {\n case 'planned': return '📅';\n case 'in-progress': return '🔨';\n case 'complete': return '✅';\n case 'archived': return '📦';\n default: return '📄';\n }\n}\n\n// Get spec file path from spec directory\nexport async function getSpecFile(specDir: string, defaultFile: string = 'README.md'): Promise<string | null> {\n const specFile = path.join(specDir, defaultFile);\n \n try {\n await fs.access(specFile);\n return specFile;\n } catch {\n return null;\n }\n}\n\n// Filter specs by criteria\nexport interface SpecFilterOptions {\n status?: SpecStatus | SpecStatus[];\n tags?: string[];\n priority?: SpecPriority | SpecPriority[];\n assignee?: string;\n}\n\nexport function matchesFilter(frontmatter: SpecFrontmatter, filter: SpecFilterOptions): boolean {\n // Status filter\n if (filter.status) {\n const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];\n if (!statuses.includes(frontmatter.status)) {\n return false;\n }\n }\n\n // Tags filter (spec must have ALL specified tags)\n if (filter.tags && filter.tags.length > 0) {\n if (!frontmatter.tags || frontmatter.tags.length === 0) {\n return false;\n }\n const hasAllTags = filter.tags.every(tag => frontmatter.tags!.includes(tag));\n if (!hasAllTags) {\n return false;\n }\n }\n\n // Priority filter\n if (filter.priority) {\n const priorities = Array.isArray(filter.priority) ? filter.priority : [filter.priority];\n if (!frontmatter.priority || !priorities.includes(frontmatter.priority)) {\n return false;\n }\n }\n\n // Assignee filter\n if (filter.assignee) {\n if (frontmatter.assignee !== filter.assignee) {\n return false;\n }\n }\n\n return true;\n}\n","import chalk from 'chalk';\nimport type { SpecStatus, SpecPriority } from '../frontmatter.js';\n\n/**\n * Get emoji for spec status\n */\nexport function getStatusEmoji(status: SpecStatus): string {\n switch (status) {\n case 'planned': return chalk.gray('📅');\n case 'in-progress': return chalk.yellow('🔨');\n case 'complete': return chalk.green('✅');\n case 'archived': return chalk.gray('📦');\n default: return '';\n }\n}\n\n/**\n * Get label for spec priority\n */\nexport function getPriorityLabel(priority: SpecPriority): string {\n switch (priority) {\n case 'low': return chalk.gray('low');\n case 'medium': return chalk.blue('med');\n case 'high': return chalk.yellow('high');\n case 'critical': return chalk.red('CRIT');\n default: return '';\n }\n}\n","import * as path from 'node:path';\nimport chalk from 'chalk';\nimport { loadConfig } from '../config.js';\nimport { getSpecFile, updateFrontmatter } from '../frontmatter.js';\nimport { resolveSpecPath } from '../utils/path-helpers.js';\nimport type { SpecStatus, SpecPriority } from '../frontmatter.js';\n\nexport async function updateSpec(\n specPath: string,\n updates: {\n status?: SpecStatus;\n priority?: SpecPriority;\n tags?: string[];\n assignee?: string;\n }\n): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n \n const resolvedPath = await resolveSpecPath(specPath, cwd, specsDir);\n\n if (!resolvedPath) {\n console.error(chalk.red(`Error: Spec not found: ${specPath}`));\n console.error(chalk.gray(`Tried: ${specPath}, specs/${specPath}, and searching in date directories`));\n process.exit(1);\n }\n\n // Get spec file\n const specFile = await getSpecFile(resolvedPath, config.structure.defaultFile);\n if (!specFile) {\n console.error(chalk.red(`Error: No spec file found in: ${specPath}`));\n process.exit(1);\n }\n\n // Update frontmatter\n await updateFrontmatter(specFile, updates);\n\n console.log(chalk.green(`✓ Updated: ${path.relative(cwd, resolvedPath)}`));\n \n // Show what was updated\n const updatedFields = Object.keys(updates).join(', ');\n console.log(chalk.gray(` Fields: ${updatedFields}`));\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport chalk from 'chalk';\nimport { loadConfig, saveConfig } from '../config.js';\n\nexport async function listTemplates(cwd: string = process.cwd()): Promise<void> {\n const config = await loadConfig(cwd);\n const templatesDir = path.join(cwd, '.lspec', 'templates');\n\n console.log('');\n console.log(chalk.green('=== Project Templates ==='));\n console.log('');\n\n try {\n await fs.access(templatesDir);\n } catch {\n console.log(chalk.yellow('No templates directory found.'));\n console.log(chalk.gray('Run: lspec init'));\n console.log('');\n return;\n }\n\n const files = await fs.readdir(templatesDir);\n const templateFiles = files.filter((f) => f.endsWith('.md'));\n\n if (templateFiles.length === 0) {\n console.log(chalk.yellow('No templates found.'));\n console.log('');\n return;\n }\n\n // Show registered templates first\n if (config.templates && Object.keys(config.templates).length > 0) {\n console.log(chalk.cyan('Registered:'));\n for (const [name, file] of Object.entries(config.templates)) {\n const isDefault = config.template === file;\n const marker = isDefault ? chalk.green('✓ (default)') : '';\n console.log(` ${chalk.bold(name)}: ${file} ${marker}`);\n }\n console.log('');\n }\n\n // Show all available template files\n console.log(chalk.cyan('Available files:'));\n for (const file of templateFiles) {\n const filePath = path.join(templatesDir, file);\n const stat = await fs.stat(filePath);\n const sizeKB = (stat.size / 1024).toFixed(1);\n console.log(` ${file} (${sizeKB} KB)`);\n }\n\n console.log('');\n console.log(chalk.gray('Use templates with: lspec create <name> --template=<template-name>'));\n console.log('');\n}\n\nexport async function showTemplate(\n templateName: string,\n cwd: string = process.cwd(),\n): Promise<void> {\n const config = await loadConfig(cwd);\n\n if (!config.templates?.[templateName]) {\n console.error(chalk.red(`Template not found: ${templateName}`));\n console.error(chalk.gray(`Available: ${Object.keys(config.templates || {}).join(', ')}`));\n process.exit(1);\n }\n\n const templatesDir = path.join(cwd, '.lspec', 'templates');\n const templateFile = config.templates[templateName];\n const templatePath = path.join(templatesDir, templateFile);\n\n try {\n const content = await fs.readFile(templatePath, 'utf-8');\n console.log('');\n console.log(chalk.cyan(`=== Template: ${templateName} (${templateFile}) ===`));\n console.log('');\n console.log(content);\n console.log('');\n } catch (error) {\n console.error(chalk.red(`Error reading template: ${templateFile}`));\n console.error(error);\n process.exit(1);\n }\n}\n\nexport async function addTemplate(\n name: string,\n file: string,\n cwd: string = process.cwd(),\n): Promise<void> {\n const config = await loadConfig(cwd);\n const templatesDir = path.join(cwd, '.lspec', 'templates');\n const templatePath = path.join(templatesDir, file);\n\n // Check if file exists\n try {\n await fs.access(templatePath);\n } catch {\n console.error(chalk.red(`Template file not found: ${file}`));\n console.error(chalk.gray(`Expected at: ${templatePath}`));\n console.error(\n chalk.yellow('Create the file first or use: lspec templates copy <source> <target>'),\n );\n process.exit(1);\n }\n\n // Add to config\n if (!config.templates) {\n config.templates = {};\n }\n\n if (config.templates[name]) {\n console.log(chalk.yellow(`Warning: Template '${name}' already exists, updating...`));\n }\n\n config.templates[name] = file;\n await saveConfig(config, cwd);\n\n console.log(chalk.green(`✓ Added template: ${name} → ${file}`));\n console.log(chalk.gray(` Use with: lspec create <spec-name> --template=${name}`));\n}\n\nexport async function removeTemplate(name: string, cwd: string = process.cwd()): Promise<void> {\n const config = await loadConfig(cwd);\n\n if (!config.templates?.[name]) {\n console.error(chalk.red(`Template not found: ${name}`));\n console.error(chalk.gray(`Available: ${Object.keys(config.templates || {}).join(', ')}`));\n process.exit(1);\n }\n\n if (name === 'default') {\n console.error(chalk.red('Cannot remove default template'));\n process.exit(1);\n }\n\n const file = config.templates[name];\n delete config.templates[name];\n await saveConfig(config, cwd);\n\n console.log(chalk.green(`✓ Removed template: ${name}`));\n console.log(chalk.gray(` Note: Template file ${file} still exists in .lspec/templates/`));\n}\n\nexport async function copyTemplate(\n source: string,\n target: string,\n cwd: string = process.cwd(),\n): Promise<void> {\n const config = await loadConfig(cwd);\n const templatesDir = path.join(cwd, '.lspec', 'templates');\n\n // Resolve source template\n let sourceFile: string;\n if (config.templates?.[source]) {\n sourceFile = config.templates[source];\n } else {\n sourceFile = source;\n }\n\n const sourcePath = path.join(templatesDir, sourceFile);\n\n // Check if source exists\n try {\n await fs.access(sourcePath);\n } catch {\n console.error(chalk.red(`Source template not found: ${source}`));\n console.error(chalk.gray(`Expected at: ${sourcePath}`));\n process.exit(1);\n }\n\n // Determine target filename\n const targetFile = target.endsWith('.md') ? target : `${target}.md`;\n const targetPath = path.join(templatesDir, targetFile);\n\n // Copy file\n await fs.copyFile(sourcePath, targetPath);\n console.log(chalk.green(`✓ Copied: ${sourceFile} → ${targetFile}`));\n\n // Optionally register the new template\n if (!config.templates) {\n config.templates = {};\n }\n\n const templateName = target.replace(/\\.md$/, '');\n config.templates[templateName] = targetFile;\n await saveConfig(config, cwd);\n\n console.log(chalk.green(`✓ Registered template: ${templateName}`));\n console.log(chalk.gray(` Edit: ${targetPath}`));\n console.log(chalk.gray(` Use with: lspec create <spec-name> --template=${templateName}`));\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport chalk from 'chalk';\nimport { select } from '@inquirer/prompts';\nimport { saveConfig, type LeanSpecConfig } from '../config.js';\nimport {\n detectExistingSystemPrompts,\n handleExistingFiles,\n copyDirectory,\n getProjectName,\n} from '../utils/template-helpers.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = path.join(__dirname, '..', 'templates');\n\nexport async function initProject(): Promise<void> {\n const cwd = process.cwd();\n\n // Check if already initialized\n try {\n await fs.access(path.join(cwd, '.lspec', 'config.json'));\n console.log(chalk.yellow('LeanSpec already initialized in this directory.'));\n console.log(chalk.gray('To reinitialize, delete .lspec/ directory first.'));\n return;\n } catch {\n // Not initialized, continue\n }\n\n console.log('');\n console.log(chalk.green('Welcome to LeanSpec!'));\n console.log('');\n\n // Main question: How to set up?\n const setupMode = await select({\n message: 'How would you like to set up?',\n choices: [\n {\n name: 'Quick start (recommended)',\n value: 'quick',\n description: 'Use standard template, start immediately',\n },\n {\n name: 'Choose template',\n value: 'template',\n description: 'Pick from: minimal, standard, enterprise',\n },\n {\n name: 'Customize everything',\n value: 'custom',\n description: 'Full control over structure and settings',\n },\n ],\n });\n\n let templateName = 'standard';\n\n if (setupMode === 'template') {\n // Let user choose template\n templateName = await select({\n message: 'Select template:',\n choices: [\n { name: 'minimal', value: 'minimal', description: 'Just folder structure, no extras' },\n { name: 'standard', value: 'standard', description: 'Recommended - includes AGENTS.md' },\n {\n name: 'enterprise',\n value: 'enterprise',\n description: 'Governance with approvals and compliance',\n },\n ],\n });\n } else if (setupMode === 'custom') {\n // TODO: Implement full customization flow\n console.log(chalk.yellow('Full customization coming soon. Using standard for now.'));\n }\n\n // Load template config\n const templateDir = path.join(TEMPLATES_DIR, templateName);\n const templateConfigPath = path.join(templateDir, 'config.json');\n\n let templateConfig: LeanSpecConfig;\n try {\n const content = await fs.readFile(templateConfigPath, 'utf-8');\n templateConfig = JSON.parse(content).config;\n } catch {\n console.error(chalk.red(`Error: Template not found: ${templateName}`));\n process.exit(1);\n }\n\n // Create .lspec/templates/ directory\n const templatesDir = path.join(cwd, '.lspec', 'templates');\n try {\n await fs.mkdir(templatesDir, { recursive: true });\n } catch (error) {\n console.error(chalk.red('Error creating templates directory:'), error);\n process.exit(1);\n }\n \n // Copy chosen template to .lspec/templates/spec-template.md\n const templateSpecPath = path.join(templateDir, 'spec-template.md');\n const targetSpecPath = path.join(templatesDir, 'spec-template.md');\n try {\n await fs.copyFile(templateSpecPath, targetSpecPath);\n console.log(chalk.green('✓ Created .lspec/templates/spec-template.md'));\n } catch (error) {\n console.error(chalk.red('Error copying template:'), error);\n process.exit(1);\n }\n \n // Update config to use new template structure\n templateConfig.template = 'spec-template.md';\n templateConfig.templates = {\n default: 'spec-template.md',\n };\n\n // Save config\n await saveConfig(templateConfig, cwd);\n console.log(chalk.green('✓ Created .lspec/config.json'));\n\n // Check for existing system prompt files\n const existingFiles = await detectExistingSystemPrompts(cwd);\n let skipFiles: string[] = [];\n\n if (existingFiles.length > 0) {\n console.log('');\n console.log(chalk.yellow(`Found existing: ${existingFiles.join(', ')}`));\n\n const action = await select<'merge' | 'backup' | 'skip'>({\n message: 'How would you like to proceed?',\n choices: [\n {\n name: 'Merge - Add LeanSpec section to existing files',\n value: 'merge',\n description: 'Appends LeanSpec guidance to your existing AGENTS.md',\n },\n {\n name: 'Backup - Save existing and create new',\n value: 'backup',\n description: 'Renames existing files to .backup and creates fresh ones',\n },\n {\n name: 'Skip - Keep existing files as-is',\n value: 'skip',\n description: 'Only adds .lspec config and specs/ directory',\n },\n ],\n });\n\n // Get project name for variable substitution\n const projectName = await getProjectName(cwd);\n \n await handleExistingFiles(action, existingFiles, templateDir, cwd, { project_name: projectName });\n\n if (action === 'skip') {\n skipFiles = existingFiles;\n }\n }\n\n // Get project name for variable substitution\n const projectName = await getProjectName(cwd);\n\n // Copy template files (excluding those we're skipping)\n const filesDir = path.join(templateDir, 'files');\n try {\n await copyDirectory(filesDir, cwd, skipFiles, { project_name: projectName });\n console.log(chalk.green('✓ Initialized project structure'));\n } catch (error) {\n console.error(chalk.red('Error copying template files:'), error);\n process.exit(1);\n }\n\n console.log('');\n console.log(chalk.green('✓ LeanSpec initialized!'));\n console.log('');\n console.log('Next steps:');\n console.log(chalk.gray(' - Review and customize AGENTS.md'));\n console.log(chalk.gray(' - Check out example spec in specs/'));\n console.log(chalk.gray(' - Create your first spec: lspec create my-feature'));\n console.log('');\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport chalk from 'chalk';\n\n/**\n * Detect common system prompt files in a directory\n */\nexport async function detectExistingSystemPrompts(cwd: string): Promise<string[]> {\n const commonFiles = [\n 'AGENTS.md',\n '.cursorrules',\n '.github/copilot-instructions.md',\n ];\n\n const found: string[] = [];\n for (const file of commonFiles) {\n try {\n await fs.access(path.join(cwd, file));\n found.push(file);\n } catch {\n // File doesn't exist\n }\n }\n return found;\n}\n\n/**\n * Handle existing system prompt files based on user's chosen action\n */\nexport async function handleExistingFiles(\n action: 'merge' | 'backup' | 'skip',\n existingFiles: string[],\n templateDir: string,\n cwd: string,\n variables: Record<string, string> = {}\n): Promise<void> {\n for (const file of existingFiles) {\n const filePath = path.join(cwd, file);\n const templateFilePath = path.join(templateDir, 'files', file);\n\n // Check if template has this file\n try {\n await fs.access(templateFilePath);\n } catch {\n // Template doesn't have this file, skip\n continue;\n }\n\n if (action === 'merge' && file === 'AGENTS.md') {\n // Append LeanSpec section to existing AGENTS.md\n const existing = await fs.readFile(filePath, 'utf-8');\n let template = await fs.readFile(templateFilePath, 'utf-8');\n \n // Replace variables in template\n for (const [key, value] of Object.entries(variables)) {\n template = template.replace(new RegExp(`\\\\{${key}\\\\}`, 'g'), value);\n }\n\n const merged = `${existing}\n\n---\n\n## LeanSpec Integration\n\n${template.split('\\n').slice(1).join('\\n')}`;\n\n await fs.writeFile(filePath, merged, 'utf-8');\n console.log(chalk.green(`✓ Merged LeanSpec section into ${file}`));\n } else if (action === 'backup') {\n // Backup existing file\n const backupPath = `${filePath}.backup`;\n await fs.rename(filePath, backupPath);\n console.log(chalk.yellow(`✓ Backed up ${file} → ${file}.backup`));\n\n // Copy template file with variable substitution\n let content = await fs.readFile(templateFilePath, 'utf-8');\n \n // Replace variables in content\n for (const [key, value] of Object.entries(variables)) {\n content = content.replace(new RegExp(`\\\\{${key}\\\\}`, 'g'), value);\n }\n \n await fs.writeFile(filePath, content, 'utf-8');\n console.log(chalk.green(`✓ Created new ${file}`));\n }\n // If skip, do nothing with this file\n }\n}\n\n/**\n * Recursively copy directory with variable substitution and skip list\n */\nexport async function copyDirectory(\n src: string,\n dest: string,\n skipFiles: string[] = [],\n variables: Record<string, string> = {}\n): Promise<void> {\n await fs.mkdir(dest, { recursive: true });\n\n const entries = await fs.readdir(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n // Check if this file should be skipped\n if (skipFiles.includes(entry.name)) {\n continue;\n }\n\n if (entry.isDirectory()) {\n await copyDirectory(srcPath, destPath, skipFiles, variables);\n } else {\n // Only copy if file doesn't exist\n try {\n await fs.access(destPath);\n // File exists, skip it\n } catch {\n // File doesn't exist, copy it with variable substitution\n let content = await fs.readFile(srcPath, 'utf-8');\n \n // Replace variables in content\n for (const [key, value] of Object.entries(variables)) {\n content = content.replace(new RegExp(`\\\\{${key}\\\\}`, 'g'), value);\n }\n \n await fs.writeFile(destPath, content, 'utf-8');\n }\n }\n }\n}\n\n/**\n * Get project name from package.json or directory name\n */\nexport async function getProjectName(cwd: string): Promise<string> {\n try {\n const packageJsonPath = path.join(cwd, 'package.json');\n const content = await fs.readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n if (pkg.name) {\n return pkg.name;\n }\n } catch {\n // package.json not found or invalid\n }\n \n // Fallback to directory name\n return path.basename(cwd);\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport chalk from 'chalk';\nimport { getSpec, loadSubFiles } from '../spec-loader.js';\nimport { resolveSpecPath } from '../utils/path-helpers.js';\nimport { loadConfig } from '../config.js';\n\nexport async function filesCommand(\n specPath: string,\n options: {\n type?: 'docs' | 'assets';\n tree?: boolean;\n } = {}\n): Promise<void> {\n const config = await loadConfig();\n const cwd = process.cwd();\n const specsDir = path.join(cwd, config.specsDir);\n\n // Resolve spec path\n const resolvedPath = await resolveSpecPath(specPath, cwd, specsDir);\n if (!resolvedPath) {\n console.error(chalk.red(`Spec not found: ${specPath}`));\n console.error(\n chalk.gray('Try using the full path or spec name (e.g., 001-my-spec)')\n );\n process.exit(1);\n }\n\n // Load spec info\n const spec = await getSpec(resolvedPath);\n if (!spec) {\n console.error(chalk.red(`Could not load spec: ${specPath}`));\n process.exit(1);\n }\n\n // Load sub-files\n const subFiles = await loadSubFiles(spec.fullPath);\n\n console.log('');\n console.log(chalk.cyan(`📄 Files in ${spec.name}`));\n console.log('');\n\n // Show README.md (required)\n console.log(chalk.green('Required:'));\n const readmeStat = await fs.stat(spec.filePath);\n const readmeSize = formatSize(readmeStat.size);\n console.log(chalk.green(` ✓ README.md (${readmeSize}) Main spec`));\n console.log('');\n\n // Filter by type if requested\n let filteredFiles = subFiles;\n if (options.type === 'docs') {\n filteredFiles = subFiles.filter((f) => f.type === 'document');\n } else if (options.type === 'assets') {\n filteredFiles = subFiles.filter((f) => f.type === 'asset');\n }\n\n if (filteredFiles.length === 0) {\n console.log(chalk.gray('No additional files'));\n console.log('');\n return;\n }\n\n // Group by type\n const documents = filteredFiles.filter((f) => f.type === 'document');\n const assets = filteredFiles.filter((f) => f.type === 'asset');\n\n if (documents.length > 0 && (!options.type || options.type === 'docs')) {\n console.log(chalk.cyan('Documents:'));\n for (const file of documents) {\n const size = formatSize(file.size);\n console.log(chalk.cyan(` ✓ ${file.name.padEnd(20)} (${size})`));\n }\n console.log('');\n }\n\n if (assets.length > 0 && (!options.type || options.type === 'assets')) {\n console.log(chalk.yellow('Assets:'));\n for (const file of assets) {\n const size = formatSize(file.size);\n console.log(chalk.yellow(` ✓ ${file.name.padEnd(20)} (${size})`));\n }\n console.log('');\n }\n\n // Show totals\n const totalFiles = filteredFiles.length + 1; // +1 for README.md\n const totalSize = formatSize(\n readmeStat.size + filteredFiles.reduce((sum, f) => sum + f.size, 0)\n );\n console.log(chalk.gray(`Total: ${totalFiles} files, ${totalSize}`));\n console.log('');\n}\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n } else if (bytes < 1024 * 1024) {\n return `${(bytes / 1024).toFixed(1)} KB`;\n } else {\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n }\n}\n","import React from 'react';\nimport { render } from 'ink';\nimport { loadAllSpecs } from '../spec-loader.js';\nimport type { SpecFilterOptions } from '../frontmatter.js';\nimport { Board } from '../components/Board.js';\nimport { withSpinner } from '../utils/ui.js';\n\nexport async function boardCommand(options: {\n showComplete?: boolean;\n tag?: string;\n assignee?: string;\n}): Promise<void> {\n // Build filter\n const filter: SpecFilterOptions = {};\n if (options.tag) {\n filter.tags = [options.tag];\n }\n if (options.assignee) {\n filter.assignee = options.assignee;\n }\n\n // Load all specs with spinner (exclude archived, they go in their own archive view)\n const specs = await withSpinner(\n 'Loading specs...',\n () => loadAllSpecs({\n includeArchived: false,\n filter,\n })\n );\n\n if (specs.length === 0) {\n console.log('No specs found.');\n return;\n }\n\n // Render with Ink\n const filterOptions = {\n tag: options.tag,\n assignee: options.assignee,\n };\n\n render(\n React.createElement(Board, {\n specs,\n showComplete: options.showComplete,\n filter: (options.tag || options.assignee) ? filterOptions : undefined,\n })\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { SpecInfo } from '../spec-loader.js';\nimport type { SpecStatus } from '../frontmatter.js';\n\ninterface BoardProps {\n specs: SpecInfo[];\n showComplete?: boolean;\n filter?: {\n tag?: string;\n assignee?: string;\n };\n}\n\nconst STATUS_CONFIG: Record<SpecStatus, { emoji: string; label: string; color: string }> = {\n planned: { emoji: '📅', label: 'Planned', color: 'gray' },\n 'in-progress': { emoji: '🔨', label: 'In Progress', color: 'yellow' },\n complete: { emoji: '✅', label: 'Complete', color: 'green' },\n archived: { emoji: '📦', label: 'Archived', color: 'gray' },\n};\n\ninterface ColumnProps {\n title: string;\n emoji: string;\n specs: SpecInfo[];\n expanded: boolean;\n color: string;\n}\n\nconst Column: React.FC<ColumnProps> = ({ title, emoji, specs, expanded, color }) => {\n const width = 60;\n const count = specs.length;\n const header = `${emoji} ${title} (${count})`;\n const padding = Math.max(0, width - header.length - 4);\n\n return (\n <Box flexDirection=\"column\" marginBottom={1}>\n {/* Top border */}\n <Text>┌─ {header} {'─'.repeat(padding)}┐</Text>\n\n {/* Content */}\n {expanded && specs.length > 0 ? (\n specs.map((spec, index) => (\n <Box key={spec.path} flexDirection=\"column\">\n <Text>\n │ <Text color=\"cyan\">{spec.path.padEnd(width - 2)}</Text>│\n </Text>\n\n {/* Metadata line */}\n {(spec.frontmatter.tags?.length || spec.frontmatter.priority || spec.frontmatter.assignee) && (() => {\n const parts: string[] = [];\n if (spec.frontmatter.tags?.length) {\n parts.push(`[${spec.frontmatter.tags.join(', ')}]`);\n }\n if (spec.frontmatter.priority) {\n parts.push(`priority: ${spec.frontmatter.priority}`);\n }\n if (spec.frontmatter.assignee) {\n parts.push(`assignee: ${spec.frontmatter.assignee}`);\n }\n const metaText = parts.join(' ');\n const paddingNeeded = Math.max(0, width - 2 - metaText.length);\n \n return (\n <Text>\n │ <Text dimColor>{metaText}</Text>{' '.repeat(paddingNeeded)}│\n </Text>\n );\n })()}\n\n {/* Spacing between specs */}\n {index < specs.length - 1 && (\n <Text>│ {' '.repeat(width - 2)}│</Text>\n )}\n </Box>\n ))\n ) : !expanded && specs.length > 0 ? (\n <Text>\n │ <Text dimColor>(collapsed, use --show-complete to expand)</Text>\n {' '.repeat(Math.max(0, width - 47))}│\n </Text>\n ) : (\n <Text>\n │ <Text dimColor>(no specs)</Text>\n {' '.repeat(Math.max(0, width - 13))}│\n </Text>\n )}\n\n {/* Bottom border */}\n <Text>└{'─'.repeat(width)}┘</Text>\n </Box>\n );\n};\n\nexport const Board: React.FC<BoardProps> = ({ specs, showComplete, filter }) => {\n // Group specs by status\n const columns: Record<SpecStatus, SpecInfo[]> = {\n planned: [],\n 'in-progress': [],\n complete: [],\n archived: [],\n };\n\n for (const spec of specs) {\n // Handle invalid status by treating as 'planned'\n const status = columns[spec.frontmatter.status] !== undefined \n ? spec.frontmatter.status \n : 'planned';\n columns[status].push(spec);\n }\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold color=\"green\">📋 Spec Board</Text>\n </Box>\n\n {/* Filter info */}\n {filter && (filter.tag || filter.assignee) && (\n <Box marginBottom={1}>\n <Text dimColor>\n Filtered by: {filter.tag && `tag=${filter.tag}`}\n {filter.tag && filter.assignee && ', '}\n {filter.assignee && `assignee=${filter.assignee}`}\n </Text>\n </Box>\n )}\n\n {/* Columns */}\n <Column\n title={STATUS_CONFIG.planned.label}\n emoji={STATUS_CONFIG.planned.emoji}\n specs={columns.planned}\n expanded={true}\n color={STATUS_CONFIG.planned.color}\n />\n\n <Column\n title={STATUS_CONFIG['in-progress'].label}\n emoji={STATUS_CONFIG['in-progress'].emoji}\n specs={columns['in-progress']}\n expanded={true}\n color={STATUS_CONFIG['in-progress'].color}\n />\n\n <Column\n title={STATUS_CONFIG.complete.label}\n emoji={STATUS_CONFIG.complete.emoji}\n specs={columns.complete}\n expanded={showComplete || false}\n color={STATUS_CONFIG.complete.color}\n />\n </Box>\n );\n};\n","import React from 'react';\nimport { render } from 'ink';\nimport { loadAllSpecs } from '../spec-loader.js';\nimport type { SpecStatus, SpecPriority, SpecFilterOptions } from '../frontmatter.js';\nimport { StatsDisplay } from '../components/StatsDisplay.js';\nimport { withSpinner } from '../utils/ui.js';\n\nexport async function statsCommand(options: {\n tag?: string;\n assignee?: string;\n json?: boolean;\n}): Promise<void> {\n // Build filter\n const filter: SpecFilterOptions = {};\n if (options.tag) {\n filter.tags = [options.tag];\n }\n if (options.assignee) {\n filter.assignee = options.assignee;\n }\n\n // Load all specs with spinner (including archived for total count)\n const specs = await withSpinner(\n 'Loading specs...',\n () => loadAllSpecs({\n includeArchived: true,\n filter,\n })\n );\n\n if (specs.length === 0) {\n console.log('No specs found.');\n return;\n }\n\n // Output as JSON if requested\n if (options.json) {\n // Calculate statistics for JSON output\n const statusCounts: Record<SpecStatus, number> = {\n planned: 0,\n 'in-progress': 0,\n complete: 0,\n archived: 0,\n };\n\n const priorityCounts: Record<SpecPriority, number> = {\n low: 0,\n medium: 0,\n high: 0,\n critical: 0,\n };\n\n const tagCounts: Record<string, number> = {};\n\n for (const spec of specs) {\n statusCounts[spec.frontmatter.status]++;\n if (spec.frontmatter.priority) {\n priorityCounts[spec.frontmatter.priority]++;\n }\n if (spec.frontmatter.tags) {\n for (const tag of spec.frontmatter.tags) {\n tagCounts[tag] = (tagCounts[tag] || 0) + 1;\n }\n }\n }\n\n const data = {\n total: specs.length,\n status: statusCounts,\n priority: priorityCounts,\n tags: tagCounts,\n filter: filter,\n };\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n // Render with Ink\n const filterOptions = {\n tag: options.tag,\n assignee: options.assignee,\n };\n\n render(\n React.createElement(StatsDisplay, {\n specs,\n filter: (options.tag || options.assignee) ? filterOptions : undefined,\n })\n );\n}\n","import React from 'react';\nimport { Box, Text } from 'ink';\nimport type { SpecInfo } from '../spec-loader.js';\nimport type { SpecStatus, SpecPriority } from '../frontmatter.js';\n\ninterface StatsProps {\n specs: SpecInfo[];\n filter?: {\n tag?: string;\n assignee?: string;\n };\n}\n\nexport const StatsDisplay: React.FC<StatsProps> = ({ specs, filter }) => {\n // Calculate statistics\n const statusCounts: Record<SpecStatus, number> = {\n planned: 0,\n 'in-progress': 0,\n complete: 0,\n archived: 0,\n };\n\n const priorityCounts: Record<SpecPriority, number> = {\n low: 0,\n medium: 0,\n high: 0,\n critical: 0,\n };\n\n const tagCounts: Record<string, number> = {};\n\n for (const spec of specs) {\n // Count by status\n statusCounts[spec.frontmatter.status]++;\n\n // Count by priority\n if (spec.frontmatter.priority) {\n priorityCounts[spec.frontmatter.priority]++;\n }\n\n // Count by tags\n if (spec.frontmatter.tags) {\n for (const tag of spec.frontmatter.tags) {\n tagCounts[tag] = (tagCounts[tag] || 0) + 1;\n }\n }\n }\n\n // Sort tags by count\n const topTags = Object.entries(tagCounts)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5);\n\n const totalWithPriority = Object.values(priorityCounts).reduce((sum, count) => sum + count, 0);\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold color=\"green\">📊 Spec Statistics</Text>\n </Box>\n\n {/* Filter info */}\n {filter && (filter.tag || filter.assignee) && (\n <Box marginBottom={1}>\n <Text dimColor>\n Filtered by: {filter.tag && `tag=${filter.tag}`}\n {filter.tag && filter.assignee && ', '}\n {filter.assignee && `assignee=${filter.assignee}`}\n </Text>\n </Box>\n )}\n\n {/* Status breakdown */}\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold>Status:</Text>\n <Text> 📅 Planned: <Text color=\"cyan\">{statusCounts.planned.toString().padStart(3)}</Text></Text>\n <Text> 🔨 In Progress: <Text color=\"yellow\">{statusCounts['in-progress'].toString().padStart(3)}</Text></Text>\n <Text> ✅ Complete: <Text color=\"green\">{statusCounts.complete.toString().padStart(3)}</Text></Text>\n <Text> 📦 Archived: <Text dimColor>{statusCounts.archived.toString().padStart(3)}</Text></Text>\n </Box>\n\n {/* Priority breakdown */}\n {totalWithPriority > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold>Priority:</Text>\n {priorityCounts.critical > 0 && (\n <Text> 🔴 Critical: <Text color=\"red\">{priorityCounts.critical.toString().padStart(3)}</Text></Text>\n )}\n {priorityCounts.high > 0 && (\n <Text> 🟡 High: <Text color=\"yellow\">{priorityCounts.high.toString().padStart(3)}</Text></Text>\n )}\n {priorityCounts.medium > 0 && (\n <Text> 🟠 Medium: <Text color=\"blue\">{priorityCounts.medium.toString().padStart(3)}</Text></Text>\n )}\n {priorityCounts.low > 0 && (\n <Text> 🟢 Low: <Text dimColor>{priorityCounts.low.toString().padStart(3)}</Text></Text>\n )}\n </Box>\n )}\n\n {/* Top tags */}\n {topTags.length > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold>Tags (top {topTags.length}):</Text>\n {topTags.map(([tag, count]) => (\n <Text key={tag}>\n {' '}{tag.padEnd(20)} <Text color=\"cyan\">{count.toString().padStart(3)}</Text>\n </Text>\n ))}\n </Box>\n )}\n\n {/* Total */}\n <Box>\n <Text bold>Total Specs: <Text color=\"green\">{specs.length.toString()}</Text></Text>\n </Box>\n </Box>\n );\n};\n","import React from 'react';\nimport { render } from 'ink';\nimport chalk from 'chalk';\nimport { loadAllSpecs } from '../spec-loader.js';\nimport type { SpecStatus, SpecPriority, SpecFilterOptions } from '../frontmatter.js';\nimport { SpecList } from '../components/SpecList.js';\nimport { withSpinner } from '../utils/ui.js';\n\nexport async function searchCommand(query: string, options: {\n status?: SpecStatus;\n tag?: string;\n priority?: SpecPriority;\n assignee?: string;\n}): Promise<void> {\n // Build filter\n const filter: SpecFilterOptions = {};\n if (options.status) filter.status = options.status;\n if (options.tag) filter.tags = [options.tag];\n if (options.priority) filter.priority = options.priority;\n if (options.assignee) filter.assignee = options.assignee;\n\n // Load all specs with content and spinner\n const specs = await withSpinner(\n 'Searching specs...',\n () => loadAllSpecs({\n includeArchived: true,\n includeContent: true,\n filter,\n })\n );\n\n if (specs.length === 0) {\n console.log('No specs found matching filters.');\n return;\n }\n\n // Search for query in content\n const results: Array<{\n spec: typeof specs[0];\n matches: string[];\n }> = [];\n\n const queryLower = query.toLowerCase();\n\n for (const spec of specs) {\n if (!spec.content) continue;\n\n const matches: string[] = [];\n \n // Search in content\n const lines = spec.content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.toLowerCase().includes(queryLower)) {\n // Get context: current line with some surrounding context\n const contextStart = Math.max(0, i - 1);\n const contextEnd = Math.min(lines.length - 1, i + 1);\n const context = lines.slice(contextStart, contextEnd + 1);\n \n // Highlight the matching line\n const matchLine = context[i - contextStart];\n const highlighted = highlightMatch(matchLine, query);\n \n matches.push(highlighted);\n }\n }\n\n if (matches.length > 0) {\n results.push({ spec, matches });\n }\n }\n\n // Display results\n if (results.length === 0) {\n console.log('');\n console.log(chalk.yellow(`🔍 No specs found matching \"${query}\"`));\n \n // Show active filters\n if (Object.keys(filter).length > 0) {\n const filters: string[] = [];\n if (options.status) filters.push(`status=${options.status}`);\n if (options.tag) filters.push(`tag=${options.tag}`);\n if (options.priority) filters.push(`priority=${options.priority}`);\n if (options.assignee) filters.push(`assignee=${options.assignee}`);\n console.log(chalk.gray(`With filters: ${filters.join(', ')}`));\n }\n console.log('');\n return;\n }\n\n // Show summary header\n console.log('');\n console.log(chalk.green(`🔍 Found ${results.length} spec${results.length === 1 ? '' : 's'} matching \"${query}\"`));\n \n // Show active filters\n if (Object.keys(filter).length > 0) {\n const filters: string[] = [];\n if (options.status) filters.push(`status=${options.status}`);\n if (options.tag) filters.push(`tag=${options.tag}`);\n if (options.priority) filters.push(`priority=${options.priority}`);\n if (options.assignee) filters.push(`assignee=${options.assignee}`);\n console.log(chalk.gray(`With filters: ${filters.join(', ')}`));\n }\n console.log('');\n\n // Display each result with matches\n for (const result of results) {\n const { spec, matches } = result;\n \n // Spec header\n console.log(chalk.cyan(`${spec.frontmatter.status === 'in-progress' ? '🔨' : spec.frontmatter.status === 'complete' ? '✅' : '📅'} ${spec.path}`));\n \n // Metadata\n const meta: string[] = [];\n if (spec.frontmatter.priority) {\n const priorityEmoji = spec.frontmatter.priority === 'critical' ? '🔴' : \n spec.frontmatter.priority === 'high' ? '🟡' :\n spec.frontmatter.priority === 'medium' ? '🟠' : '🟢';\n meta.push(`${priorityEmoji} ${spec.frontmatter.priority}`);\n }\n if (spec.frontmatter.tags && spec.frontmatter.tags.length > 0) {\n meta.push(`[${spec.frontmatter.tags.join(', ')}]`);\n }\n if (meta.length > 0) {\n console.log(chalk.gray(` ${meta.join(' • ')}`));\n }\n \n // Show first few matches (limit to 3 per spec)\n const maxMatches = 3;\n for (let i = 0; i < Math.min(matches.length, maxMatches); i++) {\n console.log(` ${chalk.gray('Match:')} ${matches[i].trim()}`);\n }\n \n if (matches.length > maxMatches) {\n console.log(chalk.gray(` ... and ${matches.length - maxMatches} more match${matches.length - maxMatches === 1 ? '' : 'es'}`));\n }\n \n console.log('');\n }\n}\n\nfunction highlightMatch(text: string, query: string): string {\n const regex = new RegExp(`(${escapeRegex(query)})`, 'gi');\n return text.replace(regex, chalk.yellow('$1'));\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import chalk from 'chalk';\nimport { getSpec, loadAllSpecs, type SpecInfo } from '../spec-loader.js';\n\nexport async function depsCommand(specPath: string, options: {\n depth?: number;\n graph?: boolean;\n json?: boolean;\n}): Promise<void> {\n const spec = await getSpec(specPath);\n \n if (!spec) {\n console.error(chalk.red(`Error: Spec not found: ${specPath}`));\n process.exit(1);\n }\n\n // Load all specs to resolve dependencies\n const allSpecs = await loadAllSpecs({ includeArchived: true });\n const specMap = new Map<string, SpecInfo>();\n for (const s of allSpecs) {\n specMap.set(s.path, s);\n }\n\n // Find dependencies\n const dependsOn = findDependencies(spec, specMap);\n const blocks = findBlocking(spec, allSpecs);\n const related = findRelated(spec, specMap);\n\n // Output as JSON if requested\n if (options.json) {\n const data = {\n spec: spec.path,\n dependsOn: dependsOn.map(s => ({ path: s.path, status: s.frontmatter.status })),\n blocks: blocks.map(s => ({ path: s.path, status: s.frontmatter.status })),\n related: related.map(s => ({ path: s.path, status: s.frontmatter.status })),\n chain: buildDependencyChain(spec, specMap, options.depth || 3),\n };\n console.log(JSON.stringify(data, null, 2));\n return;\n }\n\n // Display dependencies\n console.log('');\n console.log(chalk.green(`📦 Dependencies for ${chalk.cyan(spec.path)}`));\n console.log('');\n\n // Depends On section\n console.log(chalk.bold('Depends On:'));\n if (dependsOn.length > 0) {\n for (const dep of dependsOn) {\n const status = getStatusIndicator(dep.frontmatter.status);\n console.log(` → ${dep.path} ${status}`);\n }\n } else {\n console.log(chalk.gray(' (none)'));\n }\n console.log('');\n\n // Blocks section\n console.log(chalk.bold('Blocks:'));\n if (blocks.length > 0) {\n for (const blocked of blocks) {\n const status = getStatusIndicator(blocked.frontmatter.status);\n console.log(` ← ${blocked.path} ${status}`);\n }\n } else {\n console.log(chalk.gray(' (none)'));\n }\n console.log('');\n\n // Related section\n if (related.length > 0) {\n console.log(chalk.bold('Related:'));\n for (const rel of related) {\n const status = getStatusIndicator(rel.frontmatter.status);\n console.log(` ⟷ ${rel.path} ${status}`);\n }\n console.log('');\n }\n\n // Dependency chain (tree view)\n if (options.graph || dependsOn.length > 0) {\n console.log(chalk.bold('Dependency Chain:'));\n const chain = buildDependencyChain(spec, specMap, options.depth || 3);\n displayChain(chain, 0);\n console.log('');\n }\n}\n\ninterface DependencyNode {\n spec: SpecInfo;\n dependencies: DependencyNode[];\n}\n\nfunction findDependencies(spec: SpecInfo, specMap: Map<string, SpecInfo>): SpecInfo[] {\n if (!spec.frontmatter.depends_on) return [];\n \n const deps: SpecInfo[] = [];\n for (const depPath of spec.frontmatter.depends_on) {\n const dep = specMap.get(depPath);\n if (dep) {\n deps.push(dep);\n } else {\n // Try to find by name only (in case of relative path)\n for (const [path, s] of specMap.entries()) {\n if (path.includes(depPath)) {\n deps.push(s);\n break;\n }\n }\n }\n }\n \n return deps;\n}\n\nfunction findBlocking(spec: SpecInfo, allSpecs: SpecInfo[]): SpecInfo[] {\n const blocks: SpecInfo[] = [];\n \n for (const other of allSpecs) {\n if (other.path === spec.path) continue;\n \n if (other.frontmatter.depends_on) {\n for (const depPath of other.frontmatter.depends_on) {\n if (depPath === spec.path || spec.path.includes(depPath)) {\n blocks.push(other);\n break;\n }\n }\n }\n }\n \n return blocks;\n}\n\nfunction findRelated(spec: SpecInfo, specMap: Map<string, SpecInfo>): SpecInfo[] {\n if (!spec.frontmatter.related) return [];\n \n const related: SpecInfo[] = [];\n for (const relPath of spec.frontmatter.related) {\n const rel = specMap.get(relPath);\n if (rel) {\n related.push(rel);\n } else {\n // Try to find by name only\n for (const [path, s] of specMap.entries()) {\n if (path.includes(relPath)) {\n related.push(s);\n break;\n }\n }\n }\n }\n \n return related;\n}\n\nfunction buildDependencyChain(\n spec: SpecInfo,\n specMap: Map<string, SpecInfo>,\n maxDepth: number,\n currentDepth: number = 0,\n visited: Set<string> = new Set()\n): DependencyNode {\n const node: DependencyNode = {\n spec,\n dependencies: [],\n };\n \n // Prevent infinite loops\n if (visited.has(spec.path)) {\n return node;\n }\n visited.add(spec.path);\n \n // Stop at max depth\n if (currentDepth >= maxDepth) {\n return node;\n }\n \n // Find dependencies\n const deps = findDependencies(spec, specMap);\n for (const dep of deps) {\n node.dependencies.push(buildDependencyChain(dep, specMap, maxDepth, currentDepth + 1, visited));\n }\n \n return node;\n}\n\nfunction displayChain(node: DependencyNode, level: number): void {\n const indent = ' '.repeat(level);\n const status = getStatusIndicator(node.spec.frontmatter.status);\n const name = level === 0 ? chalk.cyan(node.spec.path) : node.spec.path;\n \n console.log(`${indent}${name} ${status}`);\n \n for (const dep of node.dependencies) {\n const prefix = ' '.repeat(level) + '└─ ';\n const depStatus = getStatusIndicator(dep.spec.frontmatter.status);\n console.log(`${prefix}${dep.spec.path} ${depStatus}`);\n \n // Recursively display nested dependencies with increased indent\n for (const nestedDep of dep.dependencies) {\n displayChain(nestedDep, level + 2);\n }\n }\n}\n\nfunction getStatusIndicator(status: string): string {\n switch (status) {\n case 'planned': return chalk.gray('[planned]');\n case 'in-progress': return chalk.yellow('[in-progress]');\n case 'complete': return chalk.green('✓');\n case 'archived': return chalk.gray('[archived]');\n default: return '';\n }\n}\n","import chalk from 'chalk';\nimport dayjs from 'dayjs';\nimport { loadAllSpecs } from '../spec-loader.js';\nimport type { SpecFilterOptions } from '../frontmatter.js';\n\nexport async function timelineCommand(options: {\n days?: number;\n byTag?: boolean;\n byAssignee?: boolean;\n}): Promise<void> {\n const days = options.days || 30;\n \n // Load all specs (including archived for completion history)\n const specs = await loadAllSpecs({\n includeArchived: true,\n });\n\n if (specs.length === 0) {\n console.log('No specs found.');\n return;\n }\n\n // Calculate date range\n const today = dayjs();\n const startDate = today.subtract(days, 'day');\n\n // Count specs by date\n const createdByDate: Record<string, number> = {};\n const completedByDate: Record<string, number> = {};\n const createdByMonth: Record<string, number> = {};\n\n for (const spec of specs) {\n const created = dayjs(spec.frontmatter.created);\n \n // Count created specs within date range\n if (created.isAfter(startDate)) {\n const dateKey = created.format('YYYY-MM-DD');\n createdByDate[dateKey] = (createdByDate[dateKey] || 0) + 1;\n }\n\n // Count by month for all time\n const monthKey = created.format('MMM YYYY');\n createdByMonth[monthKey] = (createdByMonth[monthKey] || 0) + 1;\n\n // Count completed specs\n if (spec.frontmatter.completed) {\n const completed = dayjs(spec.frontmatter.completed);\n if (completed.isAfter(startDate)) {\n const dateKey = completed.format('YYYY-MM-DD');\n completedByDate[dateKey] = (completedByDate[dateKey] || 0) + 1;\n }\n }\n }\n\n // Display timeline\n console.log('');\n console.log(chalk.green(`📈 Spec Timeline (Last ${days} Days)`));\n console.log('');\n\n // Show daily activity (only days with activity)\n const allDates = new Set([...Object.keys(createdByDate), ...Object.keys(completedByDate)]);\n const sortedDates = Array.from(allDates).sort();\n\n if (sortedDates.length > 0) {\n for (const date of sortedDates) {\n const created = createdByDate[date] || 0;\n const completed = completedByDate[date] || 0;\n \n const createdBar = '█'.repeat(created);\n const completedBar = '█'.repeat(completed);\n \n let line = `${date} `;\n if (created > 0) {\n line += `${chalk.blue(createdBar)} ${created} created`;\n }\n if (completed > 0) {\n if (created > 0) line += ' ';\n line += `${chalk.green(completedBar)} ${completed} completed`;\n }\n \n console.log(line);\n }\n console.log('');\n }\n\n // Show creation by month (all time)\n const sortedMonths = Object.entries(createdByMonth)\n .sort((a, b) => {\n const dateA = dayjs(a[0], 'MMM YYYY');\n const dateB = dayjs(b[0], 'MMM YYYY');\n return dateB.diff(dateA);\n })\n .slice(0, 6); // Last 6 months\n\n if (sortedMonths.length > 0) {\n console.log(chalk.bold('Created by Month:'));\n for (const [month, count] of sortedMonths) {\n console.log(` ${month}: ${chalk.cyan(count.toString())} specs`);\n }\n console.log('');\n }\n\n // Completion rate\n const last7Days = specs.filter(s => {\n if (!s.frontmatter.completed) return false;\n const completed = dayjs(s.frontmatter.completed);\n return completed.isAfter(today.subtract(7, 'day'));\n }).length;\n\n const last30Days = specs.filter(s => {\n if (!s.frontmatter.completed) return false;\n const completed = dayjs(s.frontmatter.completed);\n return completed.isAfter(today.subtract(30, 'day'));\n }).length;\n\n console.log(chalk.bold('Completion Rate:'));\n console.log(` Last 7 days: ${chalk.green(last7Days.toString())} specs completed`);\n console.log(` Last 30 days: ${chalk.green(last30Days.toString())} specs completed`);\n console.log('');\n\n // By tag breakdown (if requested)\n if (options.byTag) {\n const tagStats: Record<string, { created: number; completed: number }> = {};\n \n for (const spec of specs) {\n const created = dayjs(spec.frontmatter.created);\n const isInRange = created.isAfter(startDate);\n \n if (isInRange && spec.frontmatter.tags) {\n for (const tag of spec.frontmatter.tags) {\n if (!tagStats[tag]) tagStats[tag] = { created: 0, completed: 0 };\n tagStats[tag].created++;\n \n if (spec.frontmatter.completed) {\n const completed = dayjs(spec.frontmatter.completed);\n if (completed.isAfter(startDate)) {\n tagStats[tag].completed++;\n }\n }\n }\n }\n }\n \n const sortedTags = Object.entries(tagStats)\n .sort((a, b) => b[1].created - a[1].created)\n .slice(0, 10);\n \n if (sortedTags.length > 0) {\n console.log(chalk.bold('By Tag:'));\n for (const [tag, stats] of sortedTags) {\n console.log(` ${tag.padEnd(20)} ${chalk.blue(stats.created.toString())} created, ${chalk.green(stats.completed.toString())} completed`);\n }\n console.log('');\n }\n }\n\n // By assignee breakdown (if requested)\n if (options.byAssignee) {\n const assigneeStats: Record<string, { created: number; completed: number }> = {};\n \n for (const spec of specs) {\n if (!spec.frontmatter.assignee) continue;\n \n const created = dayjs(spec.frontmatter.created);\n const isInRange = created.isAfter(startDate);\n \n if (isInRange) {\n const assignee = spec.frontmatter.assignee;\n if (!assigneeStats[assignee]) assigneeStats[assignee] = { created: 0, completed: 0 };\n assigneeStats[assignee].created++;\n \n if (spec.frontmatter.completed) {\n const completed = dayjs(spec.frontmatter.completed);\n if (completed.isAfter(startDate)) {\n assigneeStats[assignee].completed++;\n }\n }\n }\n }\n \n const sortedAssignees = Object.entries(assigneeStats)\n .sort((a, b) => b[1].created - a[1].created);\n \n if (sortedAssignees.length > 0) {\n console.log(chalk.bold('By Assignee:'));\n for (const [assignee, stats] of sortedAssignees) {\n console.log(` ${assignee.padEnd(20)} ${chalk.blue(stats.created.toString())} created, ${chalk.green(stats.completed.toString())} completed`);\n }\n console.log('');\n }\n }\n}\n","import chalk from 'chalk';\nimport dayjs from 'dayjs';\nimport { loadAllSpecs, type SpecInfo } from '../spec-loader.js';\n\nexport async function ganttCommand(options: {\n weeks?: number;\n showComplete?: boolean;\n criticalPath?: boolean;\n}): Promise<void> {\n const weeks = options.weeks || 4;\n \n // Load all specs\n const specs = await loadAllSpecs({\n includeArchived: false,\n });\n\n if (specs.length === 0) {\n console.log('No specs found.');\n return;\n }\n\n // Filter specs with due dates or in relevant status\n const relevantSpecs = specs.filter(spec => {\n if (!options.showComplete && spec.frontmatter.status === 'complete') {\n return false;\n }\n // Include specs that have due dates, dependencies, or are in progress\n return (\n spec.frontmatter.due ||\n spec.frontmatter.depends_on ||\n spec.frontmatter.status === 'in-progress' ||\n spec.frontmatter.status === 'complete'\n );\n });\n\n if (relevantSpecs.length === 0) {\n console.log('No specs found with due dates or dependencies.');\n console.log(chalk.gray('Tip: Add a \"due: YYYY-MM-DD\" field to frontmatter to use gantt view.'));\n return;\n }\n\n // Calculate date range\n const today = dayjs();\n const startDate = today.startOf('week');\n const endDate = startDate.add(weeks, 'week');\n\n // Display gantt chart\n console.log('');\n console.log(chalk.green('📅 Gantt Chart'));\n console.log('');\n\n // Display timeline header\n const timelineHeader = buildTimelineHeader(startDate, weeks);\n console.log(timelineHeader);\n console.log('|' + '--------|'.repeat(weeks));\n console.log('');\n\n // Display each spec\n for (const spec of relevantSpecs) {\n displaySpecTimeline(spec, startDate, endDate, weeks, specs);\n console.log('');\n }\n}\n\nfunction buildTimelineHeader(startDate: dayjs.Dayjs, weeks: number): string {\n const dates: string[] = [];\n for (let i = 0; i < weeks; i++) {\n const date = startDate.add(i, 'week');\n dates.push(date.format('MMM D').padEnd(8));\n }\n return dates.join(' ');\n}\n\nfunction displaySpecTimeline(\n spec: SpecInfo,\n startDate: dayjs.Dayjs,\n endDate: dayjs.Dayjs,\n weeks: number,\n allSpecs: SpecInfo[]\n): void {\n // Display spec name\n console.log(chalk.cyan(spec.path));\n\n // Show dependencies if any\n if (spec.frontmatter.depends_on && spec.frontmatter.depends_on.length > 0) {\n console.log(chalk.gray(` ↳ depends on: ${spec.frontmatter.depends_on.join(', ')}`));\n }\n\n // Build timeline bar\n const bar = buildTimelineBar(spec, startDate, endDate, weeks);\n console.log(bar);\n\n // Show metadata\n const meta: string[] = [];\n meta.push(getStatusLabel(spec.frontmatter.status));\n if (spec.frontmatter.due) {\n meta.push(`due: ${spec.frontmatter.due}`);\n }\n console.log(chalk.gray(` (${meta.join(', ')})`));\n}\n\nfunction buildTimelineBar(\n spec: SpecInfo,\n startDate: dayjs.Dayjs,\n endDate: dayjs.Dayjs,\n weeks: number\n): string {\n const charsPerWeek = 8;\n const totalChars = weeks * charsPerWeek;\n \n // Determine spec dates\n const created = dayjs(spec.frontmatter.created);\n const due = spec.frontmatter.due ? dayjs(spec.frontmatter.due) : null;\n const completed = spec.frontmatter.completed ? dayjs(spec.frontmatter.completed) : null;\n \n // If no due date and not started before timeline, estimate based on status\n let specStart = created;\n let specEnd = due || completed;\n \n // Default duration if no due date (2 weeks from creation)\n if (!specEnd && spec.frontmatter.status !== 'complete') {\n specEnd = created.add(2, 'week');\n }\n \n if (!specEnd) {\n // No timeline info, just show a marker at creation\n const daysFromStart = created.diff(startDate, 'day');\n const position = Math.floor((daysFromStart / 7) * charsPerWeek);\n \n if (position >= 0 && position < totalChars) {\n const bar = ' '.repeat(position) + '■' + ' '.repeat(totalChars - position - 1);\n return bar;\n }\n return ' '.repeat(totalChars);\n }\n \n // Calculate bar position and length\n const startDaysFromStart = specStart.diff(startDate, 'day');\n const endDaysFromStart = specEnd.diff(startDate, 'day');\n \n const startPos = Math.floor((startDaysFromStart / 7) * charsPerWeek);\n const endPos = Math.floor((endDaysFromStart / 7) * charsPerWeek);\n \n const barStart = Math.max(0, startPos);\n const barEnd = Math.min(totalChars, endPos);\n const barLength = Math.max(1, barEnd - barStart);\n \n // Build bar based on status\n let fillChar = '■';\n let emptyChar = '□';\n let color = chalk.blue;\n \n if (spec.frontmatter.status === 'complete') {\n fillChar = '■';\n color = chalk.green;\n } else if (spec.frontmatter.status === 'in-progress') {\n fillChar = '■';\n emptyChar = '□';\n color = chalk.yellow;\n \n // Show progress (half filled for in-progress)\n const halfLength = Math.floor(barLength / 2);\n const filled = fillChar.repeat(halfLength);\n const empty = emptyChar.repeat(barLength - halfLength);\n const bar = ' '.repeat(barStart) + color(filled + empty) + ' '.repeat(Math.max(0, totalChars - barEnd));\n return bar;\n } else {\n fillChar = '□';\n color = chalk.gray;\n }\n \n const bar = ' '.repeat(barStart) + color(fillChar.repeat(barLength)) + ' '.repeat(Math.max(0, totalChars - barEnd));\n return bar;\n}\n\nfunction getStatusLabel(status: string): string {\n switch (status) {\n case 'planned': return 'planned';\n case 'in-progress': return 'in-progress';\n case 'complete': return 'complete';\n case 'archived': return 'archived';\n default: return status;\n }\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","chalk","chalk","fs","path","chalk","chalk","fs","path","fs","path","stat","chalk","chalk","path","chalk","chalk","fs","path","chalk","chalk","stat","fs","path","chalk","fs","path","chalk","__dirname","chalk","projectName","fs","path","chalk","chalk","React","React","React","render","React","Box","Text","render","React","chalk","chalk","chalk","chalk","path","chalk","dayjs","dayjs","chalk","chalk","dayjs","chalk","dayjs","bar"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/utils/cli-helpers.ts"],"sourcesContent":["import { Command } from 'commander';\nimport {\n createSpec,\n archiveSpec,\n listSpecs,\n updateSpec,\n checkSpecs,\n backfillTimestamps,\n listTemplates,\n showTemplate,\n addTemplate,\n removeTemplate,\n copyTemplate,\n initProject,\n statsCommand,\n boardCommand,\n timelineCommand,\n depsCommand,\n searchCommand,\n ganttCommand,\n filesCommand,\n viewCommand,\n openCommand,\n validateCommand,\n mcpCommand,\n} from './commands/index.js';\nimport { parseCustomFieldOptions } from './utils/cli-helpers.js';\nimport type { SpecStatus, SpecPriority } from './frontmatter.js';\n\nconst program = new Command();\n\nprogram\n .name('lspec')\n .description('Manage LeanSpec documents')\n .version('0.1.0');\n\n// Add custom help text with grouped commands\nprogram.addHelpText('after', `\nCommand Groups:\n \n Core Commands:\n init Initialize LeanSpec in current directory\n create <name> Create new spec in folder structure\n list List all specs\n update <spec> Update spec metadata\n archive <spec> Move spec to archived/\n backfill [specs...] Backfill timestamps from git history\n \n Viewing & Navigation:\n view <spec> View spec content\n open <spec> Open spec in editor\n search <query> Full-text search with metadata filters\n files <spec> List files in a spec\n \n Project & Analytics:\n board Show Kanban-style board view\n stats Show aggregate statistics\n timeline Show creation/completion over time\n gantt Show timeline with dependencies\n deps <spec> Show dependency graph for a spec\n \n Maintenance:\n check Check for sequence conflicts\n validate [specs...] Validate specs for quality issues\n templates Manage spec templates\n \n Server:\n mcp Start MCP server for AI assistants\n\nExamples:\n $ lspec init\n $ lspec create my-feature --priority high\n $ lspec list --status in-progress\n $ lspec view 042\n $ lspec backfill --dry-run\n $ lspec board --tag backend\n $ lspec search \"authentication\"\n $ lspec validate\n $ lspec validate --verbose\n $ lspec validate --quiet --rule max-lines\n $ lspec validate 018 --max-lines 500\n`);\n\n// archive command\nprogram\n .command('archive <spec>')\n .description('Move spec to archived/')\n .action(async (specPath: string) => {\n await archiveSpec(specPath);\n });\n\n// backfill command\nprogram\n .command('backfill [specs...]')\n .description('Backfill timestamps from git history')\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 .action(async (specs: string[] | undefined, options: {\n dryRun?: boolean;\n force?: boolean;\n assignee?: boolean;\n transitions?: boolean;\n all?: 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 });\n });\n\n// board command\nprogram\n .command('board')\n .description('Show Kanban-style board view with project completion summary')\n .option('--complete', 'Include complete specs (default: hidden)')\n .option('--simple', 'Hide completion summary (kanban only)')\n .option('--completion-only', 'Show only completion summary (no kanban)')\n .option('--tag <tag>', 'Filter by tag')\n .option('--assignee <name>', 'Filter by assignee')\n .action(async (options: {\n showComplete?: boolean;\n simple?: boolean;\n completionOnly?: boolean;\n tag?: string;\n assignee?: string;\n }) => {\n await boardCommand(options);\n });\n\n// check command\nprogram\n .command('check')\n .description('Check for sequence conflicts')\n .option('-q, --quiet', 'Brief output')\n .action(async (options: {\n quiet?: boolean;\n }) => {\n const hasNoConflicts = await checkSpecs(options);\n // Exit with 0 (success) if no conflicts, 1 (error) if conflicts found\n process.exit(hasNoConflicts ? 0 : 1);\n });\n\n// validate command\nprogram\n .command('validate [specs...]')\n .description('Validate specs for quality issues')\n .option('--max-lines <number>', 'Custom line limit (default: 400)', parseInt)\n .option('--verbose', 'Show passing specs')\n .option('--quiet', 'Suppress warnings, only show errors')\n .option('--format <format>', 'Output format: default, json, compact', 'default')\n .option('--rule <rule>', 'Filter by specific rule name (e.g., max-lines, frontmatter)')\n .action(async (specs: string[] | undefined, options: {\n maxLines?: number;\n verbose?: boolean;\n quiet?: boolean;\n format?: 'default' | 'json' | 'compact';\n rule?: string;\n }) => {\n const passed = await validateCommand({\n maxLines: options.maxLines,\n specs: specs && specs.length > 0 ? specs : undefined,\n verbose: options.verbose,\n quiet: options.quiet,\n format: options.format,\n rule: options.rule,\n });\n // Exit with 0 (success) if all passed, 1 (error) if any failed\n process.exit(passed ? 0 : 1);\n });\n\n// create command\nprogram\n .command('create <name>')\n .description('Create new spec in folder structure')\n .option('--title <title>', 'Set custom title')\n .option('--description <desc>', 'Set initial description')\n .option('--tags <tags>', 'Set tags (comma-separated)')\n .option('--priority <priority>', 'Set priority (low, medium, high, critical)')\n .option('--assignee <name>', 'Set assignee')\n .option('--template <template>', 'Use a specific template')\n .option('--field <name=value...>', 'Set custom field (can specify multiple)')\n .option('--no-prefix', 'Skip date prefix even if configured')\n .action(async (name: string, options: {\n title?: string;\n description?: string;\n tags?: string;\n priority?: SpecPriority;\n assignee?: string;\n template?: string;\n field?: string[];\n prefix?: boolean;\n }) => {\n // Parse custom fields from --field options\n const customFields = parseCustomFieldOptions(options.field);\n \n const createOptions: {\n title?: string;\n description?: string;\n tags?: string[];\n priority?: SpecPriority;\n assignee?: string;\n template?: string;\n customFields?: Record<string, unknown>;\n noPrefix?: boolean;\n } = {\n title: options.title,\n description: options.description,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n priority: options.priority,\n assignee: options.assignee,\n template: options.template,\n customFields: Object.keys(customFields).length > 0 ? customFields : undefined,\n noPrefix: options.prefix === false,\n };\n await createSpec(name, createOptions);\n });\n\n// deps command\nprogram\n .command('deps <spec>')\n .description('Show dependency graph for a spec. Related specs (⟷) are shown bidirectionally, depends_on (→) are directional.')\n .option('--depth <n>', 'Show N levels deep (default: 3)', parseInt)\n .option('--graph', 'ASCII graph visualization')\n .option('--json', 'Output as JSON')\n .action(async (specPath: string, options: {\n depth?: number;\n graph?: boolean;\n json?: boolean;\n }) => {\n await depsCommand(specPath, options);\n });\n\n// files command\nprogram\n .command('files <spec>')\n .description('List files in a spec')\n .option('--type <type>', 'Filter by type: docs, assets')\n .option('--tree', 'Show tree structure')\n .action(async (specPath: string, options: {\n type?: 'docs' | 'assets';\n tree?: boolean;\n }) => {\n await filesCommand(specPath, options);\n });\n\n// gantt command\nprogram\n .command('gantt')\n .description('Show timeline with dependencies')\n .option('--weeks <n>', 'Show N weeks (default: 4)', parseInt)\n .option('--show-complete', 'Include completed specs')\n .option('--critical-path', 'Highlight critical path')\n .action(async (options: {\n weeks?: number;\n showComplete?: boolean;\n criticalPath?: boolean;\n }) => {\n await ganttCommand(options);\n });\n\n// init command\nprogram\n .command('init')\n .description('Initialize LeanSpec in current directory')\n .action(async () => {\n await initProject();\n });\n\n// list command\nprogram\n .command('list')\n .description('List all specs')\n .option('--archived', 'Include archived specs')\n .option('--status <status>', 'Filter by status (planned, in-progress, complete, archived)')\n .option('--tag <tag...>', 'Filter by tag (can specify multiple)')\n .option('--priority <priority>', 'Filter by priority (low, medium, high, critical)')\n .option('--assignee <name>', 'Filter by assignee')\n .option('--field <name=value...>', 'Filter by custom field (can specify multiple)')\n .option('--sort <field>', 'Sort by field (id, created, name, status, priority)', 'id')\n .option('--order <order>', 'Sort order (asc, desc)', 'desc')\n .action(async (options: {\n archived?: boolean;\n status?: SpecStatus;\n tag?: string[];\n priority?: SpecPriority;\n assignee?: string;\n field?: string[];\n sort?: string;\n order?: string;\n }) => {\n // Parse custom field filters from --field options\n const customFields = parseCustomFieldOptions(options.field);\n \n const listOptions: {\n showArchived?: boolean;\n status?: SpecStatus;\n tags?: string[];\n priority?: SpecPriority;\n assignee?: string;\n customFields?: Record<string, unknown>;\n sortBy?: string;\n sortOrder?: 'asc' | 'desc';\n } = {\n showArchived: options.archived,\n status: options.status,\n tags: options.tag,\n priority: options.priority,\n assignee: options.assignee,\n customFields: Object.keys(customFields).length > 0 ? customFields : undefined,\n sortBy: options.sort || 'id',\n sortOrder: (options.order as 'asc' | 'desc') || 'desc',\n };\n await listSpecs(listOptions);\n });\n\n// open command\nprogram\n .command('open <spec>')\n .description('Open spec in editor')\n .option('--editor <editor>', 'Specify editor command')\n .action(async (specPath: string, options: {\n editor?: string;\n }) => {\n try {\n await openCommand(specPath, {\n editor: options.editor,\n });\n } catch (error) {\n console.error('\\x1b[31mError:\\x1b[0m', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n });\n\n// search command\nprogram\n .command('search <query>')\n .description('Full-text search with metadata filters')\n .option('--status <status>', 'Filter by status')\n .option('--tag <tag>', 'Filter by tag')\n .option('--priority <priority>', 'Filter by priority')\n .option('--assignee <name>', 'Filter by assignee')\n .option('--field <name=value...>', 'Filter by custom field (can specify multiple)')\n .action(async (query: string, options: {\n status?: SpecStatus;\n tag?: string;\n priority?: SpecPriority;\n assignee?: string;\n field?: string[];\n }) => {\n // Parse custom field filters from --field options\n const customFields = parseCustomFieldOptions(options.field);\n \n await searchCommand(query, {\n status: options.status,\n tag: options.tag,\n priority: options.priority,\n assignee: options.assignee,\n customFields: Object.keys(customFields).length > 0 ? customFields : undefined,\n });\n });\n\n// stats command\nprogram\n .command('stats')\n .description('Show aggregate statistics (default: simplified view)')\n .option('--tag <tag>', 'Filter by tag')\n .option('--assignee <name>', 'Filter by assignee')\n .option('--full', 'Show full detailed analytics (all sections)')\n .option('--timeline', 'Show only timeline section')\n .option('--velocity', 'Show only velocity section')\n .option('--json', 'Output as JSON')\n .action(async (options: {\n tag?: string;\n assignee?: string;\n full?: boolean;\n timeline?: boolean;\n velocity?: boolean;\n json?: boolean;\n }) => {\n await statsCommand(options);\n });\n\n// templates command and subcommands\nconst templatesCmd = program\n .command('templates')\n .description('Manage spec templates');\n\ntemplatesCmd\n .command('list')\n .description('List available templates')\n .action(async () => {\n await listTemplates();\n });\n\ntemplatesCmd\n .command('show <name>')\n .description('Show template content')\n .action(async (name: string) => {\n await showTemplate(name);\n });\n\ntemplatesCmd\n .command('add <name> <file>')\n .description('Register a template')\n .action(async (name: string, file: string) => {\n await addTemplate(name, file);\n });\n\ntemplatesCmd\n .command('remove <name>')\n .description('Unregister a template')\n .action(async (name: string) => {\n await removeTemplate(name);\n });\n\ntemplatesCmd\n .command('copy <source> <target>')\n .description('Copy a template to create a new one')\n .action(async (source: string, target: string) => {\n await copyTemplate(source, target);\n });\n\n// Default action for templates (list)\ntemplatesCmd\n .action(async () => {\n await listTemplates();\n });\n\n// timeline command\nprogram\n .command('timeline')\n .description('Show creation/completion over time')\n .option('--days <n>', 'Show last N days (default: 30)', parseInt)\n .option('--by-tag', 'Group by tag')\n .option('--by-assignee', 'Group by assignee')\n .action(async (options: {\n days?: number;\n byTag?: boolean;\n byAssignee?: boolean;\n }) => {\n await timelineCommand(options);\n });\n\n// update command\nprogram\n .command('update <spec>')\n .description('Update spec metadata')\n .option('--status <status>', 'Set status (planned, in-progress, complete, archived)')\n .option('--priority <priority>', 'Set priority (low, medium, high, critical)')\n .option('--tags <tags>', 'Set tags (comma-separated)')\n .option('--assignee <name>', 'Set assignee')\n .option('--field <name=value...>', 'Set custom field (can specify multiple)')\n .action(async (specPath: string, options: {\n status?: SpecStatus;\n priority?: SpecPriority;\n tags?: string;\n assignee?: string;\n field?: string[];\n }) => {\n // Parse custom fields from --field options\n const customFields = parseCustomFieldOptions(options.field);\n \n const updates: {\n status?: SpecStatus;\n priority?: SpecPriority;\n tags?: string[];\n assignee?: string;\n customFields?: Record<string, unknown>;\n } = {\n status: options.status,\n priority: options.priority,\n tags: options.tags ? options.tags.split(',').map(t => t.trim()) : undefined,\n assignee: options.assignee,\n customFields: Object.keys(customFields).length > 0 ? customFields : undefined,\n };\n \n // Filter out undefined values\n Object.keys(updates).forEach(key => {\n if (updates[key as keyof typeof updates] === undefined) {\n delete updates[key as keyof typeof updates];\n }\n });\n \n if (Object.keys(updates).length === 0) {\n console.error('Error: At least one update option required (--status, --priority, --tags, --assignee, --field)');\n process.exit(1);\n }\n \n await updateSpec(specPath, updates);\n });\n\n// view command (primary viewer)\nprogram\n .command('view <spec>')\n .description('View spec content (supports sub-specs like \"045/DESIGN.md\")')\n .option('--raw', 'Output raw markdown (for piping/scripting)')\n .option('--json', 'Output as JSON')\n .option('--no-color', 'Disable colors')\n .action(async (specPath: string, options: {\n raw?: boolean;\n json?: boolean;\n color?: boolean;\n }) => {\n try {\n await viewCommand(specPath, {\n raw: options.raw,\n json: options.json,\n noColor: options.color === false,\n });\n } catch (error) {\n console.error('\\x1b[31mError:\\x1b[0m', error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n });\n\n// mcp command\nprogram\n .command('mcp')\n .description('Start MCP server for AI assistants (Claude Desktop, Cline, etc.)')\n .action(async () => {\n await mcpCommand();\n });\n\n// Parse and execute\nprogram.parse();\n","/**\n * Parse custom fields from CLI --field options\n * @param fieldOptions Array of \"name=value\" strings\n * @returns Record of parsed field names and values\n */\nexport function parseCustomFieldOptions(fieldOptions?: string[]): Record<string, unknown> {\n const customFields: Record<string, unknown> = {};\n \n if (!fieldOptions) {\n return customFields;\n }\n \n for (const field of fieldOptions) {\n const [key, ...valueParts] = field.split('=');\n if (key && valueParts.length > 0) {\n const value = valueParts.join('='); // Handle values with '=' in them\n customFields[key.trim()] = value.trim();\n }\n }\n \n return customFields;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,23 @@
1
+ import {
2
+ enrichWithTimestamps,
3
+ getSpecFile,
4
+ matchesFilter,
5
+ normalizeDateFields,
6
+ normalizeTagsField,
7
+ parseFrontmatter,
8
+ updateFrontmatter,
9
+ validateCustomField,
10
+ validateCustomFields
11
+ } from "./chunk-S4YNQ5KE.js";
12
+ export {
13
+ enrichWithTimestamps,
14
+ getSpecFile,
15
+ matchesFilter,
16
+ normalizeDateFields,
17
+ normalizeTagsField,
18
+ parseFrontmatter,
19
+ updateFrontmatter,
20
+ validateCustomField,
21
+ validateCustomFields
22
+ };
23
+ //# sourceMappingURL=frontmatter-26SOQGYM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createMcpServer
4
+ } from "./chunk-GLXYUS7F.js";
5
+ import "./chunk-S4YNQ5KE.js";
6
+ export {
7
+ createMcpServer
8
+ };
9
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lean-spec",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Lightweight spec methodology for AI-powered development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,12 +10,14 @@
10
10
  "build": "tsup",
11
11
  "dev": "tsup --watch",
12
12
  "typecheck": "tsc --noEmit",
13
- "lint": "eslint src",
14
13
  "format": "prettier --write .",
15
14
  "test": "pnpm test:run",
16
15
  "test:ui": "vitest --ui",
17
16
  "test:run": "vitest run",
18
- "test:coverage": "vitest run --coverage"
17
+ "test:coverage": "vitest run --coverage",
18
+ "docs:dev": "pnpm -F docs-site start",
19
+ "docs:build": "pnpm -F docs-site build",
20
+ "docs:serve": "pnpm -F docs-site serve"
19
21
  },
20
22
  "keywords": [
21
23
  "spec",
@@ -31,7 +33,7 @@
31
33
  "type": "git",
32
34
  "url": "https://github.com/codervisor/lean-spec.git"
33
35
  },
34
- "homepage": "https://github.com/codervisor/lean-spec#readme",
36
+ "homepage": "https://lean-spec.dev",
35
37
  "bugs": {
36
38
  "url": "https://github.com/codervisor/lean-spec/issues"
37
39
  },
@@ -44,13 +46,12 @@
44
46
  "CHANGELOG.md"
45
47
  ],
46
48
  "devDependencies": {
49
+ "@types/js-yaml": "^4.0.9",
50
+ "@types/marked-terminal": "^6.1.1",
47
51
  "@types/node": "^20.10.0",
48
52
  "@types/react": "^19.2.2",
49
- "@typescript-eslint/eslint-plugin": "^6.15.0",
50
- "@typescript-eslint/parser": "^6.15.0",
51
53
  "@vitest/coverage-v8": "^4.0.6",
52
54
  "@vitest/ui": "^4.0.6",
53
- "eslint": "^8.56.0",
54
55
  "prettier": "^3.1.1",
55
56
  "tsup": "^8.0.1",
56
57
  "typescript": "^5.3.3",
@@ -58,6 +59,7 @@
58
59
  },
59
60
  "dependencies": {
60
61
  "@inquirer/prompts": "^7.9.0",
62
+ "@modelcontextprotocol/sdk": "^1.21.0",
61
63
  "chalk": "^5.3.0",
62
64
  "cli-spinners": "^3.3.0",
63
65
  "cli-table3": "^0.6.5",
@@ -65,8 +67,20 @@
65
67
  "dayjs": "^1.11.19",
66
68
  "gray-matter": "^4.0.3",
67
69
  "ink": "^6.4.0",
70
+ "ink-box": "^2.0.0",
71
+ "ink-gradient": "^3.0.0",
72
+ "ink-progress-bar": "^3.0.0",
73
+ "ink-select-input": "^6.2.0",
74
+ "ink-spinner": "^5.0.0",
75
+ "ink-table": "^3.1.0",
76
+ "ink-text-input": "^6.0.0",
77
+ "js-yaml": "^4.1.0",
78
+ "marked": "^15.0.12",
79
+ "marked-terminal": "^7.3.0",
68
80
  "ora": "^9.0.0",
69
- "react": "^19.2.0"
81
+ "react": "^19.2.0",
82
+ "strip-ansi": "^7.1.2",
83
+ "zod": "^3.25.76"
70
84
  },
71
85
  "engines": {
72
86
  "node": ">=18"
@@ -5,7 +5,8 @@
5
5
  "template": "enterprise",
6
6
  "specsDir": "specs",
7
7
  "structure": {
8
- "pattern": "{date}/{seq}-{name}/",
8
+ "pattern": "flat",
9
+ "prefix": "",
9
10
  "dateFormat": "YYYYMMDD",
10
11
  "sequenceDigits": 3,
11
12
  "defaultFile": "README.md"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  status: planned
3
- created: {date}
3
+ created: '{date}'
4
4
  tags: []
5
5
  priority: medium
6
6
  assignee:
@@ -12,8 +12,8 @@ epic:
12
12
 
13
13
  # {name}
14
14
 
15
- > **Status**: 📅 Planned · **Priority**: Medium · **Created**: {date}
16
- > **Assignee**: TBD · **Reviewer**: TBD
15
+ > **Status**: {status} · **Priority**: {priority} · **Created**: {date}
16
+ > **Assignee**: {assignee} · **Reviewer**: {reviewer}
17
17
 
18
18
  ## Overview
19
19
 
@@ -43,6 +43,11 @@ epic:
43
43
 
44
44
  <!-- Break into phases if needed -->
45
45
 
46
+ <!-- 💡 TIP: If your plan has >6 phases or this spec approaches
47
+ 400 lines, consider using sub-spec files:
48
+ - IMPLEMENTATION.md for detailed implementation
49
+ - See spec 012-sub-spec-files for guidance on splitting -->
50
+
46
51
  - [ ] Task 1 - @owner
47
52
  - [ ] Task 2 - @owner
48
53
  - [ ] Task 3 - @owner