speckeeper 0.8.1 → 0.9.0

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/utils/config-loader.ts","../src/utils/file-writer.ts","../src/core/relation.ts","../src/core/model.ts","../src/cli/build.ts","../src/cli/lint.ts","../src/cli/drift.ts","../src/cli/check.ts","../src/cli/new.ts","../src/cli/impact.ts","../src/cli/init.ts","../src/scaffold/mermaid-parser.ts","../src/scaffold/edge-vocabulary.ts","../src/scaffold/template-registry.ts","../src/scaffold/artifact-defaults.ts","../src/scaffold/templates/base.ts","../src/scaffold/templates/index.ts","../src/scaffold/model-generator.ts","../src/scaffold/index-generator.ts","../src/cli/scaffold.ts","../src/cli/index.ts"],"names":["parseYaml","existsSync","dirname","readFileSync","chalk","join","models","model","writeFileSync","__filename","__dirname","mkdirSync","SPECKEEPER_CLASS","resolve","fileURLToPath"],"mappings":"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","file":"cli.js","sourcesContent":["import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Specification-compliant output path definitions\n * \n * Human-readable artifacts (docs/):\n * requirements/ - Requirements Markdown\n * usecases/ - Use cases\n * architecture/ - Architecture (C4 diagrams)\n * data-model/ - Conceptual model (ER diagrams)\n * screens/ - Screen specifications\n * flows/ - Process flows\n * glossary/ - Glossary\n * \n * Machine-readable artifacts (specs/):\n * schemas/entities/ - Entity JSON Schema\n * index.json - Aggregated data\n */\nexport interface OutputPaths {\n // docs/ subdirectories\n requirements: string;\n usecases: string;\n architecture: string;\n dataModel: string;\n screens: string;\n flows: string;\n glossary: string;\n component: string;\n \n // specs/ subdirectories\n schemasEntities: string;\n}\n\nexport interface SpeckeeperConfig {\n // Project info\n projectName?: string;\n version?: string;\n \n // Source paths\n srcDir: string;\n requirementsDir?: string;\n designDir?: string;\n usecasesDir?: string;\n \n // Output paths\n docsDir: string;\n specsDir: string;\n \n // External SSOT paths\n externalSsot?: {\n openapi?: {\n enabled: boolean;\n paths: string[];\n microContracts?: {\n enabled: boolean;\n requiredExtensions?: string[];\n strictMode?: boolean;\n };\n };\n ddl?: {\n enabled: boolean;\n paths: string[];\n type: 'ddl' | 'prisma' | 'typeorm' | 'drizzle';\n };\n iac?: {\n enabled: boolean;\n paths: string[];\n type: 'cloudformation' | 'terraform' | 'cdk';\n };\n };\n \n // Lint configuration\n lint?: {\n architecture?: {\n allowCrossBoundaryDependencies?: boolean;\n allowCrossLayerViolations?: boolean;\n maxComponentsPerDiagram?: number;\n };\n conceptModel?: {\n requireEntityDescription?: boolean;\n requireAggregateRoot?: boolean;\n warnOnOrphanEntities?: boolean;\n namingConvention?: 'PascalCase' | 'camelCase' | 'snake_case' | 'none';\n };\n screen?: {\n warnOnOrphanScreens?: boolean;\n warnOnDeadEnds?: boolean;\n checkAuthPaths?: boolean;\n };\n phaseGate?: {\n currentPhase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strictMode?: boolean;\n };\n };\n \n // Build configuration\n build?: {\n generateMermaidImages?: boolean;\n mermaidCliPath?: string;\n };\n \n // Custom model definitions\n models?: unknown[];\n \n // Spec data entries (from design/index.ts via mergeSpecs())\n specs?: import('../core/model.js').SpecEntry[];\n}\n\n// Default configuration\nconst defaultConfig: SpeckeeperConfig = {\n srcDir: 'src',\n designDir: 'design', // Directory for requirements/design TS models\n docsDir: 'docs',\n specsDir: 'specs',\n};\n\n// ============================================================================\n// Output Paths (spec-compliant)\n// ============================================================================\n\n/**\n * Get output paths compliant with specification\n */\nexport function getOutputPaths(config: SpeckeeperConfig, cwd: string = process.cwd()): OutputPaths {\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n return {\n // docs/ subdirectories (compliant with spec section 7.1)\n requirements: join(docsDir, 'requirements'),\n usecases: join(docsDir, 'usecases'),\n architecture: join(docsDir, 'architecture'),\n dataModel: join(docsDir, 'data-model'),\n screens: join(docsDir, 'screens'),\n flows: join(docsDir, 'flows'),\n glossary: join(docsDir, 'glossary'),\n component: join(docsDir, 'component'),\n \n // specs/ subdirectories (compliant with spec section 7.1)\n schemasEntities: join(specsDir, 'schemas', 'entities'),\n };\n}\n\n/**\n * List of expected output paths (for drift check)\n */\nexport function getExpectedOutputDirs(config: SpeckeeperConfig, cwd: string = process.cwd()): string[] {\n const paths = getOutputPaths(config, cwd);\n return [\n paths.requirements,\n paths.usecases,\n paths.architecture,\n paths.dataModel,\n paths.screens,\n paths.flows,\n paths.glossary,\n paths.component,\n paths.schemasEntities,\n ];\n}\n\n/**\n * Validate if output path complies with specification\n */\nexport function validateOutputPaths(actualPath: string, config: SpeckeeperConfig, cwd: string = process.cwd()): {\n valid: boolean;\n expectedPaths: string[];\n message?: string;\n} {\n const expectedDirs = getExpectedOutputDirs(config, cwd);\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n // Check if actualPath is under docs/ or specs/\n const isUnderDocs = actualPath.startsWith(docsDir);\n const isUnderSpecs = actualPath.startsWith(specsDir);\n \n if (!isUnderDocs && !isUnderSpecs) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" is not under docs/ or specs/`,\n };\n }\n \n // Check if under any of the expected paths\n const isValidPath = expectedDirs.some(dir => actualPath.startsWith(dir));\n \n if (!isValidPath) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" does not match spec-compliant paths. Expected one of: ${expectedDirs.map(d => d.replace(cwd + '/', '')).join(', ')}`,\n };\n }\n \n return { valid: true, expectedPaths: expectedDirs };\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nconst CONFIG_FILES = [\n 'speckeeper.config.yaml',\n 'speckeeper.config.yml',\n 'speckeeper.config.json',\n 'speckeeper.config.ts',\n 'speckeeper.config.js',\n];\n\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n \n while (currentDir !== dirname(currentDir)) {\n for (const configFile of CONFIG_FILES) {\n const configPath = resolve(currentDir, configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n \n return null;\n}\n\nexport async function loadConfig(\n configPath?: string,\n cwd: string = process.cwd()\n): Promise<SpeckeeperConfig> {\n const resolvedPath = configPath ?? findConfigFile(cwd);\n \n if (!resolvedPath) {\n return { ...defaultConfig };\n }\n \n const ext = resolvedPath.split('.').pop()?.toLowerCase();\n \n try {\n if (ext === 'yaml' || ext === 'yml') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = parseYaml(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'json') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'ts' || ext === 'js') {\n const module = await import(resolvedPath);\n const parsed = module.default ?? module;\n return { ...defaultConfig, ...parsed };\n }\n \n return { ...defaultConfig };\n } catch (error) {\n console.error(`Failed to load config from ${resolvedPath}:`, error);\n return { ...defaultConfig };\n }\n}\n\n// ============================================================================\n// Configuration Validation\n// ============================================================================\n\nexport function validateConfig(config: SpeckeeperConfig): string[] {\n const errors: string[] = [];\n \n if (!config.srcDir) {\n errors.push('srcDir is required');\n }\n \n if (!config.docsDir) {\n errors.push('docsDir is required');\n }\n \n if (!config.specsDir) {\n errors.push('specsDir is required');\n }\n \n return errors;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createHash } from 'node:crypto';\n\n// ============================================================================\n// File Writing\n// ============================================================================\n\nexport interface WriteResult {\n path: string;\n created: boolean;\n updated: boolean;\n unchanged: boolean;\n}\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\nexport function writeFile(filePath: string, content: string): WriteResult {\n const dir = dirname(filePath);\n ensureDir(dir);\n \n const existed = existsSync(filePath);\n let unchanged = false;\n \n if (existed) {\n const existingContent = readFileSync(filePath, 'utf-8');\n unchanged = existingContent === content;\n }\n \n if (!unchanged) {\n writeFileSync(filePath, content, 'utf-8');\n }\n \n return {\n path: filePath,\n created: !existed,\n updated: existed && !unchanged,\n unchanged,\n };\n}\n\nexport function writeJsonFile(filePath: string, data: unknown, indent: number = 2): WriteResult {\n const content = JSON.stringify(data, null, indent) + '\\n';\n return writeFile(filePath, content);\n}\n\n// ============================================================================\n// Batch Writing\n// ============================================================================\n\nexport interface BatchWriteResult {\n results: WriteResult[];\n created: number;\n updated: number;\n unchanged: number;\n total: number;\n}\n\nexport function batchWriteFiles(\n files: Array<{ path: string; content: string }>\n): BatchWriteResult {\n const results: WriteResult[] = [];\n \n for (const { path, content } of files) {\n results.push(writeFile(path, content));\n }\n \n return {\n results,\n created: results.filter(r => r.created).length,\n updated: results.filter(r => r.updated).length,\n unchanged: results.filter(r => r.unchanged).length,\n total: results.length,\n };\n}\n\n// ============================================================================\n// Drift Detection\n// ============================================================================\n\nexport interface DriftResult {\n file: string;\n hasDrift: boolean;\n expectedHash?: string;\n actualHash?: string;\n missing?: boolean;\n}\n\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function checkFileDrift(\n filePath: string,\n expectedContent: string\n): DriftResult {\n const expectedHash = computeHash(expectedContent);\n \n if (!existsSync(filePath)) {\n return {\n file: filePath,\n hasDrift: true,\n expectedHash,\n missing: true,\n };\n }\n \n const actualContent = readFileSync(filePath, 'utf-8');\n const actualHash = computeHash(actualContent);\n \n return {\n file: filePath,\n hasDrift: expectedHash !== actualHash,\n expectedHash,\n actualHash,\n };\n}\n\nexport function checkBatchDrift(\n files: Array<{ path: string; content: string }>\n): DriftResult[] {\n return files.map(({ path, content }) => checkFileDrift(path, content));\n}\n\n// ============================================================================\n// File Discovery\n// ============================================================================\n\nimport { glob } from 'glob';\n\nexport async function findFiles(\n pattern: string,\n cwd: string = process.cwd()\n): Promise<string[]> {\n return glob(pattern, { cwd, absolute: true });\n}\n\nexport async function findTypeScriptFiles(\n srcDir: string\n): Promise<string[]> {\n return findFiles('**/*.ts', srcDir);\n}\n\nexport async function findDefinitionFiles(\n srcDir: string,\n subDir: string\n): Promise<string[]> {\n const pattern = join(srcDir, subDir, '**/*.ts');\n return glob(pattern, { absolute: true, ignore: ['**/*.d.ts', '**/index.ts'] });\n}\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\nexport function generateDocsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n\nexport function generateSpecsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n","/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'verifiedBy',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // Spec→Test (verification relationship: spec is verified by test code)\n 'verifiedBy': {\n allowedTargetLevels: ['L2', 'L3'],\n levelRule: 'any',\n propagation: 'backward',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Model base class\n * \n * All model definitions inherit from this class\n */\nimport { z, ZodType } from 'zod';\nimport {\n type ModelLevel,\n type Relation,\n type RelationValidationError,\n validateRelationLevel,\n detectCycles,\n inferModelIdFromSpecId,\n} from './relation.js';\n\n// Re-export relation types\nexport type { ModelLevel, Relation, RelationValidationError };\nexport { RELATION_TYPES, RELATION_CONSTRAINTS, RelationSchema, RelationsFieldSchema } from './relation.js';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Lint rule definition\n */\nexport interface LintRule<T> {\n id: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n check: (spec: T) => boolean; // true if there is an issue\n}\n\n/**\n * Lint result\n */\nexport interface LintResult {\n ruleId: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n specId?: string;\n}\n\n/**\n * Exporter definition\n */\nexport interface Exporter<T> {\n format: 'markdown' | 'json' | 'mermaid';\n single?: (spec: T) => string;\n index?: (specs: T[]) => string;\n /** Subdirectory under docsDir (used with single + index/index.md) */\n outputDir?: string;\n /** Direct output file path relative to docsDir (used with index-only exporters) */\n outputFile?: string;\n filename?: (spec: T) => string;\n}\n\n/**\n * External checker definition\n */\nexport interface ExternalChecker<T> {\n targetType: string; // 'openapi' | 'ddl' | 'cli' etc.\n sourcePath: (spec: T) => string;\n check: (spec: T, externalData: unknown) => CheckResult;\n}\n\n/**\n * Check result\n */\nexport interface CheckResult {\n success: boolean;\n errors: { message: string; field?: string; specId?: string }[];\n warnings: { message: string; field?: string; specId?: string }[];\n /** Files where annotations matching this spec were found */\n matchedFiles?: Array<{\n specId: string;\n filePath: string;\n line: number;\n relationType: 'verifiedBy' | 'implements' | 'traces';\n }>;\n}\n\n/**\n * Coverage result\n */\nexport interface CoverageResult {\n /** Total target count */\n total: number;\n /** Covered count */\n covered: number;\n /** Uncovered count */\n uncovered: number;\n /** Coverage rate (%) */\n coveragePercent: number;\n /** Details of covered items */\n coveredItems: { id: string; description?: string }[];\n /** Details of uncovered items */\n uncoveredItems: { id: string; description?: string; sourceId?: string }[];\n}\n\n/**\n * Coverage checker definition\n * \n * Verify cross-model consistency (coverage).\n * Example: Whether TestRef covers acceptanceCriteria of Requirement\n */\nexport interface CoverageChecker<T> {\n /** Target model ID for coverage (e.g. 'requirement') */\n targetModel: string;\n /** Description of coverage check */\n description: string;\n /** Execute coverage check */\n check: (\n specs: T[],\n registry: Record<string, Map<string, unknown>>\n ) => CoverageResult;\n}\n\n// ============================================================================\n// Renderer (for embeds)\n// ============================================================================\n\n/**\n * Render context\n * Simplified version compatible with embedoc's EmbedContext\n */\nexport interface RenderContext {\n /** Parameters (filter conditions other than format, etc.) */\n params: Record<string, string | undefined>;\n /** Markdown helpers */\n markdown: {\n /** Generate table */\n table: (headers: string[], rows: (string | unknown)[][]) => string;\n };\n}\n\n/**\n * Renderer definition\n * \n * Model-specific rendering called from embeds\n */\nexport interface Renderer<T> {\n /** Format ID ('table', 'list', 'detail', 'spec-chapter', etc.) */\n format: string;\n /** Rendering process */\n render: (specs: T[], ctx: RenderContext) => string;\n}\n\n// ============================================================================\n// Model Base Class\n// ============================================================================\n\n/**\n * Model base class\n * \n * @template TSchema - Zod schema type\n */\nexport abstract class Model<TSchema extends ZodType> {\n /** Singleton instance storage (per subclass) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static _instances: WeakMap<new () => any, Model<ZodType>> = new WeakMap();\n\n /**\n * Get singleton instance of the model\n * Usage: RequirementModel.instance\n */\n static get instance(): Model<ZodType> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctor = this as unknown as new () => any;\n if (!this._instances.has(ctor)) {\n this._instances.set(ctor, new ctor());\n }\n return this._instances.get(ctor)!;\n }\n\n /** Model ID ('requirement', 'usecase', etc.) */\n abstract readonly id: string;\n \n /** Model name ('Requirement', 'UseCase', etc.) */\n abstract readonly name: string;\n \n /** ID prefix ('REQ', 'UC', etc.) */\n abstract readonly idPrefix: string;\n \n /** Zod schema */\n abstract readonly schema: TSchema;\n \n /** Model description (optional) */\n readonly description?: string;\n \n /** External SSOT type (optional, e.g. 'OpenAPI', 'DDL/Prisma') */\n readonly externalSsotType?: string;\n \n /** Spec instance type */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected get specType(): z.infer<TSchema> { return undefined as any; }\n \n /** Lint rules (override in subclass) */\n protected lintRules: LintRule<z.infer<TSchema>>[] = [];\n \n /** Exporters (override in subclass) */\n protected exporters: Exporter<z.infer<TSchema>>[] = [];\n \n /** External checker (optional) */\n protected externalChecker?: ExternalChecker<z.infer<TSchema>>;\n \n /** Coverage checker (optional) */\n protected coverageChecker?: CoverageChecker<z.infer<TSchema>>;\n \n /** Model level (set in _models/) */\n protected modelLevel?: ModelLevel;\n \n /** Renderers (for embeds, override in subclass) */\n protected renderers: Renderer<z.infer<TSchema>>[] = [];\n \n /**\n * Get model level\n * Returns modelLevel set in _models/\n */\n get level(): ModelLevel | undefined {\n return this.modelLevel;\n }\n \n /**\n * Execute schema validation\n */\n validate(spec: unknown): z.infer<TSchema> {\n return this.schema.parse(spec);\n }\n \n /**\n * Schema validation (safe version, returns error object on failure)\n */\n safeParse(spec: unknown): { success: true; data: z.infer<TSchema> } | { success: false; error: z.ZodError } {\n return this.schema.safeParse(spec);\n }\n \n /**\n * Execute lint\n */\n lint(spec: z.infer<TSchema>): LintResult[] {\n const specId = (spec as { id?: string }).id;\n return this.lintRules\n .filter(rule => rule.check(spec))\n .map(rule => ({\n ruleId: rule.id,\n severity: rule.severity,\n message: rule.message,\n specId,\n }));\n }\n \n /**\n * Execute lint for multiple specs\n */\n lintAll(specs: z.infer<TSchema>[]): LintResult[] {\n return specs.flatMap(spec => this.lint(spec));\n }\n \n /**\n * Validate level constraints of relations\n * @param spec - Spec instance (if it has relations property)\n * @returns Array of validation errors\n */\n validateRelations(spec: z.infer<TSchema>): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n \n if (!specWithRelations.relations || !specWithRelations.id) {\n return errors;\n }\n \n // Get all models to retrieve target model levels\n const allModels = getAllModels();\n const modelLevelMap = new Map<string, ModelLevel | undefined>();\n for (const model of allModels) {\n modelLevelMap.set(model.id, model.level);\n }\n \n for (const relation of specWithRelations.relations) {\n // Infer target model ID\n const targetModelId = inferModelIdFromSpecId(relation.target);\n if (!targetModelId) {\n continue; // Skip if model ID cannot be inferred\n }\n \n const targetLevel = modelLevelMap.get(targetModelId);\n \n const error = validateRelationLevel(\n this.level,\n specWithRelations.id,\n relation,\n targetLevel,\n );\n \n if (error) {\n errors.push(error);\n }\n }\n \n return errors;\n }\n \n /**\n * Validate relations of multiple specs (including circular reference check)\n */\n validateAllRelations(specs: z.infer<TSchema>[]): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const allRelations: Array<{ sourceId: string; targetId: string; type: string }> = [];\n \n for (const spec of specs) {\n // Individual level constraint check\n errors.push(...this.validateRelations(spec));\n \n // Collect relations for circular reference check\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n if (specWithRelations.relations && specWithRelations.id) {\n for (const rel of specWithRelations.relations) {\n allRelations.push({\n sourceId: specWithRelations.id,\n targetId: rel.target,\n type: rel.type,\n });\n }\n }\n }\n \n // Circular reference check\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errors.push(...detectCycles(allRelations as any));\n \n return errors;\n }\n \n /**\n * Export in specified format (single spec)\n */\n exportSingle(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.single) return null;\n return exporter.single(spec);\n }\n \n /**\n * Export in specified format (index)\n */\n exportIndex(specs: z.infer<TSchema>[], format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.index) return null;\n return exporter.index(specs);\n }\n \n /**\n * Get exporter output directory\n */\n getOutputDir(format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n return exporter?.outputDir ?? null;\n }\n \n /**\n * Get filename\n */\n getFilename(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.filename) return null;\n return exporter.filename(spec);\n }\n \n /**\n * Check consistency with external SSOT\n */\n check(spec: z.infer<TSchema>, externalData: unknown): CheckResult {\n if (!this.externalChecker) {\n return { success: true, errors: [], warnings: [] };\n }\n return this.externalChecker.check(spec, externalData);\n }\n \n /**\n * Get external SSOT path\n */\n getExternalSourcePath(spec: z.infer<TSchema>): string | null {\n if (!this.externalChecker) return null;\n return this.externalChecker.sourcePath(spec);\n }\n \n /**\n * Execute coverage check\n * @param specs - Array of spec instances for this model\n * @param registry - Registry of all models\n */\n checkCoverage(\n specs: z.infer<TSchema>[],\n registry: Record<string, Map<string, unknown>>\n ): CoverageResult | null {\n if (!this.coverageChecker) return null;\n return this.coverageChecker.check(specs, registry);\n }\n \n /**\n * Get coverage checker\n */\n getCoverageChecker(): CoverageChecker<z.infer<TSchema>> | undefined {\n return this.coverageChecker;\n }\n \n /**\n * Get lint rules\n */\n getLintRules(): LintRule<z.infer<TSchema>>[] {\n return this.lintRules;\n }\n \n /**\n * Get exporters\n */\n getExporters(): Exporter<z.infer<TSchema>>[] {\n return this.exporters;\n }\n \n // ============================================================================\n // Renderer (for embeds)\n // ============================================================================\n \n /**\n * Render in specified format\n * @param format - Format ID ('table', 'list', 'detail', etc.)\n * @param specs - Array of specs to render\n * @param ctx - Render context\n * @returns Rendered result (Markdown string), null if no matching renderer\n */\n render(format: string, specs: z.infer<TSchema>[], ctx: RenderContext): string | null {\n const renderer = this.renderers.find(r => r.format === format);\n if (!renderer) return null;\n return renderer.render(specs, ctx);\n }\n \n /**\n * Get list of available formats\n */\n getAvailableFormats(): string[] {\n return this.renderers.map(r => r.format);\n }\n \n /**\n * Get renderers\n */\n getRenderers(): Renderer<z.infer<TSchema>>[] {\n return this.renderers;\n }\n \n /**\n * Check if renderer exists for specific format\n */\n hasRenderer(format: string): boolean {\n return this.renderers.some(r => r.format === format);\n }\n \n /**\n * Register spec instances for this model.\n * Stores specs in the global specStore keyed by this model's id.\n */\n register(specs: z.infer<TSchema>[]): void {\n if (!specStore.has(this.id)) {\n specStore.set(this.id, new Map());\n }\n const map = specStore.get(this.id)!;\n for (const spec of specs) {\n map.set((spec as { id: string }).id, spec);\n }\n }\n}\n\n// ============================================================================\n// Spec Store\n// ============================================================================\n\nconst specStore = new Map<string, Map<string, unknown>>();\n\n/**\n * Get the global spec store (model ID → spec ID → spec data)\n */\nexport function getSpecStore(): Map<string, Map<string, unknown>> {\n return specStore;\n}\n\n/**\n * Reset the spec store (clears all registered specs)\n */\nexport function resetSpecStore(): void {\n specStore.clear();\n}\n\n// ============================================================================\n// Model Registry\n// ============================================================================\n\n/** Map of registered models */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modelRegistry = new Map<string, Model<any>>();\n\n/**\n * Register model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerModel(model: Model<any>): void {\n modelRegistry.set(model.id, model);\n}\n\n/**\n * Get model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getModel(id: string): Model<any> | undefined {\n return modelRegistry.get(id);\n}\n\n/**\n * Get all registered models\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getAllModels(): Model<any>[] {\n return Array.from(modelRegistry.values());\n}\n\n/**\n * Clear registry\n */\nexport function clearModelRegistry(): void {\n modelRegistry.clear();\n}\n\n/**\n * Register model instances from config.models array.\n * Filters out non-Model values. Call this once after config is loaded.\n */\nexport function registerModelsFromConfig(models: unknown[]): void {\n for (const model of models) {\n if (model && typeof model === 'object' && 'id' in model && 'schema' in model) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n registerModel(model as Model<any>);\n }\n }\n}\n\n/**\n * Get specs for a given model ID from specStore\n */\nexport function getSpecs(modelId: string): unknown[] {\n const map = specStore.get(modelId);\n if (!map) return [];\n return Array.from(map.values());\n}\n\n/**\n * Get all spec IDs across all models\n */\nexport function getAllSpecIds(): Set<string> {\n const ids = new Set<string>();\n for (const map of specStore.values()) {\n for (const id of map.keys()) {\n ids.add(id);\n }\n }\n return ids;\n}\n\n/**\n * Find which model type a spec ID belongs to\n */\nexport function findModelTypeBySpecId(specId: string): string | null {\n for (const [modelId, map] of specStore) {\n if (map.has(specId)) return modelId;\n }\n return null;\n}\n\n/**\n * Get a spec by ID (searches all models)\n */\nexport function getSpecById(specId: string): { modelId: string; spec: unknown } | null {\n const modelId = findModelTypeBySpecId(specId);\n if (!modelId) return null;\n return { modelId, spec: specStore.get(modelId)!.get(specId) };\n}\n\n// ============================================================================\n// SpecModule: Common interface for spec data files\n// ============================================================================\n\n/**\n * A single (Model, data[]) pair.\n * Uses structural typing (not nominal Model<any>) so that\n * compiled dist/ Model instances are compatible with src/ types.\n */\nexport interface SpecEntry {\n model: { id: string; register: (data: unknown[]) => void };\n data: unknown[];\n}\n\n/**\n * Common export interface for spec data files.\n * Each spec file exports a SpecModule via defineSpecs().\n */\nexport interface SpecModule {\n entries: SpecEntry[];\n}\n\n/**\n * Aggregated result from mergeSpecs().\n */\nexport interface MergedDesign {\n models: SpecEntry['model'][];\n specs: SpecEntry[];\n}\n\n/**\n * Define spec data in a spec file. Returns a SpecModule.\n *\n * @example\n * ```typescript\n * export default defineSpecs(\n * [FunctionalRequirementModel.instance, functionalRequirements],\n * [NonFunctionalRequirementModel.instance, nonFunctionalRequirements],\n * );\n * ```\n */\nexport function defineSpecs(...entries: [SpecEntry['model'], unknown[]][]): SpecModule {\n return {\n entries: entries.map(([model, data]) => ({ model, data })),\n };\n}\n\n/**\n * Merge multiple SpecModules into a single MergedDesign.\n * Models are deduplicated by model.id.\n *\n * @example\n * ```typescript\n * // design/index.ts\n * export default mergeSpecs(requirements, usecases, glossary);\n * ```\n */\nexport function mergeSpecs(...modules: SpecModule[]): MergedDesign {\n const modelMap = new Map<string, SpecEntry['model']>();\n const allSpecs: SpecEntry[] = [];\n\n for (const mod of modules) {\n for (const entry of mod.entries) {\n modelMap.set(entry.model.id, entry.model);\n allSpecs.push(entry);\n }\n }\n\n return {\n models: Array.from(modelMap.values()),\n specs: allSpecs,\n };\n}\n\n/**\n * Build a registry (modelId -> Map<specId, spec>) from config.specs.\n * Pure function — no global state.\n */\nexport function buildRegistryFromConfig(\n specs: SpecEntry[] | undefined\n): Record<string, Map<string, unknown>> {\n const registry: Record<string, Map<string, unknown>> = {};\n if (!specs) return registry;\n for (const entry of specs) {\n if (!registry[entry.model.id]) {\n registry[entry.model.id] = new Map();\n }\n const map = registry[entry.model.id];\n for (const spec of entry.data) {\n map.set((spec as { id: string }).id, spec);\n }\n }\n return registry;\n}\n\n/**\n * Get specs for a model ID from config.specs.\n * Pure function — no global state.\n */\nexport function getSpecsFromConfig(\n specs: SpecEntry[] | undefined,\n modelId: string\n): unknown[] {\n if (!specs) return [];\n return specs\n .filter(e => e.model.id === modelId)\n .flatMap(e => e.data);\n}\n\n/**\n * Find which model type a spec ID belongs to, from config.specs.\n * Pure function — no global state.\n */\nexport function findModelTypeFromConfig(\n specs: SpecEntry[] | undefined,\n specId: string\n): string | null {\n if (!specs) return null;\n for (const entry of specs) {\n for (const spec of entry.data) {\n if ((spec as { id: string }).id === specId) {\n return entry.model.id;\n }\n }\n }\n return null;\n}\n","/**\n * Build Command\n * \n * Generate documents and schemas using model class exporters\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { batchWriteFiles, ensureDir } from '../utils/file-writer.js';\nimport { getSpecsFromConfig } from '../core/model.js';\n\n// ============================================================================\n// Build Command Options\n// ============================================================================\n\nexport interface BuildCommandOptions {\n config?: string;\n output?: string;\n format?: 'markdown' | 'json' | 'both';\n verbose?: boolean;\n clean?: boolean;\n}\n\n// ============================================================================\n// Build Command\n// ============================================================================\n\nexport async function buildCommand(options: BuildCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper build'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log(chalk.gray(` Specs: ${config.specsDir}/`));\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n ensureDir(join(cwd, config.docsDir));\n ensureDir(join(cwd, config.specsDir));\n \n const files: Array<{ path: string; content: string }> = [];\n \n if (models.length === 0) {\n console.log(chalk.yellow(' No models registered. Add models to speckeeper.config.ts.'));\n return;\n }\n \n console.log(chalk.blue(` Processing ${models.length} model types...`));\n \n for (const model of models) {\n const exporters = model.getExporters();\n \n if (exporters.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no exporters defined`));\n }\n continue;\n }\n \n const modelSpecs = getSpecsFromConfig(specs, model.id);\n \n if (modelSpecs.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no specs found`));\n }\n continue;\n }\n \n for (const exporter of exporters) {\n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n if (exporter.single) {\n ensureDir(outputDir);\n }\n \n if (exporter.single) {\n for (const spec of modelSpecs) {\n const content = exporter.single(spec);\n const filename = model.getFilename(spec, exporter.format) || (spec as { id: string }).id;\n files.push({\n path: join(outputDir, `${filename}.md`),\n content,\n });\n }\n }\n \n if (exporter.index) {\n const indexContent = exporter.index(modelSpecs);\n const indexPath = exporter.outputFile\n ? join(cwd, config.docsDir, exporter.outputFile)\n : join(outputDir, 'index.md');\n if (!exporter.outputFile) {\n ensureDir(outputDir);\n }\n files.push({\n path: indexPath,\n content: indexContent,\n });\n }\n }\n \n console.log(chalk.green(` ✓ ${model.name}`));\n }\n \n if (files.length > 0) {\n console.log('');\n console.log(chalk.blue(` Writing ${files.length} files...`));\n \n const result = await batchWriteFiles(files);\n \n console.log('');\n console.log(chalk.green(` ✓ Build complete`));\n console.log(chalk.gray(` Created: ${result.created}`));\n console.log(chalk.gray(` Updated: ${result.updated}`));\n console.log(chalk.gray(` Unchanged: ${result.unchanged}`));\n } else {\n console.log(chalk.yellow(' No files to generate.'));\n }\n \n } catch (error) {\n console.error(chalk.red('Build failed:'), error);\n process.exit(1);\n }\n}\n","/**\n * Lint Command\n * \n * Execute design consistency checks using model class lintRules\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getSpecsFromConfig, type SpecEntry } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LintCommandOptions {\n config?: string;\n phase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strict?: boolean;\n fix?: boolean;\n format?: 'text' | 'json' | 'github';\n}\n\nexport type LintSeverity = 'error' | 'warning' | 'info';\n\nexport interface LintIssue {\n rule: string;\n severity: LintSeverity;\n message: string;\n specId?: string;\n modelType?: string;\n}\n\nexport interface LintResult {\n issues: LintIssue[];\n errors: number;\n warnings: number;\n infos: number;\n}\n\n// ============================================================================\n// Lint Command\n// ============================================================================\n\nexport async function lintCommand(options: LintCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper lint'));\n console.log('');\n \n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n if (options.phase) {\n console.log(chalk.gray(` Phase: ${options.phase}`));\n }\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n console.log(chalk.gray(` Loaded: ${models.length} models`));\n console.log('');\n \n console.log(chalk.blue(' Running lint checks...'));\n const result = runModelLint(models, specs, options);\n \n console.log('');\n outputLintResults(result, options);\n \n if (result.errors > 0) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Lint failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Lint Runner\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction runModelLint(models: any[], specs: SpecEntry[] | undefined, options: LintCommandOptions): LintResult {\n const issues: LintIssue[] = [];\n \n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n \n if (modelSpecs.length === 0) continue;\n \n const lintResults = model.lintAll(modelSpecs);\n \n for (const result of lintResults) {\n issues.push({\n rule: result.ruleId,\n severity: result.severity,\n message: result.message,\n specId: result.specId,\n modelType: model.name,\n });\n }\n }\n \n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n \n if (!options.strict) {\n return {\n issues: issues.filter(i => i.severity !== 'info'),\n errors,\n warnings,\n infos,\n };\n }\n \n return { issues, errors, warnings, infos };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputLintResults(result: LintResult, options: LintCommandOptions): void {\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'github') {\n for (const issue of result.issues) {\n const level = issue.severity === 'error' ? 'error' : issue.severity === 'warning' ? 'warning' : 'notice';\n console.log(`::${level}::${issue.message} [${issue.rule}]${issue.specId ? ` (${issue.specId})` : ''}`);\n }\n return;\n }\n \n if (result.issues.length === 0) {\n console.log(chalk.green(' ✓ No issues found'));\n return;\n }\n \n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';\n const color = issue.severity === 'error' ? chalk.red : issue.severity === 'warning' ? chalk.yellow : chalk.blue;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n console.log(chalk.gray(` Rule: ${issue.rule}`));\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${result.errors} errors, ${result.warnings} warnings, ${result.infos} infos`));\n}\n","/**\n * Drift Command\n * \n * Detect drift between generated artifacts and SSOT\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getSpecsFromConfig } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DriftCommandOptions {\n config?: string;\n verbose?: boolean;\n failOnDrift?: boolean;\n}\n\nexport interface DriftResult {\n file: string;\n status: 'ok' | 'drifted' | 'missing';\n details?: string;\n}\n\n// ============================================================================\n// Drift Command\n// ============================================================================\n\nexport async function driftCommand(options: DriftCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper drift'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n const results: DriftResult[] = [];\n \n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n if (modelSpecs.length === 0) continue;\n \n for (const exporter of model.getExporters()) {\n if (exporter.format !== 'markdown') continue;\n \n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n if (exporter.single) {\n for (const spec of modelSpecs) {\n const filename = model.getFilename(spec, 'markdown') || (spec as { id: string }).id;\n const filePath = join(outputDir, `${filename}.md`);\n \n if (!existsSync(filePath)) {\n results.push({ file: filePath, status: 'missing' });\n continue;\n }\n \n const expected = exporter.single(spec);\n const actual = readFileSync(filePath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: filePath, status: 'drifted' });\n } else {\n results.push({ file: filePath, status: 'ok' });\n }\n }\n }\n \n if (exporter.index) {\n const indexPath = exporter.outputFile\n ? join(cwd, config.docsDir, exporter.outputFile)\n : join(outputDir, 'index.md');\n \n if (!existsSync(indexPath)) {\n results.push({ file: indexPath, status: 'missing' });\n } else {\n const expected = exporter.index(modelSpecs);\n const actual = readFileSync(indexPath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: indexPath, status: 'drifted' });\n } else {\n results.push({ file: indexPath, status: 'ok' });\n }\n }\n }\n }\n }\n \n outputDriftResults(results, options);\n \n const hasDrift = results.some(r => r.status === 'drifted' || r.status === 'missing');\n if (hasDrift && options.failOnDrift) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Drift check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeContent(content: string): string {\n return content.trim().replace(/\\r\\n/g, '\\n');\n}\n\nfunction outputDriftResults(results: DriftResult[], _options: DriftCommandOptions): void {\n console.log('');\n \n const ok = results.filter(r => r.status === 'ok');\n const drifted = results.filter(r => r.status === 'drifted');\n const missing = results.filter(r => r.status === 'missing');\n \n if (drifted.length === 0 && missing.length === 0) {\n console.log(chalk.green(' ✓ No drift detected'));\n console.log(chalk.gray(` Checked: ${results.length} files`));\n return;\n }\n \n if (drifted.length > 0) {\n console.log(chalk.yellow(` ⚠ ${drifted.length} file(s) have drifted:`));\n for (const result of drifted) {\n console.log(chalk.yellow(` - ${result.file}`));\n }\n }\n \n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} file(s) are missing:`));\n for (const result of missing) {\n console.log(chalk.red(` - ${result.file}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${ok.length} ok, ${drifted.length} drifted, ${missing.length} missing`));\n}\n","/**\n * Check Command\n * \n * Check consistency with external SSOT using model class externalChecker\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getSpecsFromConfig, buildRegistryFromConfig, type SpecEntry, type CoverageResult } from '../core/model.js';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CheckCommandOptions {\n config?: string;\n type?: 'openapi' | 'ddl' | 'iac' | 'all';\n verbose?: boolean;\n coverage?: boolean;\n}\n\nexport interface CheckIssue {\n severity: 'error' | 'warning';\n message: string;\n specId?: string;\n field?: string;\n}\n\nexport interface CheckResult {\n type: string;\n success: boolean;\n issues: CheckIssue[];\n}\n\n// ============================================================================\n// Check Command\n// ============================================================================\n\nexport async function checkCommand(\n type: string | undefined,\n options: CheckCommandOptions\n): Promise<void> {\n console.log(chalk.blue('speckeeper check'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const checkType = type || options.type || 'all';\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Type: ${checkType}`));\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n if (options.verbose) {\n console.log(chalk.gray(` Registered models: ${models.map((m: { id: string }) => m.id).join(', ')}`));\n }\n \n const results: CheckResult[] = [];\n \n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n if (modelSpecs.length === 0) continue;\n \n for (const spec of modelSpecs) {\n const sourcePath = model.getExternalSourcePath(spec);\n if (!sourcePath) continue;\n \n const fullPath = join(cwd, sourcePath);\n if (!existsSync(fullPath)) {\n results.push({\n type: model.id,\n success: false,\n issues: [{\n severity: 'error',\n message: `External source not found: ${sourcePath}`,\n specId: (spec as { id: string }).id,\n }],\n });\n continue;\n }\n \n const externalData = loadExternalData(fullPath);\n const checkResult = model.check(spec, externalData);\n \n if (!checkResult.success || checkResult.errors.length > 0 || checkResult.warnings.length > 0) {\n results.push({\n type: model.id,\n success: checkResult.success,\n issues: [\n ...checkResult.errors.map((e: { message: string; specId?: string; field?: string }) => ({ severity: 'error' as const, message: e.message, specId: e.specId, field: e.field })),\n ...checkResult.warnings.map((w: { message: string; specId?: string; field?: string }) => ({ severity: 'warning' as const, message: w.message, specId: w.specId, field: w.field })),\n ],\n });\n }\n }\n }\n \n outputCheckResults(results);\n \n if (options.coverage) {\n console.log('');\n console.log(chalk.blue(' Coverage checks...'));\n const coverageResults = runAllCoverageChecks(models, specs);\n \n if (coverageResults.length > 0) {\n outputAllCoverageResults(coverageResults);\n \n for (const check of coverageResults) {\n if (check.result.uncoveredItems.length > 0) {\n results.push({\n type: `coverage-${check.modelId}`,\n success: check.result.coveragePercent >= 80,\n issues: check.result.uncoveredItems.slice(0, 10).map(item => ({\n severity: 'warning' as const,\n message: `[${check.modelName}→${check.targetModel}] '${item.id}'${item.sourceId ? ` (${item.sourceId})` : ''} not covered`,\n specId: item.id,\n })),\n });\n }\n }\n \n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n const allPassed = coverageResults.every(c => c.result.coveragePercent >= 80);\n if (allPassed) {\n console.log(chalk.green(' ✓ All coverage checks passed (≥80%)'));\n } else {\n const failed = coverageResults.filter(c => c.result.coveragePercent < 80);\n console.log(chalk.yellow(` ⚠ ${failed.length} coverage check(s) below 80%`));\n }\n } else {\n console.log(chalk.gray(' No coverage checker found'));\n }\n }\n \n const hasErrors = results.some(r => !r.success);\n if (hasErrors) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction loadExternalData(filePath: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n \n if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {\n return parseYaml(content);\n }\n \n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n \n return content;\n}\n\nfunction outputCheckResults(results: CheckResult[]): void {\n console.log('');\n \n if (results.length === 0) {\n console.log(chalk.green(' ✓ All checks passed'));\n return;\n }\n \n let totalErrors = 0;\n let totalWarnings = 0;\n \n for (const result of results) {\n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : '⚠';\n const color = issue.severity === 'error' ? chalk.red : chalk.yellow;\n \n if (issue.severity === 'error') totalErrors++;\n else totalWarnings++;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${totalErrors} errors, ${totalWarnings} warnings`));\n}\n\n// ============================================================================\n// Coverage Check\n// ============================================================================\n\ninterface CoverageCheckResult {\n modelId: string;\n modelName: string;\n description: string;\n targetModel: string;\n result: CoverageResult;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction runAllCoverageChecks(models: any[], specs: SpecEntry[] | undefined): CoverageCheckResult[] {\n const results: CoverageCheckResult[] = [];\n const registry = buildRegistryFromConfig(specs);\n \n for (const model of models) {\n const checker = model.getCoverageChecker();\n if (checker) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n const result = model.checkCoverage(modelSpecs, registry);\n \n if (result) {\n results.push({\n modelId: model.id,\n modelName: model.name,\n description: checker.description,\n targetModel: checker.targetModel,\n result,\n });\n }\n }\n }\n \n return results;\n}\n\nfunction outputAllCoverageResults(checks: CoverageCheckResult[]): void {\n for (const check of checks) {\n console.log('');\n console.log(chalk.blue(` Coverage: ${check.modelName} → ${check.targetModel}`));\n console.log(chalk.gray(` ${check.description}`));\n console.log(chalk.gray(` ─────────────────────────────────────`));\n console.log(chalk.gray(` Total: ${check.result.total}`));\n console.log(chalk.green(` Covered: ${check.result.covered}`));\n console.log(chalk.yellow(` Uncovered: ${check.result.uncovered}`));\n \n const color = check.result.coveragePercent >= 80 ? chalk.green : \n check.result.coveragePercent >= 50 ? chalk.yellow : chalk.red;\n console.log(color(` Coverage: ${check.result.coveragePercent}%`));\n \n if (check.result.uncoveredItems.length > 0 && check.result.uncoveredItems.length <= 10) {\n console.log('');\n console.log(chalk.yellow(' Uncovered items:'));\n for (const item of check.result.uncoveredItems) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n const source = item.sourceId ? ` (${item.sourceId})` : '';\n console.log(chalk.yellow(` - ${item.id}${source}${desc}`));\n }\n } else if (check.result.uncoveredItems.length > 10) {\n console.log('');\n console.log(chalk.yellow(` (${check.result.uncoveredItems.length} uncovered items - showing first 5)`));\n for (const item of check.result.uncoveredItems.slice(0, 5)) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n console.log(chalk.yellow(` - ${item.id}${desc}`));\n }\n }\n }\n}\n","/**\n * New Command\n * \n * Generate templates for new model instances\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NewCommandOptions {\n config?: string;\n type?: string;\n id?: string;\n output?: string;\n dryRun?: boolean;\n}\n\n// ============================================================================\n// New Command\n// ============================================================================\n\nexport async function newCommand(options: NewCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper new'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n // List available types if no type specified\n if (!options.type) {\n console.log(chalk.gray(' Available model types:'));\n const models = getAllModels();\n for (const model of models) {\n console.log(chalk.gray(` - ${model.id} (${model.name})`));\n }\n console.log('');\n console.log(chalk.gray(' Usage: speckeeper new --type <type> [--id <id>]'));\n return;\n }\n \n // Find model\n const models = getAllModels();\n const model = models.find(m => m.id === options.type);\n \n if (!model) {\n console.error(chalk.red(` Error: Unknown model type '${options.type}'`));\n console.log(chalk.gray(' Run `speckeeper new` to see available types'));\n process.exit(1);\n }\n \n // Generate ID if not provided\n const id = options.id || `${model.idPrefix}-${String(Date.now()).slice(-6)}`;\n \n // Generate template\n const template = generateTemplate(model, id);\n \n if (options.dryRun) {\n console.log(chalk.gray(' Template (dry run):'));\n console.log('');\n console.log(template);\n return;\n }\n \n // Write template to file\n const outputDir = options.output || join(cwd, config.designDir || 'design');\n const outputFile = join(outputDir, `${model.id}-${id}.ts`);\n \n if (existsSync(outputFile)) {\n console.error(chalk.red(` Error: File already exists: ${outputFile}`));\n process.exit(1);\n }\n \n writeFileSync(outputFile, template);\n console.log(chalk.green(` ✓ Created: ${outputFile}`));\n}\n\n// ============================================================================\n// Template Generation\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction generateTemplate(model: any, id: string): string {\n const typeName = model.name;\n const lines: string[] = [];\n \n lines.push(`/**`);\n lines.push(` * ${typeName}: ${id}`);\n lines.push(` * `);\n lines.push(` * Generated by speckeeper new`);\n lines.push(` */`);\n lines.push(`import type { ${typeName} } from './_models/${model.id}';`);\n lines.push('');\n lines.push(`export const ${camelCase(id)}: ${typeName} = {`);\n lines.push(` id: '${id}',`);\n lines.push(` // TODO: Fill in the required fields`);\n lines.push(`};`);\n lines.push('');\n \n return lines.join('\\n');\n}\n\nfunction camelCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[-_](.)/g, (_, c) => c.toUpperCase());\n}\n","/**\n * Impact Command\n * \n * Analyze the impact scope of changes\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { buildRegistryFromConfig, findModelTypeFromConfig } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImpactCommandOptions {\n config?: string;\n depth?: string;\n direction?: 'upstream' | 'downstream' | 'both';\n format?: 'text' | 'json' | 'mermaid';\n}\n\nexport interface ImpactNode {\n id: string;\n type: string;\n depth: number;\n impactType: 'direct' | 'indirect';\n}\n\nexport interface ImpactResult {\n target: string;\n targetType: string;\n impactedNodes: ImpactNode[];\n}\n\n// ============================================================================\n// Impact Command\n// ============================================================================\n\nexport async function impactCommand(targetId: string, options: ImpactCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper impact'));\n console.log('');\n \n if (!targetId) {\n console.error(chalk.red('Error: ID is required'));\n console.log(chalk.gray(' Usage: speckeeper impact <id>'));\n process.exit(1);\n }\n \n const config = await loadConfig(options.config);\n const maxDepth = options.depth ? parseInt(options.depth, 10) : 3;\n \n console.log(chalk.gray(` Target: ${targetId}`));\n console.log(chalk.gray(` Depth: ${maxDepth}`));\n console.log('');\n \n try {\n const specs = config.specs;\n const registry = buildRegistryFromConfig(specs);\n \n const targetType = findModelTypeFromConfig(specs, targetId);\n if (!targetType) {\n console.error(chalk.red(` Error: Target '${targetId}' not found`));\n process.exit(1);\n }\n \n console.log(chalk.blue(' Analyzing impact...'));\n const result = analyzeImpact(registry, targetId, targetType, maxDepth);\n \n outputImpactResults(result, options);\n \n } catch (error) {\n console.error(chalk.red('Impact analysis failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Impact Analysis\n// ============================================================================\n\nfunction analyzeImpact(\n registry: Record<string, Map<string, unknown>>,\n targetId: string,\n targetType: string,\n maxDepth: number\n): ImpactResult {\n const impactedNodes: ImpactNode[] = [];\n const visited = new Set<string>([targetId]);\n \n function findReferences(id: string, depth: number): void {\n if (depth > maxDepth) return;\n \n for (const [type, map] of Object.entries(registry)) {\n for (const [itemId, item] of map) {\n if (visited.has(itemId)) continue;\n \n const itemStr = JSON.stringify(item);\n if (itemStr.includes(`\"${id}\"`)) {\n visited.add(itemId);\n impactedNodes.push({\n id: itemId,\n type,\n depth,\n impactType: depth === 1 ? 'direct' : 'indirect',\n });\n \n findReferences(itemId, depth + 1);\n }\n }\n }\n }\n \n findReferences(targetId, 1);\n \n return {\n target: targetId,\n targetType,\n impactedNodes,\n };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputImpactResults(result: ImpactResult, options: ImpactCommandOptions): void {\n console.log('');\n \n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'mermaid') {\n console.log('```mermaid');\n console.log('graph TD');\n console.log(` ${result.target}[${result.target}]`);\n for (const node of result.impactedNodes) {\n const style = node.impactType === 'direct' ? '-->|direct|' : '-.->|indirect|';\n console.log(` ${result.target} ${style} ${node.id}[${node.id}]`);\n }\n console.log('```');\n return;\n }\n \n if (result.impactedNodes.length === 0) {\n console.log(chalk.green(' No impacted elements found'));\n return;\n }\n \n const direct = result.impactedNodes.filter(n => n.impactType === 'direct');\n const indirect = result.impactedNodes.filter(n => n.impactType === 'indirect');\n \n if (direct.length > 0) {\n console.log(chalk.yellow(` Direct impact (${direct.length}):`));\n for (const node of direct) {\n console.log(chalk.yellow(` → ${node.id} (${node.type})`));\n }\n }\n \n if (indirect.length > 0) {\n console.log(chalk.gray(` Indirect impact (${indirect.length}):`));\n for (const node of indirect) {\n console.log(chalk.gray(` ⤳ ${node.id} (${node.type}, depth: ${node.depth})`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Total: ${result.impactedNodes.length} impacted elements`));\n}\n","/**\n * speckeeper init command\n * \n * Generate starter templates for a new speckeeper project\n */\nimport chalk from 'chalk';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport async function runInit(options: InitOptions = {}): Promise<void> {\n const cwd = process.cwd();\n \n console.log(chalk.cyan('speckeeper init'));\n console.log('');\n \n // Check if already initialized\n const designDir = join(cwd, 'design');\n const configFile = join(cwd, 'speckeeper.config.ts');\n \n if (!options.force && (existsSync(designDir) || existsSync(configFile))) {\n console.log(chalk.yellow(' Project already initialized.'));\n console.log(chalk.gray(' Use --force to overwrite existing files.'));\n return;\n }\n \n // Get project name from directory\n const projectName = cwd.split('/').pop() || 'my-project';\n \n // Find templates directory\n const templatesDir = join(__dirname, 'templates', 'init');\n \n if (!existsSync(templatesDir)) {\n console.log(chalk.red(` Error: Templates directory not found at ${templatesDir}`));\n console.log(chalk.gray(' Please ensure the package is properly installed.'));\n return;\n }\n \n // Copy template files\n let packageJsonCreated = false;\n copyTemplateDir(templatesDir, cwd, projectName, options.force || false, (relativePath, created) => {\n if (created) {\n console.log(chalk.green(` Created: ${relativePath}`));\n if (relativePath === 'package.json') {\n packageJsonCreated = true;\n }\n } else {\n console.log(chalk.yellow(` Skipped: ${relativePath} (already exists)`));\n }\n });\n \n console.log('');\n console.log(chalk.cyan(' Project initialized successfully!'));\n console.log('');\n console.log(' Next steps:');\n if (packageJsonCreated) {\n console.log(chalk.gray(' 1. Run `npm install` to install dependencies'));\n console.log(chalk.gray(' 2. Add spec data in design/*.ts using defineSpecs()'));\n console.log(chalk.gray(' 3. Import new spec files in design/index.ts'));\n console.log(chalk.gray(' 4. Run `npx speckeeper lint` to validate'));\n } else {\n console.log(chalk.gray(' 1. Add speckeeper and zod to your package.json dependencies'));\n console.log(chalk.gray(' 2. Ensure \"type\": \"module\" is set in package.json'));\n console.log(chalk.gray(' 3. Add spec data in design/*.ts using defineSpecs()'));\n console.log(chalk.gray(' 4. Import new spec files in design/index.ts'));\n console.log(chalk.gray(' 5. Run `npx speckeeper lint` to validate'));\n }\n}\n\n/**\n * Recursively copy template directory\n */\nfunction copyTemplateDir(\n srcDir: string,\n destDir: string,\n projectName: string,\n force: boolean,\n onFile: (relativePath: string, created: boolean) => void,\n relativePath: string = ''\n): void {\n const entries = readdirSync(srcDir);\n \n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const stat = statSync(srcPath);\n \n // Handle .template extension\n const destEntry = entry.endsWith('.template') ? entry.slice(0, -9) : entry;\n const destPath = join(destDir, destEntry);\n const relPath = relativePath ? join(relativePath, destEntry) : destEntry;\n \n if (stat.isDirectory()) {\n // Create directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true });\n onFile(relPath + '/', true);\n }\n // Recurse into directory\n copyTemplateDir(srcPath, destPath, projectName, force, onFile, relPath);\n } else {\n // Skip if file exists and not force\n if (!force && existsSync(destPath)) {\n onFile(relPath, false);\n continue;\n }\n \n // Read and process template\n let content = readFileSync(srcPath, 'utf-8');\n \n // Replace template variables\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, projectName);\n \n // Write file\n const dir = dirname(destPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(destPath, content);\n onFile(relPath, true);\n }\n }\n}\n","/**\n * Mermaid flowchart parser\n *\n * Extracts nodes, edges, classDefs, and class assignments\n * from a mermaid flowchart block embedded in Markdown.\n */\nimport type {\n ArrowDirection,\n MermaidNode,\n MermaidEdge,\n MermaidClassDef,\n MermaidClassAssignment,\n SubgraphInfo,\n ParsedFlowchart,\n} from './types.js';\n\n/**\n * Extract mermaid code blocks from Markdown content\n */\nexport function extractMermaidBlocks(markdown: string): string[] {\n const blocks: string[] = [];\n const regex = /```mermaid\\s*\\n([\\s\\S]*?)```/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(markdown)) !== null) {\n blocks.push(match[1]);\n }\n return blocks;\n}\n\n/**\n * Parse a mermaid flowchart block into structured data\n */\nexport function parseFlowchart(mermaidSource: string): ParsedFlowchart {\n const lines = mermaidSource.split('\\n');\n const nodes = new Map<string, MermaidNode>();\n const edges: MermaidEdge[] = [];\n const classDefs: MermaidClassDef[] = [];\n const classAssignments: MermaidClassAssignment[] = [];\n const subgraphs: SubgraphInfo[] = [];\n let direction = 'TB';\n\n const subgraphStack: SubgraphInfo[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n\n if (!line || line.startsWith('%%')) continue;\n\n const flowchartMatch = line.match(/^flowchart\\s+(\\w+)/);\n if (flowchartMatch) {\n direction = flowchartMatch[1];\n continue;\n }\n\n if (line.startsWith('graph ')) {\n const gMatch = line.match(/^graph\\s+(\\w+)/);\n if (gMatch) direction = gMatch[1];\n continue;\n }\n\n // subgraph id [Label] or subgraph id\n const subgraphMatch = line.match(/^subgraph\\s+(\\S+)(?:\\s*\\[([^\\]]*)\\])?/);\n if (subgraphMatch) {\n const sg: SubgraphInfo = {\n id: subgraphMatch[1],\n label: subgraphMatch[2] || undefined,\n nodeIds: [],\n };\n subgraphStack.push(sg);\n continue;\n }\n\n if (line === 'end' && subgraphStack.length > 0) {\n const completed = subgraphStack.pop()!;\n subgraphs.push(completed);\n for (const nodeId of completed.nodeIds) {\n const node = nodes.get(nodeId);\n if (node) {\n node.subgraph = completed.id;\n }\n }\n continue;\n }\n\n const classDefMatch = line.match(/^classDef\\s+(\\S+)\\s+(.*)/);\n if (classDefMatch) {\n classDefs.push({ name: classDefMatch[1], styles: classDefMatch[2] });\n continue;\n }\n\n const classAssignMatch = line.match(/^class\\s+(\\S+)\\s+(\\S+)/);\n if (classAssignMatch) {\n const nodeIds = classAssignMatch[1].split(',').map(s => s.trim());\n classAssignments.push({ nodeIds, className: classAssignMatch[2] });\n for (const id of nodeIds) {\n ensureNode(nodes, id);\n const node = nodes.get(id)!;\n if (!node.classes.includes(classAssignMatch[2])) {\n node.classes.push(classAssignMatch[2]);\n }\n }\n continue;\n }\n\n const edgeParsed = tryParseEdgeLine(line);\n if (edgeParsed) {\n for (const { sourceId, sourceLabel, targetId, targetLabel, label, direction: dir } of edgeParsed) {\n ensureNode(nodes, sourceId, sourceLabel);\n ensureNode(nodes, targetId, targetLabel);\n edges.push({\n sourceId,\n targetId,\n rawLabel: label,\n direction: dir,\n });\n if (subgraphStack.length > 0) {\n const current = subgraphStack[subgraphStack.length - 1];\n if (!current.nodeIds.includes(sourceId)) current.nodeIds.push(sourceId);\n if (!current.nodeIds.includes(targetId)) current.nodeIds.push(targetId);\n }\n }\n continue;\n }\n\n const standaloneNode = tryParseStandaloneNode(line);\n if (standaloneNode) {\n ensureNode(nodes, standaloneNode.id, standaloneNode.label);\n if (subgraphStack.length > 0) {\n const current = subgraphStack[subgraphStack.length - 1];\n if (!current.nodeIds.includes(standaloneNode.id)) current.nodeIds.push(standaloneNode.id);\n }\n }\n }\n\n return { direction, nodes, edges, classDefs, classAssignments, subgraphs };\n}\n\n/**\n * Parse Markdown and return the first flowchart found\n */\nexport function parseMarkdownFlowchart(markdown: string): ParsedFlowchart | null {\n const blocks = extractMermaidBlocks(markdown);\n for (const block of blocks) {\n const trimmed = block.trim();\n if (trimmed.startsWith('flowchart') || trimmed.startsWith('graph')) {\n return parseFlowchart(trimmed);\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction ensureNode(nodes: Map<string, MermaidNode>, id: string, label?: string): void {\n const existing = nodes.get(id);\n if (existing) {\n if (label && !existing.label) {\n existing.label = label;\n }\n } else {\n nodes.set(id, { id, label, classes: [] });\n }\n}\n\n/** Node with optional label: ID[Label text] or ID */\nconst NODE_PATTERN = /([A-Za-z_]\\w*)(?:\\[([^\\]]*)\\])?/;\n\ninterface ParsedEdgeResult {\n sourceId: string;\n sourceLabel: string | undefined;\n targetId: string;\n targetLabel: string | undefined;\n label: string | undefined;\n direction: ArrowDirection;\n}\n\n/**\n * Try to parse an edge line. Returns array of edges (a line can have chained edges).\n *\n * Supported arrow patterns:\n * --> ---> ----> forward\n * <--> <---> <----> bidirectional\n * -.-> forward (dotted)\n * ==> forward (thick)\n * -->|label| forward with label\n * <-->|label| bidirectional with label\n */\nfunction tryParseEdgeLine(line: string): ParsedEdgeResult[] | null {\n // Arrow patterns, ordered longest-first to avoid partial matches\n const arrowPatterns = [\n { regex: /<-{2,}>/, direction: 'bidirectional' as ArrowDirection },\n { regex: /<={2,}>/, direction: 'bidirectional' as ArrowDirection },\n { regex: /-{2,}>/, direction: 'forward' as ArrowDirection },\n { regex: /={2,}>/, direction: 'forward' as ArrowDirection },\n { regex: /-\\.->/, direction: 'forward' as ArrowDirection },\n ];\n\n // Try to find any arrow in the line\n let bestMatch: {\n index: number;\n length: number;\n direction: ArrowDirection;\n } | null = null;\n\n for (const ap of arrowPatterns) {\n const m = line.match(ap.regex);\n if (m && m.index !== undefined) {\n if (!bestMatch || m.index < bestMatch.index) {\n bestMatch = { index: m.index, length: m[0].length, direction: ap.direction };\n }\n }\n }\n\n if (!bestMatch) return null;\n\n // Split line at the arrow\n const leftPart = line.substring(0, bestMatch.index).trim();\n const rightPart = line.substring(bestMatch.index + bestMatch.length).trim();\n\n // Extract source node from left part\n const sourceMatch = leftPart.match(NODE_PATTERN);\n if (!sourceMatch) return null;\n const sourceId = sourceMatch[1];\n const sourceLabel = sourceMatch[2] || undefined;\n\n // Right part may be: |label| TargetNode or just TargetNode\n let label: string | undefined;\n let targetStr = rightPart;\n\n const labelMatch = rightPart.match(/^\\|([^|]*)\\|\\s*(.*)/);\n if (labelMatch) {\n label = labelMatch[1].trim();\n targetStr = labelMatch[2];\n }\n\n // Extract target node\n const targetMatch = targetStr.match(NODE_PATTERN);\n if (!targetMatch) return null;\n const targetId = targetMatch[1];\n const targetLabel = targetMatch[2] || undefined;\n\n return [{\n sourceId,\n sourceLabel,\n targetId,\n targetLabel,\n label,\n direction: bestMatch.direction,\n }];\n}\n\nfunction tryParseStandaloneNode(line: string): { id: string; label: string | undefined } | null {\n const m = line.match(/^([A-Za-z_]\\w*)\\[([^\\]]*)\\]\\s*$/);\n if (m) {\n return { id: m[1], label: m[2] };\n }\n return null;\n}\n","/**\n * Edge label controlled vocabulary (logic-driven)\n *\n * Only edges that trigger specific speckeeper logic are defined here.\n * Other speckeeper↔speckeeper edges use generic reference integrity.\n */\nimport type {\n EdgeVocabularyEntry,\n MermaidEdge,\n MermaidNode,\n ResolvedEdge,\n ScaffoldDiagnostic,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Vocabulary definitions\n// ---------------------------------------------------------------------------\n\n/**\n * Speckeeper-managed vocabulary — labels that trigger specific logic.\n *\n * - implements (check): speckeeper → external SSOT, triggers external checker\n * - verifiedBy (check): speckeeper → external test, triggers test checker\n * - refines (lint): speckeeper → speckeeper, reference integrity + level constraint\n * - All other speckeeper↔speckeeper edges: generic reference integrity (lint)\n */\nexport const EDGE_VOCABULARY: EdgeVocabularyEntry[] = [\n // check: speckeeper → external SSOT\n {\n label: 'implements',\n expectedDirection: 'forward',\n relationType: 'implements',\n category: 'check',\n description: 'Spec is implemented as external artifact (OpenAPI, DDL, etc.)',\n },\n {\n label: 'verifiedBy',\n expectedDirection: 'forward',\n relationType: 'verifiedBy',\n category: 'check',\n description: 'Spec is verified by external test code',\n },\n\n // lint: speckeeper ↔ speckeeper with level constraint\n {\n label: 'refines',\n expectedDirection: 'forward',\n relationType: 'refines',\n category: 'lint',\n description: 'Decompose higher-level item into lower-level detail',\n },\n\n // lint: speckeeper ↔ speckeeper generic reference integrity\n {\n label: 'relatedTo',\n expectedDirection: 'bidirectional',\n relationType: 'relatedTo',\n category: 'lint',\n description: 'Bidirectional association or consistency constraint',\n },\n {\n label: 'uses',\n expectedDirection: 'forward',\n relationType: 'uses',\n category: 'lint',\n description: 'Reference / dependency',\n },\n {\n label: 'dependsOn',\n expectedDirection: 'forward',\n relationType: 'dependsOn',\n category: 'lint',\n description: 'Dependency relationship',\n },\n {\n label: 'satisfies',\n expectedDirection: 'forward',\n relationType: 'satisfies',\n category: 'lint',\n description: 'Satisfies business/requirements',\n },\n {\n label: 'includes',\n expectedDirection: 'forward',\n relationType: 'includes',\n category: 'lint',\n description: 'Parent contains child items',\n },\n {\n label: 'traces',\n expectedDirection: 'forward',\n relationType: 'traces',\n category: 'lint',\n description: 'Derive target from source',\n },\n\n // external: test code → implementation code (no checker generated)\n {\n label: 'verifies',\n expectedDirection: 'forward',\n relationType: 'verifies',\n category: 'external',\n description: 'Test code tests implementation code (external → external, no checker)',\n },\n];\n\n/**\n * Well-known labels for edges between non-speckeeper nodes.\n */\nexport const EXTERNAL_LABELS: EdgeVocabularyEntry[] = [\n {\n label: 'generate',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'drift',\n description: 'Automated generation (external tool)',\n },\n {\n label: 'apply',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'external',\n description: 'Apply to external system',\n },\n {\n label: 'deploy',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'external',\n description: 'Deploy artifact',\n },\n];\n\nconst ALL_VOCABULARY = [...EDGE_VOCABULARY, ...EXTERNAL_LABELS];\n\nconst SORTED_VOCABULARY = [...ALL_VOCABULARY].sort(\n (a, b) => b.label.length - a.label.length,\n);\n\nconst SORTED_SPECKEEPER_VOCABULARY = [...EDGE_VOCABULARY].sort(\n (a, b) => b.label.length - a.label.length,\n);\n\n// ---------------------------------------------------------------------------\n// Label normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise a raw edge label to its canonical vocabulary entry.\n */\nexport function normalizeLabel(\n rawLabel: string | undefined,\n vocabulary: EdgeVocabularyEntry[] = SORTED_VOCABULARY,\n): { entry: EdgeVocabularyEntry; modifier: string | undefined } | null {\n if (!rawLabel) return null;\n\n const lower = rawLabel.toLowerCase().trim();\n\n for (const entry of vocabulary) {\n if (lower === entry.label.toLowerCase()) {\n return { entry, modifier: undefined };\n }\n }\n\n for (const entry of vocabulary) {\n const entryLower = entry.label.toLowerCase();\n if (lower.endsWith(entryLower)) {\n const mod = rawLabel.slice(0, rawLabel.length - entry.label.length).trim();\n return { entry, modifier: mod || undefined };\n }\n }\n\n for (const entry of vocabulary) {\n const entryLower = entry.label.toLowerCase();\n if (lower.includes(entryLower)) {\n const idx = lower.indexOf(entryLower);\n const before = rawLabel.slice(0, idx).trim();\n const after = rawLabel.slice(idx + entry.label.length).trim();\n const mod = [before, after].filter(Boolean).join(' ');\n return { entry, modifier: mod || undefined };\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Edge resolution\n// ---------------------------------------------------------------------------\n\n/** Known test-like node classes */\nconst TEST_CLASSES = new Set(['test', 'e2e-test', 'unit-test', 'integration-test']);\n\nfunction isTestLikeByClass(node: MermaidNode | undefined): boolean {\n if (!node) return false;\n return node.classes.some(c => TEST_CLASSES.has(c) || c.includes('test'));\n}\n\n/**\n * Resolve raw edges to vocabulary-backed ResolvedEdges,\n * collecting diagnostics along the way.\n */\nexport function resolveEdges(\n edges: MermaidEdge[],\n nodes: Map<string, MermaidNode>,\n speckeeperClassName: string,\n): { resolved: ResolvedEdge[]; diagnostics: ScaffoldDiagnostic[] } {\n const diagnostics: ScaffoldDiagnostic[] = [];\n const resolved: ResolvedEdge[] = [];\n\n const isSpk = (id: string): boolean =>\n nodes.get(id)?.classes.includes(speckeeperClassName) ?? false;\n\n const fallback = EDGE_VOCABULARY.find(v => v.label === 'relatedTo')!;\n\n for (const edge of edges) {\n const involvesSpeckeeper = isSpk(edge.sourceId) || isSpk(edge.targetId);\n\n const norm = normalizeLabel(edge.rawLabel);\n\n if (!norm) {\n if (involvesSpeckeeper) {\n diagnostics.push({\n severity: 'warning',\n message: `Edge label \"${edge.rawLabel}\" is not a valid speckeeper RelationType — falling back to \"relatedTo\"`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n resolved.push({\n ...edge,\n normalizedLabel: 'relatedTo',\n vocabulary: fallback,\n modifier: undefined,\n });\n } else {\n resolved.push({\n ...edge,\n normalizedLabel: edge.rawLabel ?? '',\n vocabulary: { label: edge.rawLabel ?? '', expectedDirection: 'forward', relationType: undefined, category: 'external', description: '' },\n modifier: undefined,\n });\n }\n continue;\n }\n\n if (involvesSpeckeeper && !norm.entry.relationType) {\n const spkNorm = normalizeLabel(edge.rawLabel, SORTED_SPECKEEPER_VOCABULARY);\n if (!spkNorm) {\n diagnostics.push({\n severity: 'warning',\n message: `Edge label \"${edge.rawLabel}\" is not a valid speckeeper RelationType — falling back to \"relatedTo\"`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n resolved.push({\n ...edge,\n normalizedLabel: 'relatedTo',\n vocabulary: fallback,\n modifier: undefined,\n });\n continue;\n }\n }\n\n resolved.push({\n ...edge,\n normalizedLabel: norm.entry.label,\n vocabulary: norm.entry,\n modifier: norm.modifier,\n });\n\n // Validate arrow direction\n if (involvesSpeckeeper && edge.direction !== norm.entry.expectedDirection) {\n const expected = norm.entry.expectedDirection === 'bidirectional' ? '<-->' : '-->';\n diagnostics.push({\n severity: 'warning',\n message: `\"${norm.entry.label}\" expects ${expected} arrow but got ${edge.direction === 'bidirectional' ? '<-->' : '-->'}`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n\n // Validate: \"implements\" should be speckeeper → external only\n if (norm.entry.label === 'implements') {\n if (isSpk(edge.sourceId) && isSpk(edge.targetId)) {\n diagnostics.push({\n severity: 'warning',\n message: '\"implements\" should be speckeeper → external; consider using \"refines\" for speckeeper → speckeeper edges',\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n }\n\n // Validate: \"verifiedBy\" should be speckeeper → external only\n if (norm.entry.label === 'verifiedBy') {\n if (isSpk(edge.sourceId) && isSpk(edge.targetId)) {\n diagnostics.push({\n severity: 'warning',\n message: '\"verifiedBy\" should be speckeeper → external; it represents verification by external test code',\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n\n // Warn if target is not a test-like node\n const targetNode = nodes.get(edge.targetId);\n if (targetNode && !isTestLikeByClass(targetNode)) {\n const targetId = edge.targetId.toUpperCase();\n const looksLikeTest = ['UT', 'IT', 'DUT', 'E2ET'].includes(targetId) ||\n targetId.includes('TEST') ||\n (targetNode.label ?? '').toLowerCase().includes('test');\n if (!looksLikeTest) {\n diagnostics.push({\n severity: 'warning',\n message: `\"verifiedBy\" target \"${edge.targetId}\" does not appear to be a test node; verifiedBy is intended for test targets`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n }\n }\n }\n\n return { resolved, diagnostics };\n}\n\n// ---------------------------------------------------------------------------\n// Category helpers\n// ---------------------------------------------------------------------------\n\nexport function isLintEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'lint';\n}\n\nexport function isCheckEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'check';\n}\n\nexport function isCoverageEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'coverage';\n}\n\nexport function isDriftEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'drift';\n}\n\n/**\n * Determine whether a node is test-like (by ID, label, or class).\n */\nexport function isTestLikeNode(node: MermaidNode | undefined): boolean {\n if (!node) return false;\n if (isTestLikeByClass(node)) return true;\n const id = node.id.toUpperCase();\n const testIds = ['UT', 'IT', 'DUT', 'E2ET'];\n if (testIds.includes(id)) return true;\n if (id.includes('TEST')) return true;\n const label = (node.label ?? '').toLowerCase();\n if (label.includes('テスト') || label.includes('test')) return true;\n return false;\n}\n","/**\n * Template registry\n *\n * Resolves mermaid node classes to model template info.\n * All classes use the common base template (FR-SCF-028).\n * Class name is used only for model name / file name derivation\n * and node grouping — no class-specific templates exist.\n */\n\nimport type { ModelLevel } from '../core/relation.js';\n\n// ---------------------------------------------------------------------------\n// Model template metadata\n// ---------------------------------------------------------------------------\n\nexport interface ModelTemplateInfo {\n /** Template identifier — always 'base' (FR-SCF-028) */\n templateName: 'base';\n /** Default model level (inferred from subgraph) */\n defaultLevel: ModelLevel;\n /** ID prefix for spec instances (= node ID) */\n defaultIdPrefix: string;\n /** Human-readable model name (PascalCase) */\n modelName: string;\n /** kebab-case file name (without .ts) */\n fileName: string;\n}\n\n// ---------------------------------------------------------------------------\n// Subgraph → Level inference\n// ---------------------------------------------------------------------------\n\nconst LEVEL_PATTERNS: Array<{ pattern: RegExp; level: ModelLevel }> = [\n { pattern: /^L0$|business|domain/i, level: 'L0' },\n { pattern: /^L1$|requirement/i, level: 'L1' },\n { pattern: /^L2$|design|architecture/i, level: 'L2' },\n { pattern: /^L3$|implementation|external/i, level: 'L3' },\n];\n\nexport function inferLevelFromSubgraph(subgraphId: string | undefined): ModelLevel {\n if (!subgraphId) return 'L0';\n for (const { pattern, level } of LEVEL_PATTERNS) {\n if (pattern.test(subgraphId)) return level;\n }\n return 'L0';\n}\n\n// ---------------------------------------------------------------------------\n// Class-based resolution\n// ---------------------------------------------------------------------------\n\nconst SPECKEEPER_CLASS = 'speckeeper';\n\n/**\n * Resolve a mermaid node to a model template.\n *\n * Always uses the base template (FR-SCF-028). The artifact class\n * (first non-speckeeper class) determines only model name and file name.\n * Level is inferred from subgraph membership.\n */\nexport function resolveModelTemplate(\n nodeId: string,\n nodeClasses?: string[],\n subgraphId?: string,\n): ModelTemplateInfo {\n const level = inferLevelFromSubgraph(subgraphId);\n\n const artifactClass = nodeClasses\n ?.find(c => c !== SPECKEEPER_CLASS);\n\n if (!artifactClass) {\n return {\n templateName: 'base',\n defaultLevel: level,\n defaultIdPrefix: nodeId,\n modelName: toPascalCase(nodeId),\n fileName: toKebabCase(nodeId),\n };\n }\n\n return {\n templateName: 'base',\n defaultLevel: level,\n defaultIdPrefix: nodeId,\n modelName: toPascalCase(artifactClass),\n fileName: toKebabCase(artifactClass),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toPascalCase(s: string): string {\n return s\n .split(/[-_]/)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('');\n}\n\nfunction toKebabCase(s: string): string {\n return s\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[_\\s]+/g, '-')\n .toLowerCase();\n}\n","/**\n * Artifact class defaults for scaffold and config generation.\n *\n * Used by model-generator for annotationChecker code generation\n * and by config generator for speckeeper.config.ts artifacts section.\n */\n\nexport interface ArtifactClassDefaults {\n globs: string[];\n exclude?: string[];\n contentPatterns?: string[];\n}\n\nexport const ARTIFACT_CLASS_DEFAULTS: Record<string, ArtifactClassDefaults> = {\n test: {\n globs: ['test/**/*.test.ts', 'test/**/*.spec.ts', 'tests/**/*.test.ts', 'tests/**/*.spec.ts'],\n contentPatterns: ['/@verifies\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)/'],\n },\n 'e2e-test': {\n globs: ['e2e/**/*.spec.ts'],\n contentPatterns: ['/@verifies\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)/'],\n },\n 'unit-test': {\n globs: ['test/unit/**/*.test.ts'],\n contentPatterns: ['/@verifies\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)/'],\n },\n 'integration-test': {\n globs: ['test/integration/**/*.test.ts'],\n contentPatterns: ['/@verifies\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)/'],\n },\n typescript: {\n globs: ['src/**/*.ts'],\n exclude: ['src/**/*.test.ts', 'src/**/*.d.ts'],\n contentPatterns: ['/@implements\\\\s+([\\\\w-]+(?:[,\\\\s]+[\\\\w-]+)*)/'],\n },\n openapi: {\n globs: ['api/openapi.yaml', 'api/openapi.json'],\n },\n sqlschema: {\n globs: ['db/schema.sql', 'db/migration/*.sql'],\n },\n};\n\nexport const SPECIALIZED_CHECKER_MAP: Record<string, string> = {\n openapi: 'externalOpenAPIChecker',\n sqlschema: 'externalSqlSchemaChecker',\n};\n\nexport interface CheckerBindingInput {\n edgeType: 'implements' | 'verifiedBy';\n targetClass: string;\n}\n\nexport interface GeneratedCheckerCode {\n code: string;\n dslImports: string[];\n}\n\nexport function generateCheckerCode(\n bindings: CheckerBindingInput[],\n modelName: string,\n): GeneratedCheckerCode {\n const dslImports = new Set<string>(['annotationChecker']);\n for (const b of bindings) {\n const specialized = SPECIALIZED_CHECKER_MAP[b.targetClass];\n if (specialized) dslImports.add(specialized);\n }\n\n const checks = bindings.map((b) => {\n const specialized = SPECIALIZED_CHECKER_MAP[b.targetClass];\n const artifact = `'${b.targetClass}'`;\n const relationType = `'${b.edgeType}'`;\n if (specialized) {\n return `{ artifact: ${artifact}, relationType: ${relationType}, checker: ${specialized}() }`;\n }\n return `{ artifact: ${artifact}, relationType: ${relationType} }`;\n });\n\n let config: string;\n if (checks.length === 1) {\n config = checks[0]!;\n } else {\n config = `{\\n checks: [\\n ${checks.join(',\\n ')}\\n ],\\n }`;\n }\n\n const code = `protected externalChecker = annotationChecker<${modelName}>(${config});`;\n\n return {\n code,\n dslImports: Array.from(dslImports),\n };\n}\n","import type { ModelTemplateParams } from './types.js';\nimport { generateCheckerCode } from '../artifact-defaults.js';\n\nexport function generateBaseModel(params: ModelTemplateParams): string {\n const schemaName = `${params.modelName}Schema`;\n const className = `${params.modelName}Model`;\n\n const hasCheckerBindings =\n params.checkerBindings && params.checkerBindings.length > 0;\n const checkerGen = hasCheckerBindings\n ? generateCheckerCode(params.checkerBindings!, params.modelName)\n : null;\n\n const dslImportItems = ['requireField'];\n if (checkerGen) {\n dslImportItems.push(...checkerGen.dslImports);\n }\n const dslImportLine = `import { ${dslImportItems.join(', ')} } from 'speckeeper/dsl';`;\n\n const externalCheckerLine = checkerGen\n ? `\\n ${checkerGen.code}`\n : '';\n\n return `/**\n * ${params.modelName} Model Definition\n *\n * Generated by speckeeper scaffold — customise as needed.\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n${dslImportLine}\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const ${schemaName} = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type ${params.modelName} = z.input<typeof ${schemaName}>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass ${className} extends Model<typeof ${schemaName}> {\n readonly id = '${params.modelId}';\n readonly name = '${params.modelName}';\n readonly idPrefix = '${params.idPrefix}';\n readonly schema = ${schemaName};\n readonly description = '${params.description}';\n // TODO: adjust modelLevel\n protected modelLevel: ModelLevel = '${params.level}';\n\n protected lintRules: LintRule<${params.modelName}>[] = [\n requireField<${params.modelName}>('description'),\n ];\n\n protected exporters: Exporter<${params.modelName}>[] = [];${externalCheckerLine}\n}\n\nexport { ${className} };\n`;\n}\n","/**\n * Template registry — base template only\n *\n * All artifact classes use the same base template (FR-SCF-028).\n * Class-specific schemas, lint rules, and exporters are not pre-defined;\n * users customise the generated model after scaffold.\n */\nimport type { ModelTemplateParams } from './types.js';\nimport { generateBaseModel } from './base.js';\n\nexport type ModelTemplateFunction = (params: ModelTemplateParams) => string;\n\nexport const MODEL_TEMPLATE_FUNCTIONS: Record<string, ModelTemplateFunction> = {\n base: generateBaseModel,\n};\n","/**\n * Model file generator\n *\n * Generates _models/*.ts files for speckeeper-managed nodes\n * by resolving artifact class from mermaid node classes.\n */\nimport type {\n MermaidNode,\n ResolvedEdge,\n GeneratedFile,\n} from './types.js';\nimport { isCheckEdge } from './edge-vocabulary.js';\nimport { resolveModelTemplate } from './template-registry.js';\nimport { MODEL_TEMPLATE_FUNCTIONS } from './templates/index.js';\n\nexport { ARTIFACT_CLASS_DEFAULTS } from './artifact-defaults.js';\n\n// ---------------------------------------------------------------------------\n// Checker binding resolution\n// ---------------------------------------------------------------------------\n\nexport interface CheckerBinding {\n edgeType: 'implements' | 'verifiedBy';\n targetNodeId: string;\n targetClass: string;\n}\n\n/**\n * Determine checker bindings for a speckeeper node from its outgoing check edges.\n */\nexport function resolveCheckerBindings(\n _nodeId: string,\n outgoingEdges: ResolvedEdge[],\n nodes: Map<string, MermaidNode>,\n speckeeperClassName: string,\n): CheckerBinding[] {\n const isSpk = (id: string): boolean =>\n nodes.get(id)?.classes.includes(speckeeperClassName) ?? false;\n\n const bindings: CheckerBinding[] = [];\n const seen = new Set<string>();\n\n for (const edge of outgoingEdges) {\n if (!isCheckEdge(edge.vocabulary)) continue;\n if (isSpk(edge.targetId)) continue;\n\n if (seen.has(edge.targetId)) continue;\n seen.add(edge.targetId);\n\n const targetNode = nodes.get(edge.targetId);\n const targetClass = targetNode?.classes.find(c => c !== speckeeperClassName) ?? edge.targetId.toLowerCase();\n\n const edgeType = edge.normalizedLabel === 'verifiedBy' ? 'verifiedBy' as const : 'implements' as const;\n\n bindings.push({ edgeType, targetNodeId: edge.targetId, targetClass });\n }\n\n return bindings;\n}\n\n/**\n * Generate _models/*.ts file for a single speckeeper-managed node.\n *\n * Checker bindings from implements/verifiedBy edges are passed to the template\n * which generates annotationChecker() configuration code inside the model class.\n */\nexport function generateModelFile(\n node: MermaidNode,\n _incomingEdges: ResolvedEdge[],\n outgoingEdges: ResolvedEdge[],\n allNodes?: Map<string, MermaidNode>,\n): GeneratedFile {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const templateFn = MODEL_TEMPLATE_FUNCTIONS[templateInfo.templateName];\n\n const bindings = allNodes\n ? resolveCheckerBindings(node.id, outgoingEdges, allNodes, 'speckeeper')\n : [];\n\n const checkerBindings =\n bindings.length > 0\n ? bindings.map((b) => ({ edgeType: b.edgeType, targetClass: b.targetClass }))\n : undefined;\n\n const params = {\n modelId: templateInfo.fileName,\n modelName: templateInfo.modelName,\n idPrefix: templateInfo.defaultIdPrefix,\n level: templateInfo.defaultLevel,\n description: node.label ?? node.id,\n checkerBindings,\n };\n\n const content =\n !templateFn ? MODEL_TEMPLATE_FUNCTIONS['base'](params) : templateFn(params);\n\n return {\n relativePath: `_models/${templateInfo.fileName}.ts`,\n content,\n };\n}\n\n/**\n * Generate a spec data file that exports a SpecModule via defineSpecs().\n */\nexport function generateSpecDataFile(\n node: MermaidNode,\n): GeneratedFile {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const className = `${templateInfo.modelName}Model`;\n const typeName = templateInfo.modelName;\n const varName = toCamelCase(templateInfo.modelName) + 's';\n const fileName = templateInfo.fileName;\n\n const content = `/**\n * ${templateInfo.modelName} Specifications\n *\n * Generated by speckeeper scaffold — add your specs below.\n */\nimport { defineSpecs } from 'speckeeper';\nimport type { ${typeName} } from './_models/${fileName}';\nimport { ${className} } from './_models/${fileName}';\n\nconst ${varName}: ${typeName}[] = [\n // { id: '${templateInfo.defaultIdPrefix}-001', name: '...', description: '...' },\n];\n\nexport default defineSpecs(\n [${className}.instance, ${varName}],\n);\n`;\n\n return {\n relativePath: `${fileName}.ts`,\n content,\n };\n}\n\nfunction toCamelCase(pascalCase: string): string {\n return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);\n}\n\n/**\n * Generate design/index.ts that merges all spec data files.\n */\nexport function generateDesignIndex(\n speckeeperNodes: MermaidNode[],\n): GeneratedFile {\n const generated = new Set<string>();\n const specFiles: { varName: string; fileName: string }[] = [];\n\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const hasArtifactClass = node.classes.some(c => c !== 'speckeeper');\n const key = hasArtifactClass ? templateInfo.fileName : `base:${node.id}`;\n\n if (generated.has(key)) continue;\n generated.add(key);\n\n specFiles.push({\n varName: toCamelCase(templateInfo.modelName),\n fileName: templateInfo.fileName,\n });\n }\n\n const imports = specFiles\n .map(f => `import ${f.varName} from './${f.fileName}';`)\n .join('\\n');\n const args = specFiles.map(f => f.varName).join(', ');\n\n const content = `/**\n * Design entry point — generated by speckeeper scaffold\n */\nimport { mergeSpecs } from 'speckeeper';\n${imports}\n\nexport default mergeSpecs(${args});\n`;\n\n return {\n relativePath: 'index.ts',\n content,\n };\n}\n\n/**\n * Generate all model files for speckeeper-managed nodes.\n *\n * Multiple nodes with the same artifact class are de-duplicated\n * into a single model file (e.g. FR, SR, NFR with class 'requirement').\n */\nexport function generateAllModelFiles(\n speckeeperNodes: MermaidNode[],\n resolvedEdges: ResolvedEdge[],\n allNodes?: Map<string, MermaidNode>,\n): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n const generated = new Set<string>();\n\n const templateNodeGroups = new Map<string, MermaidNode[]>();\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const hasArtifactClass = node.classes.some(c => c !== 'speckeeper');\n const key = hasArtifactClass ? templateInfo.fileName : `base:${node.id}`;\n const group = templateNodeGroups.get(key) ?? [];\n group.push(node);\n templateNodeGroups.set(key, group);\n }\n\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const hasArtifactClass = node.classes.some(c => c !== 'speckeeper');\n const key = hasArtifactClass ? templateInfo.fileName : `base:${node.id}`;\n\n if (generated.has(key)) continue;\n generated.add(key);\n\n const groupNodes = templateNodeGroups.get(key) ?? [node];\n const groupNodeIds = new Set(groupNodes.map(n => n.id));\n const incoming = resolvedEdges.filter(e => groupNodeIds.has(e.targetId));\n const outgoing = resolvedEdges.filter(e => groupNodeIds.has(e.sourceId));\n files.push(generateModelFile(node, incoming, outgoing, allNodes));\n files.push(generateSpecDataFile(node));\n }\n\n files.push(generateDesignIndex(speckeeperNodes));\n\n return files;\n}\n","/**\n * Index file generator\n *\n * Generates _models/index.ts that re-exports all model classes\n * and provides an allModels array.\n */\nimport type { GeneratedFile } from './types.js';\n\ninterface ModelExportEntry {\n /** File name without .ts (e.g. 'requirement') */\n fileName: string;\n /** Class names to export (e.g. ['RequirementModel']) */\n classNames: string[];\n}\n\n/**\n * Derive model class names from generated model file content.\n *\n * Looks for `export { ClassName }` or `export { A, B }` at end of file.\n */\nfunction extractExportedClassNames(content: string): string[] {\n const match = content.match(/export\\s*\\{([^}]+)\\}\\s*;?\\s*$/m);\n if (!match) return [];\n return match[1].split(',').map(s => s.trim()).filter(Boolean);\n}\n\n/**\n * Generate _models/index.ts from a list of generated model files.\n */\nexport function generateModelsIndex(modelFiles: GeneratedFile[]): GeneratedFile {\n const entries: ModelExportEntry[] = [];\n\n for (const file of modelFiles) {\n const fileName = file.relativePath\n .replace(/^_models\\//, '')\n .replace(/\\.ts$/, '');\n const classNames = extractExportedClassNames(file.content);\n if (classNames.length > 0) {\n entries.push({ fileName, classNames });\n }\n }\n\n entries.sort((a, b) => a.fileName.localeCompare(b.fileName));\n\n const lines: string[] = [];\n lines.push('/**');\n lines.push(' * Model index — generated by speckeeper scaffold');\n lines.push(' */');\n lines.push('');\n\n for (const entry of entries) {\n lines.push(`export { ${entry.classNames.join(', ')} } from './${entry.fileName}.js';`);\n }\n\n lines.push('');\n\n const modelInstanceNames = entries.flatMap(e =>\n e.classNames.filter(n => n.endsWith('Model')),\n );\n\n if (modelInstanceNames.length > 0) {\n lines.push('import { Model } from \\'speckeeper\\';');\n lines.push('import type { ZodType } from \\'zod\\';');\n lines.push('');\n\n for (const entry of entries) {\n const models = entry.classNames.filter(n => n.endsWith('Model'));\n if (models.length > 0) {\n lines.push(`import { ${models.join(', ')} } from './${entry.fileName}.js';`);\n }\n }\n\n lines.push('');\n lines.push('// eslint-disable-next-line @typescript-eslint/no-explicit-any');\n lines.push('export const allModels: Model<ZodType>[] = [');\n\n for (const name of modelInstanceNames) {\n lines.push(` ${name}.instance as Model<ZodType>,`);\n }\n\n lines.push('];');\n }\n\n lines.push('');\n\n return {\n relativePath: '_models/index.ts',\n content: lines.join('\\n'),\n };\n}\n","/**\n * Scaffold Command\n *\n * Generate _models/ from a mermaid flowchart definition.\n * Checker logic is integrated into model definitions via core DSL factories.\n */\nimport chalk from 'chalk';\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { parseMarkdownFlowchart } from '../scaffold/mermaid-parser.js';\nimport { resolveEdges } from '../scaffold/edge-vocabulary.js';\nimport { generateAllModelFiles } from '../scaffold/model-generator.js';\nimport { generateModelsIndex } from '../scaffold/index-generator.js';\nimport type { GeneratedFile, MermaidNode, ScaffoldDiagnostic } from '../scaffold/types.js';\n\nconst SPECKEEPER_CLASS = 'speckeeper';\n\nexport interface ScaffoldCommandOptions {\n source: string;\n output?: string;\n force?: boolean;\n dryRun?: boolean;\n}\n\nexport async function scaffoldCommand(options: ScaffoldCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper scaffold'));\n console.log('');\n\n const sourcePath = resolve(options.source);\n if (!existsSync(sourcePath)) {\n console.error(chalk.red(` Error: Source file not found: ${sourcePath}`));\n process.exit(1);\n }\n\n const markdown = readFileSync(sourcePath, 'utf-8');\n\n const flowchart = parseMarkdownFlowchart(markdown);\n if (!flowchart) {\n console.error(chalk.red(' Error: No mermaid flowchart found in the source file'));\n process.exit(1);\n }\n\n console.log(chalk.gray(` Parsed: ${flowchart.nodes.size} nodes, ${flowchart.edges.length} edges`));\n\n const speckeeperNodes: MermaidNode[] = [];\n for (const node of flowchart.nodes.values()) {\n if (node.classes.includes(SPECKEEPER_CLASS)) {\n speckeeperNodes.push(node);\n }\n }\n\n if (speckeeperNodes.length === 0) {\n console.error(chalk.red(` Error: No nodes with class \"${SPECKEEPER_CLASS}\" found`));\n console.log(chalk.gray(' Add `classDef speckeeper ...` and `class NODE1,NODE2 speckeeper` to your flowchart'));\n process.exit(1);\n }\n\n console.log(chalk.gray(` speckeeper-managed nodes: ${speckeeperNodes.map(n => n.id).join(', ')}`));\n\n const { resolved, diagnostics } = resolveEdges(\n flowchart.edges,\n flowchart.nodes,\n SPECKEEPER_CLASS,\n );\n\n printDiagnostics(diagnostics);\n\n const outputDir = options.output\n ? resolve(options.output)\n : join(process.cwd(), 'design');\n\n const modelFiles = generateAllModelFiles(speckeeperNodes, resolved, flowchart.nodes);\n const indexFile = generateModelsIndex(modelFiles);\n\n const allFiles: GeneratedFile[] = [...modelFiles, indexFile];\n\n console.log('');\n console.log(chalk.cyan(` Files to generate (${allFiles.length}):`));\n for (const file of allFiles) {\n console.log(chalk.gray(` ${file.relativePath}`));\n }\n\n if (options.dryRun) {\n console.log('');\n console.log(chalk.yellow(' Dry run — no files written'));\n console.log('');\n for (const file of allFiles) {\n console.log(chalk.cyan(` === ${file.relativePath} ===`));\n console.log(file.content);\n }\n return;\n }\n\n console.log('');\n let created = 0;\n let skipped = 0;\n\n for (const file of allFiles) {\n const fullPath = join(outputDir, file.relativePath);\n const dir = dirname(fullPath);\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n if (existsSync(fullPath) && !options.force) {\n console.log(chalk.yellow(` Skipped: ${file.relativePath} (already exists, use --force to overwrite)`));\n skipped++;\n continue;\n }\n\n writeFileSync(fullPath, file.content);\n console.log(chalk.green(` Created: ${file.relativePath}`));\n created++;\n }\n\n console.log('');\n console.log(chalk.cyan(` Done: ${created} created, ${skipped} skipped`));\n}\n\nfunction printDiagnostics(diagnostics: ScaffoldDiagnostic[]): void {\n if (diagnostics.length === 0) return;\n\n console.log('');\n console.log(chalk.cyan(' Diagnostics:'));\n\n for (const diag of diagnostics) {\n const prefix = diag.severity === 'error'\n ? chalk.red(' ERROR')\n : diag.severity === 'warning'\n ? chalk.yellow(' WARN ')\n : chalk.gray(' INFO ');\n const ctx = diag.context ? chalk.gray(` [${diag.context}]`) : '';\n console.log(`${prefix} ${diag.message}${ctx}`);\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { buildCommand } from './build.js';\nimport { lintCommand } from './lint.js';\nimport { driftCommand } from './drift.js';\nimport { checkCommand } from './check.js';\nimport { newCommand } from './new.js';\nimport { impactCommand } from './impact.js';\nimport { runInit } from './init.js';\nimport { scaffoldCommand } from './scaffold.js';\n\nfunction getVersion(): string {\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\n return pkg.version;\n } catch {\n return '0.0.0';\n }\n}\n\nconst program = new Command();\n\nprogram\n .name('speckeeper')\n .description('Requirements and design management framework with TypeScript DSL')\n .version(getVersion());\n\n// Build command\n// Spec: design/cli-commands.ts CMD-BUILD\nprogram\n .command('build')\n .description('Generate docs/ and specs/ from TypeScript models')\n .option('-c, --config <path>', 'Path to config file')\n .option('-o, --output <path>', 'Base output directory path', '.')\n .option('-f, --format <format>', 'Output format: markdown, json, both', 'both')\n .option('-w, --watch', 'Watch for changes and auto-regenerate')\n .option('-v, --verbose', 'Show detailed output')\n .action(buildCommand);\n\n// Lint command\n// Spec: design/cli-commands.ts CMD-LINT\nprogram\n .command('lint')\n .description('Check design integrity (ID duplicates, references, layer violations, etc.)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-p, --phase <phase>', 'Phase gate to check against (REQ, HLD, LLD, OPS)')\n .option('-s, --strict', 'Treat warnings as errors')\n .option('--fix', 'Attempt to fix auto-fixable issues')\n .option('-f, --format <format>', 'Output format: text, json, github', 'text')\n .action(lintCommand);\n\n// Drift command\n// Spec: design/cli-commands.ts CMD-DRIFT\nprogram\n .command('drift')\n .description('Check if generated files have been manually edited')\n .option('-c, --config <path>', 'Path to config file')\n .option('-u, --update', 'Auto-update if differences are found')\n .option('-f, --format <format>', 'Output format: text, json, diff', 'text')\n .option('--fail-on-drift', 'Exit with code 1 if drift is detected (for CI)')\n .action(driftCommand);\n\n// Check command\n// Spec: design/cli-commands.ts CMD-CHECK\nprogram\n .command('check')\n .description('Check external SSOT conformance (including custom models)')\n .argument('[type]', 'Type of check: external-ssot, openapi, ddl, iac, custom, all, test')\n .option('-c, --config <path>', 'Path to config file')\n .option('--strict', 'Treat warnings as errors')\n .option('-v, --verbose', 'Show detailed output')\n .option('--coverage', 'Check if all testable acceptance criteria are covered by TestRefs')\n .action(checkCommand);\n\n// New command\n// Spec: design/cli-commands.ts CMD-NEW\nprogram\n .command('new')\n .description('Create a new element with auto-generated ID')\n .argument('<type>', 'Type: requirement, usecase, entity, component, screen, flow, error-case, term')\n .option('-k, --kind <kind>', 'Sub-kind (e.g., functional, non-functional for requirements)')\n .option('-n, --name <name>', 'Name of the element')\n .option('-o, --output <path>', 'Output directory path')\n .option('-t, --template <path>', 'Path to template file')\n .action(newCommand);\n\n// Impact command\n// Spec: design/cli-commands.ts CMD-IMPACT\nprogram\n .command('impact')\n .description('Analyze impact of changes to an ID')\n .argument('<id>', 'ID to analyze (e.g., REQ-001, ENT-ORDER)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --depth <depth>', 'Analysis depth (reference tracking level)', '3')\n .option('--direction <direction>', 'Analysis direction: upstream, downstream, both', 'both')\n .option('-f, --format <format>', 'Output format: text, json, mermaid', 'text')\n .action(impactCommand);\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new speckeeper project with starter templates')\n .option('-f, --force', 'Overwrite existing files')\n .action(runInit);\n\n// Scaffold command\nprogram\n .command('scaffold')\n .description('Generate _models/ from a mermaid flowchart definition')\n .requiredOption('-s, --source <path>', 'Path to Markdown file containing mermaid flowchart')\n .option('-o, --output <path>', 'Output directory (default: design/)')\n .option('-f, --force', 'Overwrite existing files')\n .option('--dry-run', 'Preview generated files without writing')\n .action(scaffoldCommand);\n\n// Parse arguments\nprogram.parse();\n"]}
1
+ {"version":3,"sources":["../src/utils/config-loader.ts","../src/utils/file-writer.ts","../src/core/relation.ts","../src/core/model.ts","../src/cli/build.ts","../src/cli/lint.ts","../src/cli/drift.ts","../src/core/dsl/type-compat.ts","../src/core/global-scanner.ts","../src/cli/check.ts","../src/cli/new.ts","../src/cli/impact.ts","../src/cli/init.ts","../src/scaffold/mermaid-parser.ts","../src/scaffold/edge-vocabulary.ts","../src/scaffold/template-registry.ts","../src/scaffold/templates/base.ts","../src/scaffold/templates/index.ts","../src/scaffold/model-generator.ts","../src/scaffold/index-generator.ts","../src/cli/scaffold.ts","../src/cli/index.ts"],"names":["parseYaml","existsSync","dirname","readFileSync","chalk","join","glob","models","model","writeFileSync","__filename","__dirname","mkdirSync","SPECKEEPER_CLASS","resolve","fileURLToPath"],"mappings":"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","file":"cli.js","sourcesContent":["import { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Specification-compliant output path definitions\n * \n * Human-readable artifacts (docs/):\n * requirements/ - Requirements Markdown\n * usecases/ - Use cases\n * architecture/ - Architecture (C4 diagrams)\n * data-model/ - Conceptual model (ER diagrams)\n * screens/ - Screen specifications\n * flows/ - Process flows\n * glossary/ - Glossary\n * \n * Machine-readable artifacts (specs/):\n * schemas/entities/ - Entity JSON Schema\n * index.json - Aggregated data\n */\nexport interface OutputPaths {\n // docs/ subdirectories\n requirements: string;\n usecases: string;\n architecture: string;\n dataModel: string;\n screens: string;\n flows: string;\n glossary: string;\n component: string;\n \n // specs/ subdirectories\n schemasEntities: string;\n}\n\nexport interface SpeckeeperConfig {\n // Project info\n projectName?: string;\n version?: string;\n \n // Source paths\n srcDir: string;\n requirementsDir?: string;\n designDir?: string;\n usecasesDir?: string;\n \n // Output paths\n docsDir: string;\n specsDir: string;\n \n // Global source definitions for spec ID scanning\n sources?: import('../core/config-api.js').SourceConfig[];\n \n // External SSOT paths\n externalSsot?: {\n openapi?: {\n enabled: boolean;\n paths: string[];\n microContracts?: {\n enabled: boolean;\n requiredExtensions?: string[];\n strictMode?: boolean;\n };\n };\n ddl?: {\n enabled: boolean;\n paths: string[];\n type: 'ddl' | 'prisma' | 'typeorm' | 'drizzle';\n };\n iac?: {\n enabled: boolean;\n paths: string[];\n type: 'cloudformation' | 'terraform' | 'cdk';\n };\n };\n \n // Lint configuration\n lint?: {\n architecture?: {\n allowCrossBoundaryDependencies?: boolean;\n allowCrossLayerViolations?: boolean;\n maxComponentsPerDiagram?: number;\n };\n conceptModel?: {\n requireEntityDescription?: boolean;\n requireAggregateRoot?: boolean;\n warnOnOrphanEntities?: boolean;\n namingConvention?: 'PascalCase' | 'camelCase' | 'snake_case' | 'none';\n };\n screen?: {\n warnOnOrphanScreens?: boolean;\n warnOnDeadEnds?: boolean;\n checkAuthPaths?: boolean;\n };\n phaseGate?: {\n currentPhase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strictMode?: boolean;\n };\n };\n \n // Build configuration\n build?: {\n generateMermaidImages?: boolean;\n mermaidCliPath?: string;\n };\n \n // Custom model definitions\n models?: unknown[];\n \n // Spec data entries (from design/index.ts via mergeSpecs())\n specs?: import('../core/model.js').SpecEntry[];\n}\n\n// Default configuration\nconst defaultConfig: SpeckeeperConfig = {\n srcDir: 'src',\n designDir: 'design', // Directory for requirements/design TS models\n docsDir: 'docs',\n specsDir: 'specs',\n};\n\n// ============================================================================\n// Output Paths (spec-compliant)\n// ============================================================================\n\n/**\n * Get output paths compliant with specification\n */\nexport function getOutputPaths(config: SpeckeeperConfig, cwd: string = process.cwd()): OutputPaths {\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n return {\n // docs/ subdirectories (compliant with spec section 7.1)\n requirements: join(docsDir, 'requirements'),\n usecases: join(docsDir, 'usecases'),\n architecture: join(docsDir, 'architecture'),\n dataModel: join(docsDir, 'data-model'),\n screens: join(docsDir, 'screens'),\n flows: join(docsDir, 'flows'),\n glossary: join(docsDir, 'glossary'),\n component: join(docsDir, 'component'),\n \n // specs/ subdirectories (compliant with spec section 7.1)\n schemasEntities: join(specsDir, 'schemas', 'entities'),\n };\n}\n\n/**\n * List of expected output paths (for drift check)\n */\nexport function getExpectedOutputDirs(config: SpeckeeperConfig, cwd: string = process.cwd()): string[] {\n const paths = getOutputPaths(config, cwd);\n return [\n paths.requirements,\n paths.usecases,\n paths.architecture,\n paths.dataModel,\n paths.screens,\n paths.flows,\n paths.glossary,\n paths.component,\n paths.schemasEntities,\n ];\n}\n\n/**\n * Validate if output path complies with specification\n */\nexport function validateOutputPaths(actualPath: string, config: SpeckeeperConfig, cwd: string = process.cwd()): {\n valid: boolean;\n expectedPaths: string[];\n message?: string;\n} {\n const expectedDirs = getExpectedOutputDirs(config, cwd);\n const docsDir = resolve(cwd, config.docsDir);\n const specsDir = resolve(cwd, config.specsDir);\n \n // Check if actualPath is under docs/ or specs/\n const isUnderDocs = actualPath.startsWith(docsDir);\n const isUnderSpecs = actualPath.startsWith(specsDir);\n \n if (!isUnderDocs && !isUnderSpecs) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" is not under docs/ or specs/`,\n };\n }\n \n // Check if under any of the expected paths\n const isValidPath = expectedDirs.some(dir => actualPath.startsWith(dir));\n \n if (!isValidPath) {\n return {\n valid: false,\n expectedPaths: expectedDirs,\n message: `Output path \"${actualPath}\" does not match spec-compliant paths. Expected one of: ${expectedDirs.map(d => d.replace(cwd + '/', '')).join(', ')}`,\n };\n }\n \n return { valid: true, expectedPaths: expectedDirs };\n}\n\n// ============================================================================\n// Configuration Loading\n// ============================================================================\n\nconst CONFIG_FILES = [\n 'speckeeper.config.yaml',\n 'speckeeper.config.yml',\n 'speckeeper.config.json',\n 'speckeeper.config.ts',\n 'speckeeper.config.js',\n];\n\nexport function findConfigFile(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n \n while (currentDir !== dirname(currentDir)) {\n for (const configFile of CONFIG_FILES) {\n const configPath = resolve(currentDir, configFile);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n currentDir = dirname(currentDir);\n }\n \n return null;\n}\n\nexport async function loadConfig(\n configPath?: string,\n cwd: string = process.cwd()\n): Promise<SpeckeeperConfig> {\n const resolvedPath = configPath ?? findConfigFile(cwd);\n \n if (!resolvedPath) {\n return { ...defaultConfig };\n }\n \n const ext = resolvedPath.split('.').pop()?.toLowerCase();\n \n try {\n if (ext === 'yaml' || ext === 'yml') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = parseYaml(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'json') {\n const content = readFileSync(resolvedPath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<SpeckeeperConfig>;\n return { ...defaultConfig, ...parsed };\n }\n \n if (ext === 'ts' || ext === 'js') {\n const module = await import(resolvedPath);\n const parsed = module.default ?? module;\n return { ...defaultConfig, ...parsed };\n }\n \n return { ...defaultConfig };\n } catch (error) {\n console.error(`Failed to load config from ${resolvedPath}:`, error);\n return { ...defaultConfig };\n }\n}\n\n// ============================================================================\n// Configuration Validation\n// ============================================================================\n\nexport function validateConfig(config: SpeckeeperConfig): string[] {\n const errors: string[] = [];\n \n if (!config.srcDir) {\n errors.push('srcDir is required');\n }\n \n if (!config.docsDir) {\n errors.push('docsDir is required');\n }\n \n if (!config.specsDir) {\n errors.push('specsDir is required');\n }\n \n return errors;\n}\n","import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createHash } from 'node:crypto';\n\n// ============================================================================\n// File Writing\n// ============================================================================\n\nexport interface WriteResult {\n path: string;\n created: boolean;\n updated: boolean;\n unchanged: boolean;\n}\n\nexport function ensureDir(dirPath: string): void {\n if (!existsSync(dirPath)) {\n mkdirSync(dirPath, { recursive: true });\n }\n}\n\nexport function writeFile(filePath: string, content: string): WriteResult {\n const dir = dirname(filePath);\n ensureDir(dir);\n \n const existed = existsSync(filePath);\n let unchanged = false;\n \n if (existed) {\n const existingContent = readFileSync(filePath, 'utf-8');\n unchanged = existingContent === content;\n }\n \n if (!unchanged) {\n writeFileSync(filePath, content, 'utf-8');\n }\n \n return {\n path: filePath,\n created: !existed,\n updated: existed && !unchanged,\n unchanged,\n };\n}\n\nexport function writeJsonFile(filePath: string, data: unknown, indent: number = 2): WriteResult {\n const content = JSON.stringify(data, null, indent) + '\\n';\n return writeFile(filePath, content);\n}\n\n// ============================================================================\n// Batch Writing\n// ============================================================================\n\nexport interface BatchWriteResult {\n results: WriteResult[];\n created: number;\n updated: number;\n unchanged: number;\n total: number;\n}\n\nexport function batchWriteFiles(\n files: Array<{ path: string; content: string }>\n): BatchWriteResult {\n const results: WriteResult[] = [];\n \n for (const { path, content } of files) {\n results.push(writeFile(path, content));\n }\n \n return {\n results,\n created: results.filter(r => r.created).length,\n updated: results.filter(r => r.updated).length,\n unchanged: results.filter(r => r.unchanged).length,\n total: results.length,\n };\n}\n\n// ============================================================================\n// Drift Detection\n// ============================================================================\n\nexport interface DriftResult {\n file: string;\n hasDrift: boolean;\n expectedHash?: string;\n actualHash?: string;\n missing?: boolean;\n}\n\nexport function computeHash(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function checkFileDrift(\n filePath: string,\n expectedContent: string\n): DriftResult {\n const expectedHash = computeHash(expectedContent);\n \n if (!existsSync(filePath)) {\n return {\n file: filePath,\n hasDrift: true,\n expectedHash,\n missing: true,\n };\n }\n \n const actualContent = readFileSync(filePath, 'utf-8');\n const actualHash = computeHash(actualContent);\n \n return {\n file: filePath,\n hasDrift: expectedHash !== actualHash,\n expectedHash,\n actualHash,\n };\n}\n\nexport function checkBatchDrift(\n files: Array<{ path: string; content: string }>\n): DriftResult[] {\n return files.map(({ path, content }) => checkFileDrift(path, content));\n}\n\n// ============================================================================\n// File Discovery\n// ============================================================================\n\nimport { glob } from 'glob';\n\nexport async function findFiles(\n pattern: string,\n cwd: string = process.cwd()\n): Promise<string[]> {\n return glob(pattern, { cwd, absolute: true });\n}\n\nexport async function findTypeScriptFiles(\n srcDir: string\n): Promise<string[]> {\n return findFiles('**/*.ts', srcDir);\n}\n\nexport async function findDefinitionFiles(\n srcDir: string,\n subDir: string\n): Promise<string[]> {\n const pattern = join(srcDir, subDir, '**/*.ts');\n return glob(pattern, { absolute: true, ignore: ['**/*.d.ts', '**/index.ts'] });\n}\n\n// ============================================================================\n// Output Helpers\n// ============================================================================\n\nexport function generateDocsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n\nexport function generateSpecsPath(\n baseDir: string,\n category: string,\n filename: string\n): string {\n return join(baseDir, category, filename);\n}\n","/**\n * Definition and validation of model relations\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// Model Levels\n// ============================================================================\n\n/**\n * Model abstraction level\n * \n * - L0: Business + Domain Analysis (Why / Problem space)\n * Desired outcomes/value, business flows, actors, terminology, business rules\n * - L1: Requirements (What)\n * Functional/non-functional requirements, constraints, acceptance criteria\n * - L2: Design (How / Direction)\n * Architecture, component breakdown, domain model, key sequences\n * - L3: Detailed Design/Implementation (How to build / Concrete artifacts)\n * Screen/API/DB definitions, external SSOT references\n */\nexport type ModelLevel = 'L0' | 'L1' | 'L2' | 'L3';\n\n/**\n * Get numeric index of level\n */\nexport function getLevelIndex(level: ModelLevel): number {\n return ['L0', 'L1', 'L2', 'L3'].indexOf(level);\n}\n\n// ============================================================================\n// Relation Types\n// ============================================================================\n\n/**\n * Relation types\n */\nexport const RELATION_TYPES = [\n 'dependsOn',\n 'uses',\n 'includes',\n 'implements',\n 'refines',\n 'verifies',\n 'verifiedBy',\n 'satisfies',\n 'traces',\n 'relatedTo',\n] as const;\n\nexport type RelationType = typeof RELATION_TYPES[number];\n\n/**\n * Relation schema\n */\nexport const RelationSchema = z.object({\n /** Relation type */\n type: z.enum(RELATION_TYPES),\n /** Target ID */\n target: z.string(),\n /** Description (optional) */\n description: z.string().optional(),\n});\n\n/**\n * Relation field to add to model schemas\n * Usage: schema.extend({ relations: RelationsFieldSchema })\n */\nexport const RelationsFieldSchema = z.array(RelationSchema).optional();\n\nexport type Relation = z.infer<typeof RelationSchema>;\n\n// ============================================================================\n// Relation Constraints\n// ============================================================================\n\n/**\n * Definition of relation constraints\n */\nexport interface RelationConstraint {\n /** Allowed target levels (all levels allowed if not specified) */\n allowedTargetLevels?: ModelLevel[];\n /** Level constraint rule */\n levelRule: 'source>target' | 'source>=target' | 'same' | 'any';\n /** Direction of impact propagation */\n propagation: 'forward' | 'backward' | 'both';\n}\n\n/**\n * Constraint definitions per relation type\n * \n * Level hierarchy:\n * L0 (Business) → L1 (Requirements) → L2 (Design) → L3 (Implementation)\n * Abstract ───────────────────────────→ Concrete\n */\nexport const RELATION_CONSTRAINTS: Record<RelationType, RelationConstraint> = {\n // Concrete→Abstract (implementation/design fulfills requirements)\n 'implements': {\n allowedTargetLevels: ['L1'], // Implements requirements\n levelRule: 'source>target',\n propagation: 'forward', // A changes → B needs review\n },\n // Concrete→Abstract (design/implementation satisfies business/requirements)\n 'satisfies': {\n allowedTargetLevels: ['L0', 'L1'], // Satisfies business/requirements\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A needs update\n },\n // Concrete→Abstract (refinement: requirements refine business, design refines requirements)\n 'refines': {\n allowedTargetLevels: ['L0', 'L1'], // Refines business/requirements\n levelRule: 'source>target',\n propagation: 'backward', // B changes → A needs update\n },\n // Test→Requirements/Business (verification relationship)\n 'verifies': {\n allowedTargetLevels: ['L0', 'L1'], // Verifies business/requirements\n levelRule: 'any',\n propagation: 'backward', // B changes → A needs update\n },\n // Dependencies (same level or concrete→abstract)\n 'dependsOn': {\n levelRule: 'source>=target',\n propagation: 'backward', // B changes → A affected\n },\n // Usage relationship (no level constraint)\n 'uses': {\n levelRule: 'any',\n propagation: 'backward', // B changes → A affected\n },\n // Inclusion relationship (same level only)\n 'includes': {\n levelRule: 'same',\n propagation: 'backward', // B changes → A affected\n },\n // Bidirectional tracing\n 'traces': {\n levelRule: 'any',\n propagation: 'both',\n },\n // Spec→Test (verification relationship: spec is verified by test code)\n 'verifiedBy': {\n allowedTargetLevels: ['L2', 'L3'],\n levelRule: 'any',\n propagation: 'backward',\n },\n // General relation\n 'relatedTo': {\n levelRule: 'any',\n propagation: 'both',\n },\n};\n\n// ============================================================================\n// Relation Validation\n// ============================================================================\n\n/**\n * Relation validation result\n */\nexport interface RelationValidationResult {\n valid: boolean;\n errors: RelationValidationError[];\n}\n\n/**\n * Relation validation error\n */\nexport interface RelationValidationError {\n type: 'level_violation' | 'target_level_violation' | 'self_reference' | 'cycle_detected';\n message: string;\n relation: Relation;\n sourceId: string;\n}\n\n/**\n * Validate level constraint for single relation\n * \n * @param sourceLevel - Source model level (set in _models/)\n * @param sourceSpecId - Source spec ID\n * @param relation - Relation\n * @param targetLevel - Target model level\n */\nexport function validateRelationLevel(\n sourceLevel: ModelLevel | undefined,\n sourceSpecId: string,\n relation: Relation,\n targetLevel: ModelLevel | undefined,\n): RelationValidationError | null {\n // Self-reference check\n if (sourceSpecId === relation.target) {\n return {\n type: 'self_reference',\n message: `Self-reference is not allowed: ${sourceSpecId} → ${relation.target}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n\n // Skip if level is undefined\n if (!sourceLevel || !targetLevel) {\n return null;\n }\n \n const constraint = RELATION_CONSTRAINTS[relation.type];\n \n // Target level constraint check\n if (constraint.allowedTargetLevels && \n !constraint.allowedTargetLevels.includes(targetLevel)) {\n return {\n type: 'target_level_violation',\n message: `'${relation.type}' relation target must be ${constraint.allowedTargetLevels.join(' or ')}, but target is ${targetLevel}`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n \n // Level direction constraint check\n const srcIdx = getLevelIndex(sourceLevel);\n const tgtIdx = getLevelIndex(targetLevel);\n \n switch (constraint.levelRule) {\n case 'source>target':\n if (srcIdx <= tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'source>=target':\n if (srcIdx < tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) to be same or more concrete than target (${targetLevel})`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n case 'same':\n if (srcIdx !== tgtIdx) {\n return {\n type: 'level_violation',\n message: `'${relation.type}' requires source (${sourceLevel}) and target (${targetLevel}) to be same level`,\n relation,\n sourceId: sourceSpecId,\n };\n }\n break;\n }\n \n return null;\n}\n\n/**\n * Detect circular references\n */\nexport function detectCycles(\n relations: Array<{ sourceId: string; targetId: string; type: RelationType }>,\n): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const graph = new Map<string, Set<string>>();\n const relationMap = new Map<string, Relation>();\n \n // Build graph\n for (const rel of relations) {\n if (!graph.has(rel.sourceId)) {\n graph.set(rel.sourceId, new Set());\n }\n graph.get(rel.sourceId)!.add(rel.targetId);\n relationMap.set(`${rel.sourceId}→${rel.targetId}`, { type: rel.type, target: rel.targetId });\n }\n \n // Detect cycles using DFS\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cyclePath: string[] = [];\n \n function dfs(node: string): boolean {\n visited.add(node);\n recursionStack.add(node);\n cyclePath.push(node);\n \n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) {\n return true;\n }\n } else if (recursionStack.has(neighbor)) {\n // Cycle detected\n const cycleStart = cyclePath.indexOf(neighbor);\n const cycle = cyclePath.slice(cycleStart);\n cycle.push(neighbor); // Close the cycle\n \n errors.push({\n type: 'cycle_detected',\n message: `Circular reference detected: ${cycle.join(' → ')}`,\n relation: relationMap.get(`${node}→${neighbor}`)!,\n sourceId: node,\n });\n return true;\n }\n }\n }\n \n cyclePath.pop();\n recursionStack.delete(node);\n return false;\n }\n \n for (const node of graph.keys()) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n \n return errors;\n}\n\n/**\n * Infer model ID from spec ID (prefix-based)\n */\nexport function inferModelIdFromSpecId(specId: string): string | undefined {\n const prefixMap: Record<string, string> = {\n 'REQ': 'requirement',\n 'CR': 'constraint',\n 'UC': 'usecase',\n 'ACTOR': 'actor',\n 'TERM': 'term',\n 'COMP': 'component',\n 'ENT': 'entity',\n 'FLOW': 'process-flow',\n 'LAYER': 'layer',\n 'BND': 'boundary',\n 'SCR': 'screen',\n 'API': 'api-ref',\n 'TBL': 'table-ref',\n 'IAC': 'iac-ref',\n 'BATCH': 'batch-ref',\n };\n \n for (const [prefix, modelId] of Object.entries(prefixMap)) {\n if (specId.startsWith(prefix + '-')) {\n return modelId;\n }\n }\n \n return undefined;\n}\n","/**\n * Model base class\n * \n * All model definitions inherit from this class\n */\nimport { z, ZodType } from 'zod';\nimport {\n type ModelLevel,\n type Relation,\n type RelationValidationError,\n validateRelationLevel,\n detectCycles,\n inferModelIdFromSpecId,\n} from './relation.js';\n\n// Re-export relation types\nexport type { ModelLevel, Relation, RelationValidationError };\nexport { RELATION_TYPES, RELATION_CONSTRAINTS, RelationSchema, RelationsFieldSchema } from './relation.js';\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * Lint rule definition\n */\nexport interface LintRule<T> {\n id: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n check: (spec: T) => boolean; // true if there is an issue\n}\n\n/**\n * Lint result\n */\nexport interface LintResult {\n ruleId: string;\n severity: 'error' | 'warning' | 'info';\n message: string;\n specId?: string;\n}\n\n/**\n * Exporter definition\n */\nexport interface Exporter<T> {\n format: 'markdown' | 'json' | 'mermaid';\n single?: (spec: T) => string;\n index?: (specs: T[]) => string;\n /** Subdirectory under docsDir (used with single + index/index.md) */\n outputDir?: string;\n /** Direct output file path relative to docsDir (used with index-only exporters) */\n outputFile?: string;\n filename?: (spec: T) => string;\n}\n\n/**\n * External checker definition\n */\nexport interface ExternalChecker<T> {\n targetType: string; // 'openapi' | 'ddl' | 'cli' etc.\n sourcePath: (spec: T) => string;\n check: (spec: T, externalData: unknown) => CheckResult;\n}\n\n/**\n * Check result\n */\nexport interface CheckResult {\n success: boolean;\n errors: { message: string; field?: string; specId?: string }[];\n warnings: { message: string; field?: string; specId?: string }[];\n /** Files where annotations matching this spec were found */\n matchedFiles?: Array<{\n specId: string;\n filePath: string;\n line: number;\n relationType: 'verifiedBy' | 'implements' | 'traces';\n }>;\n}\n\n// ============================================================================\n// Deep Validation (replaces per-model externalChecker)\n// ============================================================================\n\n/** OpenAPI deep validation mapping */\nexport interface OpenAPIValidationMapping {\n path: string;\n method?: string;\n parameters?: Array<{ name: string; in?: string; type?: string }>;\n responseProperties?: Array<{ name: string; type?: string }>;\n}\n\n/** DDL deep validation mapping */\nexport interface DDLValidationMapping {\n tableName: string;\n columns?: Array<{ name: string; type?: string }>;\n checkTypes?: boolean;\n}\n\n/**\n * Deep validation rule for a specific source type.\n * The mapper extracts expected structure from a spec for detailed comparison\n * against the matched source object.\n */\nexport interface DeepValidationRule<T, TMapping = unknown> {\n mapper: (spec: T) => TMapping;\n}\n\n/**\n * Deep validation configuration keyed by source type.\n * Models define this to enable Level 2/3 checks beyond existence.\n */\nexport interface DeepValidationConfig<T> {\n openapi?: DeepValidationRule<T, OpenAPIValidationMapping>;\n ddl?: DeepValidationRule<T, DDLValidationMapping>;\n [sourceType: string]: DeepValidationRule<T, unknown> | undefined;\n}\n\n/**\n * Coverage result\n */\nexport interface CoverageResult {\n /** Total target count */\n total: number;\n /** Covered count */\n covered: number;\n /** Uncovered count */\n uncovered: number;\n /** Coverage rate (%) */\n coveragePercent: number;\n /** Details of covered items */\n coveredItems: { id: string; description?: string }[];\n /** Details of uncovered items */\n uncoveredItems: { id: string; description?: string; sourceId?: string }[];\n}\n\n/**\n * Coverage checker definition\n * \n * Verify cross-model consistency (coverage).\n * Example: Whether TestRef covers acceptanceCriteria of Requirement\n */\nexport interface CoverageChecker<T> {\n /** Target model ID for coverage (e.g. 'requirement') */\n targetModel: string;\n /** Description of coverage check */\n description: string;\n /** Execute coverage check */\n check: (\n specs: T[],\n registry: Record<string, Map<string, unknown>>\n ) => CoverageResult;\n}\n\n// ============================================================================\n// Renderer (for embeds)\n// ============================================================================\n\n/**\n * Render context\n * Simplified version compatible with embedoc's EmbedContext\n */\nexport interface RenderContext {\n /** Parameters (filter conditions other than format, etc.) */\n params: Record<string, string | undefined>;\n /** Markdown helpers */\n markdown: {\n /** Generate table */\n table: (headers: string[], rows: (string | unknown)[][]) => string;\n };\n}\n\n/**\n * Renderer definition\n * \n * Model-specific rendering called from embeds\n */\nexport interface Renderer<T> {\n /** Format ID ('table', 'list', 'detail', 'spec-chapter', etc.) */\n format: string;\n /** Rendering process */\n render: (specs: T[], ctx: RenderContext) => string;\n}\n\n// ============================================================================\n// Model Base Class\n// ============================================================================\n\n/**\n * Model base class\n * \n * @template TSchema - Zod schema type\n */\nexport abstract class Model<TSchema extends ZodType> {\n /** Singleton instance storage (per subclass) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private static _instances: WeakMap<new () => any, Model<ZodType>> = new WeakMap();\n\n /**\n * Get singleton instance of the model\n * Usage: RequirementModel.instance\n */\n static get instance(): Model<ZodType> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ctor = this as unknown as new () => any;\n if (!this._instances.has(ctor)) {\n this._instances.set(ctor, new ctor());\n }\n return this._instances.get(ctor)!;\n }\n\n /** Model ID ('requirement', 'usecase', etc.) */\n abstract readonly id: string;\n \n /** Model name ('Requirement', 'UseCase', etc.) */\n abstract readonly name: string;\n \n /** ID prefix ('REQ', 'UC', etc.) */\n abstract readonly idPrefix: string;\n \n /** Zod schema */\n abstract readonly schema: TSchema;\n \n /** Model description (optional) */\n readonly description?: string;\n \n /** External SSOT type (optional, e.g. 'OpenAPI', 'DDL/Prisma') */\n readonly externalSsotType?: string;\n \n /** Spec instance type */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected get specType(): z.infer<TSchema> { return undefined as any; }\n \n /** Lint rules (override in subclass) */\n protected lintRules: LintRule<z.infer<TSchema>>[] = [];\n \n /** Exporters (override in subclass) */\n protected exporters: Exporter<z.infer<TSchema>>[] = [];\n \n /** External checker (optional) — deprecated, use deepValidation instead */\n protected externalChecker?: ExternalChecker<z.infer<TSchema>>;\n \n /** Deep validation rules keyed by source type (replaces externalChecker) */\n protected deepValidation?: DeepValidationConfig<z.infer<TSchema>>;\n \n /** Coverage checker (optional) */\n protected coverageChecker?: CoverageChecker<z.infer<TSchema>>;\n \n /** Model level (set in _models/) */\n protected modelLevel?: ModelLevel;\n \n /** Renderers (for embeds, override in subclass) */\n protected renderers: Renderer<z.infer<TSchema>>[] = [];\n \n /**\n * Get model level\n * Returns modelLevel set in _models/\n */\n get level(): ModelLevel | undefined {\n return this.modelLevel;\n }\n \n /**\n * Execute schema validation\n */\n validate(spec: unknown): z.infer<TSchema> {\n return this.schema.parse(spec);\n }\n \n /**\n * Schema validation (safe version, returns error object on failure)\n */\n safeParse(spec: unknown): { success: true; data: z.infer<TSchema> } | { success: false; error: z.ZodError } {\n return this.schema.safeParse(spec);\n }\n \n /**\n * Execute lint\n */\n lint(spec: z.infer<TSchema>): LintResult[] {\n const specId = (spec as { id?: string }).id;\n return this.lintRules\n .filter(rule => rule.check(spec))\n .map(rule => ({\n ruleId: rule.id,\n severity: rule.severity,\n message: rule.message,\n specId,\n }));\n }\n \n /**\n * Execute lint for multiple specs\n */\n lintAll(specs: z.infer<TSchema>[]): LintResult[] {\n return specs.flatMap(spec => this.lint(spec));\n }\n \n /**\n * Validate level constraints of relations\n * @param spec - Spec instance (if it has relations property)\n * @returns Array of validation errors\n */\n validateRelations(spec: z.infer<TSchema>): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n \n if (!specWithRelations.relations || !specWithRelations.id) {\n return errors;\n }\n \n // Get all models to retrieve target model levels\n const allModels = getAllModels();\n const modelLevelMap = new Map<string, ModelLevel | undefined>();\n for (const model of allModels) {\n modelLevelMap.set(model.id, model.level);\n }\n \n for (const relation of specWithRelations.relations) {\n // Infer target model ID\n const targetModelId = inferModelIdFromSpecId(relation.target);\n if (!targetModelId) {\n continue; // Skip if model ID cannot be inferred\n }\n \n const targetLevel = modelLevelMap.get(targetModelId);\n \n const error = validateRelationLevel(\n this.level,\n specWithRelations.id,\n relation,\n targetLevel,\n );\n \n if (error) {\n errors.push(error);\n }\n }\n \n return errors;\n }\n \n /**\n * Validate relations of multiple specs (including circular reference check)\n */\n validateAllRelations(specs: z.infer<TSchema>[]): RelationValidationError[] {\n const errors: RelationValidationError[] = [];\n const allRelations: Array<{ sourceId: string; targetId: string; type: string }> = [];\n \n for (const spec of specs) {\n // Individual level constraint check\n errors.push(...this.validateRelations(spec));\n \n // Collect relations for circular reference check\n const specWithRelations = spec as { id?: string; relations?: Relation[] };\n if (specWithRelations.relations && specWithRelations.id) {\n for (const rel of specWithRelations.relations) {\n allRelations.push({\n sourceId: specWithRelations.id,\n targetId: rel.target,\n type: rel.type,\n });\n }\n }\n }\n \n // Circular reference check\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n errors.push(...detectCycles(allRelations as any));\n \n return errors;\n }\n \n /**\n * Export in specified format (single spec)\n */\n exportSingle(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.single) return null;\n return exporter.single(spec);\n }\n \n /**\n * Export in specified format (index)\n */\n exportIndex(specs: z.infer<TSchema>[], format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.index) return null;\n return exporter.index(specs);\n }\n \n /**\n * Get exporter output directory\n */\n getOutputDir(format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n return exporter?.outputDir ?? null;\n }\n \n /**\n * Get filename\n */\n getFilename(spec: z.infer<TSchema>, format: string): string | null {\n const exporter = this.exporters.find(e => e.format === format);\n if (!exporter?.filename) return null;\n return exporter.filename(spec);\n }\n \n /**\n * Check consistency with external SSOT\n */\n check(spec: z.infer<TSchema>, externalData: unknown): CheckResult {\n if (!this.externalChecker) {\n return { success: true, errors: [], warnings: [] };\n }\n return this.externalChecker.check(spec, externalData);\n }\n \n /**\n * Get external SSOT path\n */\n getExternalSourcePath(spec: z.infer<TSchema>): string | null {\n if (!this.externalChecker) return null;\n return this.externalChecker.sourcePath(spec);\n }\n \n /**\n * Execute coverage check\n * @param specs - Array of spec instances for this model\n * @param registry - Registry of all models\n */\n checkCoverage(\n specs: z.infer<TSchema>[],\n registry: Record<string, Map<string, unknown>>\n ): CoverageResult | null {\n if (!this.coverageChecker) return null;\n return this.coverageChecker.check(specs, registry);\n }\n \n /**\n * Get coverage checker\n */\n getCoverageChecker(): CoverageChecker<z.infer<TSchema>> | undefined {\n return this.coverageChecker;\n }\n \n /**\n * Get deep validation config\n */\n getDeepValidation(): DeepValidationConfig<z.infer<TSchema>> | undefined {\n return this.deepValidation;\n }\n \n /**\n * Get lint rules\n */\n getLintRules(): LintRule<z.infer<TSchema>>[] {\n return this.lintRules;\n }\n \n /**\n * Get exporters\n */\n getExporters(): Exporter<z.infer<TSchema>>[] {\n return this.exporters;\n }\n \n // ============================================================================\n // Renderer (for embeds)\n // ============================================================================\n \n /**\n * Render in specified format\n * @param format - Format ID ('table', 'list', 'detail', etc.)\n * @param specs - Array of specs to render\n * @param ctx - Render context\n * @returns Rendered result (Markdown string), null if no matching renderer\n */\n render(format: string, specs: z.infer<TSchema>[], ctx: RenderContext): string | null {\n const renderer = this.renderers.find(r => r.format === format);\n if (!renderer) return null;\n return renderer.render(specs, ctx);\n }\n \n /**\n * Get list of available formats\n */\n getAvailableFormats(): string[] {\n return this.renderers.map(r => r.format);\n }\n \n /**\n * Get renderers\n */\n getRenderers(): Renderer<z.infer<TSchema>>[] {\n return this.renderers;\n }\n \n /**\n * Check if renderer exists for specific format\n */\n hasRenderer(format: string): boolean {\n return this.renderers.some(r => r.format === format);\n }\n \n /**\n * Register spec instances for this model.\n * Stores specs in the global specStore keyed by this model's id.\n */\n register(specs: z.infer<TSchema>[]): void {\n if (!specStore.has(this.id)) {\n specStore.set(this.id, new Map());\n }\n const map = specStore.get(this.id)!;\n for (const spec of specs) {\n map.set((spec as { id: string }).id, spec);\n }\n }\n}\n\n// ============================================================================\n// Spec Store\n// ============================================================================\n\nconst specStore = new Map<string, Map<string, unknown>>();\n\n/**\n * Get the global spec store (model ID → spec ID → spec data)\n */\nexport function getSpecStore(): Map<string, Map<string, unknown>> {\n return specStore;\n}\n\n/**\n * Reset the spec store (clears all registered specs)\n */\nexport function resetSpecStore(): void {\n specStore.clear();\n}\n\n// ============================================================================\n// Model Registry\n// ============================================================================\n\n/** Map of registered models */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst modelRegistry = new Map<string, Model<any>>();\n\n/**\n * Register model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function registerModel(model: Model<any>): void {\n modelRegistry.set(model.id, model);\n}\n\n/**\n * Get model\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getModel(id: string): Model<any> | undefined {\n return modelRegistry.get(id);\n}\n\n/**\n * Get all registered models\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getAllModels(): Model<any>[] {\n return Array.from(modelRegistry.values());\n}\n\n/**\n * Clear registry\n */\nexport function clearModelRegistry(): void {\n modelRegistry.clear();\n}\n\n/**\n * Register model instances from config.models array.\n * Filters out non-Model values. Call this once after config is loaded.\n */\nexport function registerModelsFromConfig(models: unknown[]): void {\n for (const model of models) {\n if (model && typeof model === 'object' && 'id' in model && 'schema' in model) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n registerModel(model as Model<any>);\n }\n }\n}\n\n/**\n * Get specs for a given model ID from specStore\n */\nexport function getSpecs(modelId: string): unknown[] {\n const map = specStore.get(modelId);\n if (!map) return [];\n return Array.from(map.values());\n}\n\n/**\n * Get all spec IDs across all models\n */\nexport function getAllSpecIds(): Set<string> {\n const ids = new Set<string>();\n for (const map of specStore.values()) {\n for (const id of map.keys()) {\n ids.add(id);\n }\n }\n return ids;\n}\n\n/**\n * Find which model type a spec ID belongs to\n */\nexport function findModelTypeBySpecId(specId: string): string | null {\n for (const [modelId, map] of specStore) {\n if (map.has(specId)) return modelId;\n }\n return null;\n}\n\n/**\n * Get a spec by ID (searches all models)\n */\nexport function getSpecById(specId: string): { modelId: string; spec: unknown } | null {\n const modelId = findModelTypeBySpecId(specId);\n if (!modelId) return null;\n return { modelId, spec: specStore.get(modelId)!.get(specId) };\n}\n\n// ============================================================================\n// SpecModule: Common interface for spec data files\n// ============================================================================\n\n/**\n * A single (Model, data[]) pair.\n * Uses structural typing (not nominal Model<any>) so that\n * compiled dist/ Model instances are compatible with src/ types.\n */\nexport interface SpecEntry {\n model: { id: string; register: (data: unknown[]) => void };\n data: unknown[];\n}\n\n/**\n * Common export interface for spec data files.\n * Each spec file exports a SpecModule via defineSpecs().\n */\nexport interface SpecModule {\n entries: SpecEntry[];\n}\n\n/**\n * Aggregated result from mergeSpecs().\n */\nexport interface MergedDesign {\n models: SpecEntry['model'][];\n specs: SpecEntry[];\n}\n\n/**\n * Define spec data in a spec file. Returns a SpecModule.\n *\n * @example\n * ```typescript\n * export default defineSpecs(\n * [FunctionalRequirementModel.instance, functionalRequirements],\n * [NonFunctionalRequirementModel.instance, nonFunctionalRequirements],\n * );\n * ```\n */\nexport function defineSpecs(...entries: [SpecEntry['model'], unknown[]][]): SpecModule {\n return {\n entries: entries.map(([model, data]) => ({ model, data })),\n };\n}\n\n/**\n * Merge multiple SpecModules into a single MergedDesign.\n * Models are deduplicated by model.id.\n *\n * @example\n * ```typescript\n * // design/index.ts\n * export default mergeSpecs(requirements, usecases, glossary);\n * ```\n */\nexport function mergeSpecs(...modules: SpecModule[]): MergedDesign {\n const modelMap = new Map<string, SpecEntry['model']>();\n const allSpecs: SpecEntry[] = [];\n\n for (const mod of modules) {\n for (const entry of mod.entries) {\n modelMap.set(entry.model.id, entry.model);\n allSpecs.push(entry);\n }\n }\n\n return {\n models: Array.from(modelMap.values()),\n specs: allSpecs,\n };\n}\n\n/**\n * Build a registry (modelId -> Map<specId, spec>) from config.specs.\n * Pure function — no global state.\n */\nexport function buildRegistryFromConfig(\n specs: SpecEntry[] | undefined\n): Record<string, Map<string, unknown>> {\n const registry: Record<string, Map<string, unknown>> = {};\n if (!specs) return registry;\n for (const entry of specs) {\n if (!registry[entry.model.id]) {\n registry[entry.model.id] = new Map();\n }\n const map = registry[entry.model.id];\n for (const spec of entry.data) {\n map.set((spec as { id: string }).id, spec);\n }\n }\n return registry;\n}\n\n/**\n * Get specs for a model ID from config.specs.\n * Pure function — no global state.\n */\nexport function getSpecsFromConfig(\n specs: SpecEntry[] | undefined,\n modelId: string\n): unknown[] {\n if (!specs) return [];\n return specs\n .filter(e => e.model.id === modelId)\n .flatMap(e => e.data);\n}\n\n/**\n * Find which model type a spec ID belongs to, from config.specs.\n * Pure function — no global state.\n */\nexport function findModelTypeFromConfig(\n specs: SpecEntry[] | undefined,\n specId: string\n): string | null {\n if (!specs) return null;\n for (const entry of specs) {\n for (const spec of entry.data) {\n if ((spec as { id: string }).id === specId) {\n return entry.model.id;\n }\n }\n }\n return null;\n}\n","/**\n * Build Command\n * \n * Generate documents and schemas using model class exporters\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { batchWriteFiles, ensureDir } from '../utils/file-writer.js';\nimport { getSpecsFromConfig } from '../core/model.js';\n\n// ============================================================================\n// Build Command Options\n// ============================================================================\n\nexport interface BuildCommandOptions {\n config?: string;\n output?: string;\n format?: 'markdown' | 'json' | 'both';\n verbose?: boolean;\n clean?: boolean;\n}\n\n// ============================================================================\n// Build Command\n// ============================================================================\n\nexport async function buildCommand(options: BuildCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper build'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log(chalk.gray(` Specs: ${config.specsDir}/`));\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n ensureDir(join(cwd, config.docsDir));\n ensureDir(join(cwd, config.specsDir));\n \n const files: Array<{ path: string; content: string }> = [];\n \n if (models.length === 0) {\n console.log(chalk.yellow(' No models registered. Add models to speckeeper.config.ts.'));\n return;\n }\n \n console.log(chalk.blue(` Processing ${models.length} model types...`));\n \n for (const model of models) {\n const exporters = model.getExporters();\n \n if (exporters.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no exporters defined`));\n }\n continue;\n }\n \n const modelSpecs = getSpecsFromConfig(specs, model.id);\n \n if (modelSpecs.length === 0) {\n if (options.verbose) {\n console.log(chalk.gray(` ${model.name}: no specs found`));\n }\n continue;\n }\n \n for (const exporter of exporters) {\n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n if (exporter.single) {\n ensureDir(outputDir);\n }\n \n if (exporter.single) {\n for (const spec of modelSpecs) {\n const content = exporter.single(spec);\n const filename = model.getFilename(spec, exporter.format) || (spec as { id: string }).id;\n files.push({\n path: join(outputDir, `${filename}.md`),\n content,\n });\n }\n }\n \n if (exporter.index) {\n const indexContent = exporter.index(modelSpecs);\n const indexPath = exporter.outputFile\n ? join(cwd, config.docsDir, exporter.outputFile)\n : join(outputDir, 'index.md');\n if (!exporter.outputFile) {\n ensureDir(outputDir);\n }\n files.push({\n path: indexPath,\n content: indexContent,\n });\n }\n }\n \n console.log(chalk.green(` ✓ ${model.name}`));\n }\n \n if (files.length > 0) {\n console.log('');\n console.log(chalk.blue(` Writing ${files.length} files...`));\n \n const result = await batchWriteFiles(files);\n \n console.log('');\n console.log(chalk.green(` ✓ Build complete`));\n console.log(chalk.gray(` Created: ${result.created}`));\n console.log(chalk.gray(` Updated: ${result.updated}`));\n console.log(chalk.gray(` Unchanged: ${result.unchanged}`));\n } else {\n console.log(chalk.yellow(' No files to generate.'));\n }\n \n } catch (error) {\n console.error(chalk.red('Build failed:'), error);\n process.exit(1);\n }\n}\n","/**\n * Lint Command\n * \n * Execute design consistency checks using model class lintRules\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getSpecsFromConfig, type SpecEntry } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface LintCommandOptions {\n config?: string;\n phase?: 'REQ' | 'HLD' | 'LLD' | 'OPS';\n strict?: boolean;\n fix?: boolean;\n format?: 'text' | 'json' | 'github';\n}\n\nexport type LintSeverity = 'error' | 'warning' | 'info';\n\nexport interface LintIssue {\n rule: string;\n severity: LintSeverity;\n message: string;\n specId?: string;\n modelType?: string;\n}\n\nexport interface LintResult {\n issues: LintIssue[];\n errors: number;\n warnings: number;\n infos: number;\n}\n\n// ============================================================================\n// Lint Command\n// ============================================================================\n\nexport async function lintCommand(options: LintCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper lint'));\n console.log('');\n \n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n if (options.phase) {\n console.log(chalk.gray(` Phase: ${options.phase}`));\n }\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n console.log(chalk.gray(` Loaded: ${models.length} models`));\n console.log('');\n \n console.log(chalk.blue(' Running lint checks...'));\n const result = runModelLint(models, specs, options);\n \n console.log('');\n outputLintResults(result, options);\n \n if (result.errors > 0) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Lint failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Lint Runner\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction runModelLint(models: any[], specs: SpecEntry[] | undefined, options: LintCommandOptions): LintResult {\n const issues: LintIssue[] = [];\n \n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n \n if (modelSpecs.length === 0) continue;\n \n const lintResults = model.lintAll(modelSpecs);\n \n for (const result of lintResults) {\n issues.push({\n rule: result.ruleId,\n severity: result.severity,\n message: result.message,\n specId: result.specId,\n modelType: model.name,\n });\n }\n }\n \n const errors = issues.filter(i => i.severity === 'error').length;\n const warnings = issues.filter(i => i.severity === 'warning').length;\n const infos = issues.filter(i => i.severity === 'info').length;\n \n if (!options.strict) {\n return {\n issues: issues.filter(i => i.severity !== 'info'),\n errors,\n warnings,\n infos,\n };\n }\n \n return { issues, errors, warnings, infos };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputLintResults(result: LintResult, options: LintCommandOptions): void {\n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'github') {\n for (const issue of result.issues) {\n const level = issue.severity === 'error' ? 'error' : issue.severity === 'warning' ? 'warning' : 'notice';\n console.log(`::${level}::${issue.message} [${issue.rule}]${issue.specId ? ` (${issue.specId})` : ''}`);\n }\n return;\n }\n \n if (result.issues.length === 0) {\n console.log(chalk.green(' ✓ No issues found'));\n return;\n }\n \n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';\n const color = issue.severity === 'error' ? chalk.red : issue.severity === 'warning' ? chalk.yellow : chalk.blue;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n console.log(chalk.gray(` Rule: ${issue.rule}`));\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${result.errors} errors, ${result.warnings} warnings, ${result.infos} infos`));\n}\n","/**\n * Drift Command\n * \n * Detect drift between generated artifacts and SSOT\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getSpecsFromConfig } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DriftCommandOptions {\n config?: string;\n verbose?: boolean;\n failOnDrift?: boolean;\n}\n\nexport interface DriftResult {\n file: string;\n status: 'ok' | 'drifted' | 'missing';\n details?: string;\n}\n\n// ============================================================================\n// Drift Command\n// ============================================================================\n\nexport async function driftCommand(options: DriftCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper drift'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Docs: ${config.docsDir}/`));\n console.log('');\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n \n const results: DriftResult[] = [];\n \n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n if (modelSpecs.length === 0) continue;\n \n for (const exporter of model.getExporters()) {\n if (exporter.format !== 'markdown') continue;\n \n const outputDir = exporter.outputDir \n ? join(cwd, config.docsDir, exporter.outputDir)\n : join(cwd, config.docsDir);\n \n if (exporter.single) {\n for (const spec of modelSpecs) {\n const filename = model.getFilename(spec, 'markdown') || (spec as { id: string }).id;\n const filePath = join(outputDir, `${filename}.md`);\n \n if (!existsSync(filePath)) {\n results.push({ file: filePath, status: 'missing' });\n continue;\n }\n \n const expected = exporter.single(spec);\n const actual = readFileSync(filePath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: filePath, status: 'drifted' });\n } else {\n results.push({ file: filePath, status: 'ok' });\n }\n }\n }\n \n if (exporter.index) {\n const indexPath = exporter.outputFile\n ? join(cwd, config.docsDir, exporter.outputFile)\n : join(outputDir, 'index.md');\n \n if (!existsSync(indexPath)) {\n results.push({ file: indexPath, status: 'missing' });\n } else {\n const expected = exporter.index(modelSpecs);\n const actual = readFileSync(indexPath, 'utf-8');\n \n if (normalizeContent(expected) !== normalizeContent(actual)) {\n results.push({ file: indexPath, status: 'drifted' });\n } else {\n results.push({ file: indexPath, status: 'ok' });\n }\n }\n }\n }\n }\n \n outputDriftResults(results, options);\n \n const hasDrift = results.some(r => r.status === 'drifted' || r.status === 'missing');\n if (hasDrift && options.failOnDrift) {\n process.exit(1);\n }\n \n } catch (error) {\n console.error(chalk.red('Drift check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeContent(content: string): string {\n return content.trim().replace(/\\r\\n/g, '\\n');\n}\n\nfunction outputDriftResults(results: DriftResult[], _options: DriftCommandOptions): void {\n console.log('');\n \n const ok = results.filter(r => r.status === 'ok');\n const drifted = results.filter(r => r.status === 'drifted');\n const missing = results.filter(r => r.status === 'missing');\n \n if (drifted.length === 0 && missing.length === 0) {\n console.log(chalk.green(' ✓ No drift detected'));\n console.log(chalk.gray(` Checked: ${results.length} files`));\n return;\n }\n \n if (drifted.length > 0) {\n console.log(chalk.yellow(` ⚠ ${drifted.length} file(s) have drifted:`));\n for (const result of drifted) {\n console.log(chalk.yellow(` - ${result.file}`));\n }\n }\n \n if (missing.length > 0) {\n console.log(chalk.red(` ✗ ${missing.length} file(s) are missing:`));\n for (const result of missing) {\n console.log(chalk.red(` - ${result.file}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${ok.length} ok, ${drifted.length} drifted, ${missing.length} missing`));\n}\n","/**\n * Type Compatibility — Containment-based type comparison\n *\n * The spec defines the minimum required type. The DDL/OpenAPI satisfies the\n * requirement if its type can hold all values of the spec type (equal or wider).\n */\n\ninterface ParsedType {\n base: string;\n length?: number;\n precision?: number;\n scale?: number;\n}\n\nconst ALIASES: Record<string, string> = {\n INTEGER: 'INT',\n BOOL: 'BOOLEAN',\n REAL: 'FLOAT',\n 'DOUBLE PRECISION': 'DOUBLE',\n SERIAL: 'INT',\n BIGSERIAL: 'BIGINT',\n SMALLSERIAL: 'SMALLINT',\n TIMESTAMPTZ: 'TIMESTAMP',\n 'TIMESTAMP WITH TIME ZONE': 'TIMESTAMP',\n 'TIMESTAMP WITHOUT TIME ZONE': 'TIMESTAMP',\n 'CHARACTER VARYING': 'VARCHAR',\n CHARACTER: 'CHAR',\n INT2: 'SMALLINT',\n INT4: 'INT',\n INT8: 'BIGINT',\n FLOAT4: 'FLOAT',\n FLOAT8: 'DOUBLE',\n};\n\nconst CONTAINMENT_CHAINS: string[][] = [\n ['SMALLINT', 'INT', 'BIGINT'],\n ['FLOAT', 'DOUBLE'],\n ['CHAR', 'VARCHAR', 'TEXT'],\n ['INTEGER', 'NUMBER'],\n];\n\nfunction parseType(raw: string): ParsedType {\n const trimmed = raw.trim().toUpperCase();\n\n const match = trimmed.match(/^([A-Z\\s]+?)(?:\\(\\s*(\\d+)(?:\\s*,\\s*(\\d+))?\\s*\\))?$/);\n if (!match) {\n return { base: trimmed };\n }\n\n const base = match[1].trim();\n\n return {\n base,\n length: match[2] !== undefined ? Number(match[2]) : undefined,\n precision: match[2] !== undefined ? Number(match[2]) : undefined,\n scale: match[3] !== undefined ? Number(match[3]) : undefined,\n };\n}\n\nfunction normalize(base: string): string {\n return ALIASES[base] ?? base;\n}\n\nfunction findAllChainPositions(\n base: string,\n chains: string[][],\n): Array<{ chain: string[]; index: number }> {\n const results: Array<{ chain: string[]; index: number }> = [];\n const resolved = normalize(base);\n for (const chain of chains) {\n let idx = chain.indexOf(base);\n if (idx === -1) idx = chain.indexOf(resolved);\n if (idx !== -1) results.push({ chain, index: idx });\n }\n return results;\n}\n\n/**\n * Returns true if ddlType can hold all values representable by specType.\n *\n * Containment rules:\n * - Numeric: SMALLINT ⊂ INT ⊂ BIGINT, FLOAT ⊂ DOUBLE\n * - String: CHAR(n) ⊂ VARCHAR(n) ⊂ TEXT (with length comparison)\n * - DECIMAL: precision/scale must be >= spec\n * - OpenAPI: integer ⊂ number\n */\nexport function isTypeContainedBy(specType: string, ddlType: string): boolean {\n const spec = parseType(specType);\n const ddl = parseType(ddlType);\n\n const specNorm = normalize(spec.base);\n const ddlNorm = normalize(ddl.base);\n\n if (specNorm === ddlNorm) {\n if (specNorm === 'DECIMAL' || specNorm === 'NUMERIC') {\n if (spec.precision !== undefined && ddl.precision !== undefined) {\n if (ddl.precision < spec.precision) return false;\n }\n if (spec.scale !== undefined && ddl.scale !== undefined) {\n if (ddl.scale < spec.scale) return false;\n }\n return true;\n }\n\n if (spec.length !== undefined && ddl.length !== undefined) {\n return ddl.length >= spec.length;\n }\n return true;\n }\n\n const specPositions = findAllChainPositions(spec.base, CONTAINMENT_CHAINS);\n const ddlPositions = findAllChainPositions(ddl.base, CONTAINMENT_CHAINS);\n\n for (const sp of specPositions) {\n for (const dp of ddlPositions) {\n if (sp.chain === dp.chain) {\n return dp.index >= sp.index;\n }\n }\n }\n\n return false;\n}\n","/**\n * Global Scanner — Scans all configured sources for spec IDs\n *\n * Replaces per-model externalChecker with a single global scan pass.\n * Built-in scanners: openapi, ddl, annotation.\n * Custom scanners can be plugged in via SourceConfig.scanner.\n */\nimport { readFileSync, existsSync } from 'node:fs';\nimport { join, isAbsolute } from 'node:path';\nimport { glob } from 'glob';\nimport { parse as parseYaml } from 'yaml';\nimport nodeSqlParser from 'node-sql-parser';\nimport type { SourceConfig, SourceMatch, SourceScanner } from './config-api.js';\nimport type { CheckResult, DeepValidationConfig, OpenAPIValidationMapping, DDLValidationMapping } from './model.js';\nimport { isTypeContainedBy } from './dsl/type-compat.js';\n\n// ============================================================================\n// Scan Result Types\n// ============================================================================\n\nexport interface GlobalScanMatch extends SourceMatch {\n /** Which source config produced this match */\n sourceType: string;\n /** Relation type from the source config */\n relation: 'implements' | 'verifiedBy';\n /** File path where the match was found */\n filePath: string;\n}\n\nexport type GlobalScanResult = Map<string, GlobalScanMatch[]>;\n\n// ============================================================================\n// Built-in: OpenAPI Scanner\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function resolveRef(doc: any, ref: string): any {\n if (!ref.startsWith('#/')) return undefined;\n const parts = ref.substring(2).split('/');\n let current = doc;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') return undefined;\n current = current[part];\n }\n return current;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function maybeResolveRef(doc: any, value: any): any {\n if (value && typeof value === 'object' && typeof value.$ref === 'string') {\n return resolveRef(doc, value.$ref);\n }\n return value;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction findSpecIdInOpenAPI(doc: any, specId: string): { pathKey: string; operation?: any; method?: string } | null {\n const paths = doc.paths;\n if (!paths || typeof paths !== 'object') return null;\n\n for (const [pathKey, pathItem] of Object.entries(paths)) {\n if (pathItem == null || typeof pathItem !== 'object') continue;\n const methods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];\n for (const method of methods) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const op = (pathItem as any)[method];\n if (!op) continue;\n if (op.operationId === specId) return { pathKey, operation: op, method };\n if (op['x-spec-id'] === specId) return { pathKey, operation: op, method };\n }\n }\n\n for (const pathKey of Object.keys(paths)) {\n const segments = pathKey.split('/').filter(Boolean);\n const cleanSegments = segments.map(s => s.replace(/^\\{|\\}$/g, ''));\n if (cleanSegments.includes(specId)) return { pathKey };\n }\n\n const schemas = doc.components?.schemas;\n if (schemas && typeof schemas === 'object') {\n if (specId in schemas) return { pathKey: `#/components/schemas/${specId}` };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function searchXSpecId(obj: any): boolean {\n if (obj == null || typeof obj !== 'object') return false;\n if (obj['x-spec-id'] === specId) return true;\n for (const val of Object.values(obj)) {\n if (searchXSpecId(val)) return true;\n }\n return false;\n }\n if (searchXSpecId(doc)) return { pathKey: '(x-spec-id match)' };\n\n return null;\n}\n\nexport const openapiScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n const doc = content;\n if (!doc || typeof doc !== 'object') return [];\n\n const matches: SourceMatch[] = [];\n for (const specId of specIds) {\n const match = findSpecIdInOpenAPI(doc, specId);\n if (match) {\n matches.push({\n specId,\n location: `${filePath}:${match.pathKey}`,\n context: { doc, match },\n });\n }\n }\n return matches;\n },\n};\n\n// ============================================================================\n// Built-in: DDL Scanner\n// ============================================================================\n\ninterface TableDefinition {\n name: string;\n columns: Array<{ name: string; type: string }>;\n}\n\nfunction stripSchemaPrefix(name: string): string {\n const dotIndex = name.lastIndexOf('.');\n return dotIndex >= 0 ? name.substring(dotIndex + 1) : name;\n}\n\nfunction parseDDLWithParser(content: string): TableDefinition[] | null {\n const parser = new nodeSqlParser.Parser();\n const tables: TableDefinition[] = [];\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const ast = parser.astify(content) as any;\n const statements = Array.isArray(ast) ? ast : [ast];\n\n for (const stmt of statements) {\n if (stmt.type !== 'create' || stmt.keyword !== 'table') continue;\n\n const rawName: string = typeof stmt.table === 'string'\n ? stmt.table\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n : (stmt.table as any[])?.[0]?.table ?? '';\n const tableName = stripSchemaPrefix(rawName);\n\n const columns: Array<{ name: string; type: string }> = (stmt.create_definitions || [])\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .filter((def: any) => def.resource === 'column')\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((def: any) => {\n const colName = def.column?.column ?? '';\n let colType = def.definition?.dataType ?? '';\n if (def.definition?.length) {\n colType += `(${def.definition.length})`;\n }\n if (def.definition?.scale) {\n colType = colType.replace(/\\)$/, `,${def.definition.scale})`);\n }\n return { name: colName, type: colType };\n });\n\n if (tableName) {\n tables.push({ name: tableName, columns });\n }\n }\n\n return tables.length > 0 ? tables : null;\n } catch {\n return null;\n }\n}\n\nfunction parseDDLWithRegex(content: string): TableDefinition[] {\n const tables: TableDefinition[] = [];\n const tableRegex = /CREATE\\s+TABLE\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?(?:(?:[`\"']?\\w+[`\"']?\\s*\\.\\s*)?)[`\"']?(\\w+)[`\"']?\\s*\\(([\\s\\S]*?)\\);/gi;\n\n let match;\n while ((match = tableRegex.exec(content)) !== null) {\n const tableName = match[1];\n const body = match[2];\n const columns: Array<{ name: string; type: string }> = [];\n\n const lines = body.split(',').map(l => l.trim()).filter(Boolean);\n for (const line of lines) {\n if (/^\\s*(PRIMARY\\s+KEY|UNIQUE|CHECK|CONSTRAINT|INDEX|FOREIGN\\s+KEY)/i.test(line)) continue;\n\n const colMatch = line.match(/^(?:`|\"|')?(\\w+)(?:`|\"|')?\\s+(\\w+(?:\\([^)]*\\))?)/i);\n if (colMatch) {\n columns.push({ name: colMatch[1], type: colMatch[2] });\n }\n }\n\n if (tableName) {\n tables.push({ name: tableName, columns });\n }\n }\n\n return tables;\n}\n\nexport const ddlScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n let tables = parseDDLWithParser(content);\n if (!tables) {\n tables = parseDDLWithRegex(content);\n }\n\n const matches: SourceMatch[] = [];\n for (const specId of specIds) {\n const table = tables.find(\n (t) => t.name.toLowerCase() === specId.toLowerCase(),\n );\n if (table) {\n matches.push({\n specId,\n location: `${filePath}:${table.name}`,\n context: { table },\n });\n }\n }\n return matches;\n },\n};\n\n// ============================================================================\n// Built-in: Annotation Scanner\n// ============================================================================\n\nfunction extractSpecIds(captured: string): string[] {\n return captured.split(/[,\\s]+/).map(s => s.trim()).filter(Boolean);\n}\n\nexport const annotationScanner: SourceScanner = {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n const specIdSet = new Set(specIds);\n const matches: SourceMatch[] = [];\n const defaultPattern = /@(?:verifies|implements|traces)\\s+([\\w-]+(?:[,\\s]+[\\w-]+)*)/g;\n\n const lines = content.split('\\n');\n for (let lineNum = 1; lineNum <= lines.length; lineNum++) {\n const line = lines[lineNum - 1];\n const copy = new RegExp(defaultPattern.source, defaultPattern.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (specIdSet.has(id)) {\n matches.push({\n specId: id,\n location: `${filePath}:${lineNum}`,\n context: { filePath, line: lineNum },\n });\n }\n }\n }\n }\n return matches;\n },\n};\n\n/**\n * Create an annotation scanner with custom content patterns.\n */\nexport function createAnnotationScanner(contentPatterns: RegExp[]): SourceScanner {\n return {\n findSpecIds(content: unknown, specIds: string[], filePath: string): SourceMatch[] {\n if (typeof content !== 'string') return [];\n\n const specIdSet = new Set(specIds);\n const matches: SourceMatch[] = [];\n\n const lines = content.split('\\n');\n for (let lineNum = 1; lineNum <= lines.length; lineNum++) {\n const line = lines[lineNum - 1];\n for (const re of contentPatterns) {\n const copy = new RegExp(re.source, re.flags);\n let m: RegExpExecArray | null;\n while ((m = copy.exec(line)) !== null) {\n const ids = extractSpecIds(m[1] ?? '');\n for (const id of ids) {\n if (specIdSet.has(id)) {\n matches.push({\n specId: id,\n location: `${filePath}:${lineNum}`,\n context: { filePath, line: lineNum },\n });\n }\n }\n }\n }\n }\n return matches;\n },\n };\n}\n\n// ============================================================================\n// Scanner Registry\n// ============================================================================\n\nconst BUILT_IN_SCANNERS: Record<string, SourceScanner> = {\n openapi: openapiScanner,\n ddl: ddlScanner,\n annotation: annotationScanner,\n};\n\nfunction getScannerForSource(source: SourceConfig): SourceScanner | null {\n if (source.scanner) return source.scanner;\n if (source.type === 'annotation' && source.contentPatterns && source.contentPatterns.length > 0) {\n return createAnnotationScanner(source.contentPatterns);\n }\n return BUILT_IN_SCANNERS[source.type] ?? null;\n}\n\n// ============================================================================\n// File Loading\n// ============================================================================\n\nfunction loadFileContent(filePath: string, sourceType: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n if (!content || content.length === 0) return null;\n\n if (sourceType === 'openapi') {\n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n return parseYaml(content);\n }\n\n return content;\n}\n\n// ============================================================================\n// Global Scan Orchestrator\n// ============================================================================\n\nexport interface ScanWarning {\n message: string;\n sourceType: string;\n filePath?: string;\n}\n\nexport interface GlobalScanOutput {\n matches: GlobalScanResult;\n warnings: ScanWarning[];\n}\n\n/**\n * Run global scan across all configured sources.\n * Returns a map of specId -> matches for all spec IDs found.\n */\nexport function runGlobalScan(\n sources: SourceConfig[],\n specIds: string[],\n basePath?: string,\n): GlobalScanOutput {\n const cwd = basePath ?? process.cwd();\n const result: GlobalScanResult = new Map();\n const warnings: ScanWarning[] = [];\n\n for (const source of sources) {\n const scanner = getScannerForSource(source);\n if (!scanner) {\n warnings.push({\n message: `No scanner found for source type \"${source.type}\". Provide a custom scanner.`,\n sourceType: source.type,\n });\n continue;\n }\n\n const allFiles = new Set<string>();\n for (const pattern of source.paths) {\n const found = glob.sync(pattern, {\n cwd,\n ignore: source.exclude ?? [],\n });\n for (const f of found) {\n allFiles.add(f);\n }\n }\n\n for (const relPath of allFiles) {\n const fullPath = isAbsolute(relPath) ? relPath : join(cwd, relPath);\n if (!existsSync(fullPath)) continue;\n\n let content: unknown;\n try {\n content = loadFileContent(fullPath, source.type);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push({\n message: `Failed to load ${relPath}: ${msg}`,\n sourceType: source.type,\n filePath: relPath,\n });\n continue;\n }\n\n if (content == null) continue;\n\n let matches: SourceMatch[];\n try {\n matches = scanner.findSpecIds(content, specIds, relPath);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n warnings.push({\n message: `Scanner error for ${relPath}: ${msg}`,\n sourceType: source.type,\n filePath: relPath,\n });\n continue;\n }\n\n for (const match of matches) {\n const globalMatch: GlobalScanMatch = {\n ...match,\n sourceType: source.type,\n relation: source.relation,\n filePath: relPath,\n };\n\n const existing = result.get(match.specId);\n if (existing) {\n existing.push(globalMatch);\n } else {\n result.set(match.specId, [globalMatch]);\n }\n }\n }\n }\n\n return { matches: result, warnings };\n}\n\n// ============================================================================\n// Deep Validation\n// ============================================================================\n\n/**\n * Run deep validation for a spec against its matched sources.\n * Uses the model's deepValidation config to perform Level 2/3 checks.\n */\nexport function runDeepValidation(\n specId: string,\n matches: GlobalScanMatch[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n deepValidation: DeepValidationConfig<any>,\n spec: unknown,\n): CheckResult {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n for (const match of matches) {\n const rule = deepValidation[match.sourceType];\n if (!rule) continue;\n\n if (match.sourceType === 'openapi') {\n const mapping = rule.mapper(spec) as OpenAPIValidationMapping;\n const ctx = match.context as { doc: unknown; match: { pathKey: string; operation?: unknown; method?: string } } | undefined;\n if (!ctx?.match?.operation) continue;\n\n validateOpenAPIDeep(specId, mapping, ctx.doc, ctx.match, warnings);\n } else if (match.sourceType === 'ddl') {\n const mapping = rule.mapper(spec) as DDLValidationMapping;\n const ctx = match.context as { table: { name: string; columns: Array<{ name: string; type: string }> } } | undefined;\n if (!ctx?.table) continue;\n\n validateDDLDeep(specId, mapping, ctx.table, warnings);\n }\n }\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nfunction validateOpenAPIDeep(\n specId: string,\n mapping: OpenAPIValidationMapping,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n doc: any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n match: { pathKey: string; operation?: any; method?: string },\n warnings: CheckResult['warnings'],\n): void {\n if (mapping.method && match.operation) {\n const expectedMethod = mapping.method.toLowerCase();\n const actualMethod = match.method?.toLowerCase();\n if (actualMethod && actualMethod !== expectedMethod) {\n warnings.push({\n message: `Method mismatch for \"${specId}\": expected ${expectedMethod.toUpperCase()}, found ${actualMethod.toUpperCase()}`,\n specId,\n });\n }\n }\n\n if (match.operation && mapping.parameters) {\n const opParams: Array<{ name: string; in?: string; schema?: { type?: string } }> =\n (match.operation.parameters || []).map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (p: any) => maybeResolveRef(doc, p),\n );\n\n for (const expectedParam of mapping.parameters) {\n const found = opParams.find(\n (p) => p?.name === expectedParam.name && (!expectedParam.in || p?.in === expectedParam.in),\n );\n if (!found) {\n warnings.push({\n message: `Parameter \"${expectedParam.name}\" not found in operation \"${specId}\"`,\n specId,\n field: expectedParam.name,\n });\n } else if (expectedParam.type && found.schema?.type) {\n if (!isTypeContainedBy(expectedParam.type, found.schema.type)) {\n warnings.push({\n message: `Parameter \"${expectedParam.name}\" type mismatch: expected ${expectedParam.type}, found ${found.schema.type}`,\n specId,\n field: expectedParam.name,\n });\n }\n }\n }\n }\n\n if (match.operation && mapping.responseProperties) {\n const successResponse = match.operation.responses?.['200'] || match.operation.responses?.['201'];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let responseSchema: any = successResponse?.content?.['application/json']?.schema;\n responseSchema = maybeResolveRef(doc, responseSchema);\n\n if (responseSchema?.type === 'array') {\n responseSchema = maybeResolveRef(doc, responseSchema.items);\n }\n\n const responseProps = responseSchema?.properties || {};\n\n for (const expectedProp of mapping.responseProperties) {\n const foundProp = responseProps[expectedProp.name];\n if (!foundProp) {\n warnings.push({\n message: `Response property \"${expectedProp.name}\" not found in operation \"${specId}\"`,\n specId,\n field: expectedProp.name,\n });\n } else if (expectedProp.type && foundProp.type) {\n if (!isTypeContainedBy(expectedProp.type, foundProp.type)) {\n warnings.push({\n message: `Response property \"${expectedProp.name}\" type mismatch: expected ${expectedProp.type}, found ${foundProp.type}`,\n specId,\n field: expectedProp.name,\n });\n }\n }\n }\n }\n}\n\nfunction validateDDLDeep(\n specId: string,\n mapping: DDLValidationMapping,\n table: { name: string; columns: Array<{ name: string; type: string }> },\n warnings: CheckResult['warnings'],\n): void {\n if (!mapping.columns) return;\n\n for (const expectedCol of mapping.columns) {\n const foundCol = table.columns.find(\n (c) => c.name.toLowerCase() === expectedCol.name.toLowerCase(),\n );\n\n if (!foundCol) {\n warnings.push({\n message: `Column \"${expectedCol.name}\" not found in table \"${mapping.tableName}\"`,\n specId,\n field: expectedCol.name,\n });\n continue;\n }\n\n if (mapping.checkTypes && expectedCol.type && foundCol.type) {\n if (!isTypeContainedBy(expectedCol.type, foundCol.type)) {\n warnings.push({\n message: `Column \"${expectedCol.name}\" type mismatch in table \"${mapping.tableName}\": expected ${expectedCol.type}, found ${foundCol.type}`,\n specId,\n field: expectedCol.name,\n });\n }\n }\n }\n}\n","/**\n * Check Command\n *\n * Global scan across configured sources, then optional deep validation per model.\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { readFileSync, existsSync } from 'node:fs';\nimport { parse as parseYaml } from 'yaml';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getSpecsFromConfig, buildRegistryFromConfig, type SpecEntry, type CoverageResult } from '../core/model.js';\nimport { runGlobalScan, runDeepValidation } from '../core/global-scanner.js';\nimport type { SourceConfig } from '../core/config-api.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CheckCommandOptions {\n config?: string;\n type?: 'openapi' | 'ddl' | 'iac' | 'all';\n verbose?: boolean;\n coverage?: boolean;\n}\n\nexport interface CheckIssue {\n severity: 'error' | 'warning';\n message: string;\n specId?: string;\n field?: string;\n}\n\nexport interface CheckResult {\n type: string;\n success: boolean;\n issues: CheckIssue[];\n}\n\n// ============================================================================\n// Check Command\n// ============================================================================\n\nexport async function checkCommand(\n type: string | undefined,\n options: CheckCommandOptions\n): Promise<void> {\n console.log(chalk.blue('speckeeper check'));\n console.log('');\n\n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n const checkType = type || options.type || 'all';\n\n console.log(chalk.gray(` Design: ${config.designDir || 'design'}/`));\n console.log(chalk.gray(` Type: ${checkType}`));\n console.log('');\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const models = (config.models || []) as any[];\n const specs = config.specs;\n const sources: SourceConfig[] = config.sources ?? [];\n\n if (options.verbose) {\n console.log(chalk.gray(` Registered models: ${models.map((m: { id: string }) => m.id).join(', ')}`));\n console.log(chalk.gray(` Sources: ${sources.length} configured`));\n }\n\n const results: CheckResult[] = [];\n\n // Collect all spec IDs across all models\n const allSpecIds: string[] = [];\n const specIdToModel = new Map<string, { modelId: string; spec: unknown }>();\n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n for (const spec of modelSpecs) {\n const specId = (spec as { id: string }).id;\n allSpecIds.push(specId);\n specIdToModel.set(specId, { modelId: model.id, spec });\n }\n }\n\n if (sources.length > 0 && allSpecIds.length > 0) {\n // Filter sources by checkType\n const filteredSources = checkType === 'all'\n ? sources\n : sources.filter(s => s.type === checkType);\n\n // Run global scan\n const { matches, warnings: scanWarnings } = runGlobalScan(filteredSources, allSpecIds, cwd);\n\n for (const sw of scanWarnings) {\n results.push({\n type: sw.sourceType,\n success: true,\n issues: [{\n severity: 'warning',\n message: sw.message,\n }],\n });\n }\n\n // For each spec, check matches + deep validation\n for (const [specId, entry] of specIdToModel) {\n const specMatches = matches.get(specId);\n\n // Run deep validation if model has rules and there are matches\n if (specMatches && specMatches.length > 0) {\n const model = models.find((m: { id: string }) => m.id === entry.modelId);\n const deepValidation = model?.getDeepValidation?.();\n if (deepValidation) {\n const deepResult = runDeepValidation(specId, specMatches, deepValidation, entry.spec);\n if (deepResult.errors.length > 0 || deepResult.warnings.length > 0) {\n results.push({\n type: entry.modelId,\n success: deepResult.success,\n issues: [\n ...deepResult.errors.map((e: { message: string; specId?: string; field?: string }) => ({\n severity: 'error' as const, message: e.message, specId: e.specId, field: e.field,\n })),\n ...deepResult.warnings.map((w: { message: string; specId?: string; field?: string }) => ({\n severity: 'warning' as const, message: w.message, specId: w.specId, field: w.field,\n })),\n ],\n });\n }\n }\n }\n }\n\n // Report unmatched specs\n if (options.verbose) {\n for (const specId of allSpecIds) {\n if (!matches.has(specId)) {\n const entry = specIdToModel.get(specId);\n results.push({\n type: entry?.modelId ?? 'unknown',\n success: true,\n issues: [{\n severity: 'warning',\n message: `Spec ID \"${specId}\" not found in any configured source`,\n specId,\n }],\n });\n }\n }\n }\n }\n\n // Run per-model externalChecker for models that still define one (legacy support)\n runLegacyChecks(models, specs, cwd, results);\n\n outputCheckResults(results);\n\n if (options.coverage) {\n console.log('');\n console.log(chalk.blue(' Coverage checks...'));\n const coverageResults = runAllCoverageChecks(models, specs);\n\n if (coverageResults.length > 0) {\n outputAllCoverageResults(coverageResults);\n\n for (const check of coverageResults) {\n if (check.result.uncoveredItems.length > 0) {\n results.push({\n type: `coverage-${check.modelId}`,\n success: check.result.coveragePercent >= 80,\n issues: check.result.uncoveredItems.slice(0, 10).map(item => ({\n severity: 'warning' as const,\n message: `[${check.modelName}→${check.targetModel}] '${item.id}'${item.sourceId ? ` (${item.sourceId})` : ''} not covered`,\n specId: item.id,\n })),\n });\n }\n }\n\n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n const allPassed = coverageResults.every(c => c.result.coveragePercent >= 80);\n if (allPassed) {\n console.log(chalk.green(' ✓ All coverage checks passed (≥80%)'));\n } else {\n const failed = coverageResults.filter(c => c.result.coveragePercent < 80);\n console.log(chalk.yellow(` ⚠ ${failed.length} coverage check(s) below 80%`));\n }\n } else {\n console.log(chalk.gray(' No coverage checker found'));\n }\n }\n\n const hasErrors = results.some(r => !r.success);\n if (hasErrors) {\n process.exit(1);\n }\n\n } catch (error) {\n console.error(chalk.red('Check failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Legacy per-model checker (used when sources not configured)\n// ============================================================================\n\nfunction loadExternalData(filePath: string): unknown {\n const content = readFileSync(filePath, 'utf-8');\n\n if (filePath.endsWith('.yaml') || filePath.endsWith('.yml')) {\n return parseYaml(content);\n }\n\n if (filePath.endsWith('.json')) {\n return JSON.parse(content);\n }\n\n return content;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction runLegacyChecks(models: any[], specs: SpecEntry[] | undefined, cwd: string, results: CheckResult[]): void {\n for (const model of models) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n if (modelSpecs.length === 0) continue;\n\n for (const spec of modelSpecs) {\n const sourcePath = model.getExternalSourcePath?.(spec);\n if (!sourcePath) continue;\n\n const fullPath = join(cwd, sourcePath);\n if (!existsSync(fullPath)) {\n results.push({\n type: model.id,\n success: false,\n issues: [{\n severity: 'error',\n message: `External source not found: ${sourcePath}`,\n specId: (spec as { id: string }).id,\n }],\n });\n continue;\n }\n\n const externalData = loadExternalData(fullPath);\n const checkResult = model.check(spec, externalData);\n\n if (!checkResult.success || checkResult.errors.length > 0 || checkResult.warnings.length > 0) {\n results.push({\n type: model.id,\n success: checkResult.success,\n issues: [\n ...checkResult.errors.map((e: { message: string; specId?: string; field?: string }) => ({ severity: 'error' as const, message: e.message, specId: e.specId, field: e.field })),\n ...checkResult.warnings.map((w: { message: string; specId?: string; field?: string }) => ({ severity: 'warning' as const, message: w.message, specId: w.specId, field: w.field })),\n ],\n });\n }\n }\n }\n}\n\nfunction outputCheckResults(results: CheckResult[]): void {\n console.log('');\n \n if (results.length === 0) {\n console.log(chalk.green(' ✓ All checks passed'));\n return;\n }\n \n let totalErrors = 0;\n let totalWarnings = 0;\n \n for (const result of results) {\n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '✗' : '⚠';\n const color = issue.severity === 'error' ? chalk.red : chalk.yellow;\n \n if (issue.severity === 'error') totalErrors++;\n else totalWarnings++;\n \n const prefix = issue.specId ? `[${issue.specId}] ` : '';\n console.log(color(` ${icon} ${prefix}${issue.message}`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Summary: ${totalErrors} errors, ${totalWarnings} warnings`));\n}\n\n// ============================================================================\n// Coverage Check\n// ============================================================================\n\ninterface CoverageCheckResult {\n modelId: string;\n modelName: string;\n description: string;\n targetModel: string;\n result: CoverageResult;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction runAllCoverageChecks(models: any[], specs: SpecEntry[] | undefined): CoverageCheckResult[] {\n const results: CoverageCheckResult[] = [];\n const registry = buildRegistryFromConfig(specs);\n \n for (const model of models) {\n const checker = model.getCoverageChecker();\n if (checker) {\n const modelSpecs = getSpecsFromConfig(specs, model.id);\n const result = model.checkCoverage(modelSpecs, registry);\n \n if (result) {\n results.push({\n modelId: model.id,\n modelName: model.name,\n description: checker.description,\n targetModel: checker.targetModel,\n result,\n });\n }\n }\n }\n \n return results;\n}\n\nfunction outputAllCoverageResults(checks: CoverageCheckResult[]): void {\n for (const check of checks) {\n console.log('');\n console.log(chalk.blue(` Coverage: ${check.modelName} → ${check.targetModel}`));\n console.log(chalk.gray(` ${check.description}`));\n console.log(chalk.gray(` ─────────────────────────────────────`));\n console.log(chalk.gray(` Total: ${check.result.total}`));\n console.log(chalk.green(` Covered: ${check.result.covered}`));\n console.log(chalk.yellow(` Uncovered: ${check.result.uncovered}`));\n \n const color = check.result.coveragePercent >= 80 ? chalk.green : \n check.result.coveragePercent >= 50 ? chalk.yellow : chalk.red;\n console.log(color(` Coverage: ${check.result.coveragePercent}%`));\n \n if (check.result.uncoveredItems.length > 0 && check.result.uncoveredItems.length <= 10) {\n console.log('');\n console.log(chalk.yellow(' Uncovered items:'));\n for (const item of check.result.uncoveredItems) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n const source = item.sourceId ? ` (${item.sourceId})` : '';\n console.log(chalk.yellow(` - ${item.id}${source}${desc}`));\n }\n } else if (check.result.uncoveredItems.length > 10) {\n console.log('');\n console.log(chalk.yellow(` (${check.result.uncoveredItems.length} uncovered items - showing first 5)`));\n for (const item of check.result.uncoveredItems.slice(0, 5)) {\n const desc = item.description ? `: ${item.description.substring(0, 40)}` : '';\n console.log(chalk.yellow(` - ${item.id}${desc}`));\n }\n }\n }\n}\n","/**\n * New Command\n * \n * Generate templates for new model instances\n */\n\nimport chalk from 'chalk';\nimport { join } from 'node:path';\nimport { writeFileSync, existsSync } from 'node:fs';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { getAllModels } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface NewCommandOptions {\n config?: string;\n type?: string;\n id?: string;\n output?: string;\n dryRun?: boolean;\n}\n\n// ============================================================================\n// New Command\n// ============================================================================\n\nexport async function newCommand(options: NewCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper new'));\n console.log('');\n \n const cwd = process.cwd();\n const config = await loadConfig(options.config);\n \n // List available types if no type specified\n if (!options.type) {\n console.log(chalk.gray(' Available model types:'));\n const models = getAllModels();\n for (const model of models) {\n console.log(chalk.gray(` - ${model.id} (${model.name})`));\n }\n console.log('');\n console.log(chalk.gray(' Usage: speckeeper new --type <type> [--id <id>]'));\n return;\n }\n \n // Find model\n const models = getAllModels();\n const model = models.find(m => m.id === options.type);\n \n if (!model) {\n console.error(chalk.red(` Error: Unknown model type '${options.type}'`));\n console.log(chalk.gray(' Run `speckeeper new` to see available types'));\n process.exit(1);\n }\n \n // Generate ID if not provided\n const id = options.id || `${model.idPrefix}-${String(Date.now()).slice(-6)}`;\n \n // Generate template\n const template = generateTemplate(model, id);\n \n if (options.dryRun) {\n console.log(chalk.gray(' Template (dry run):'));\n console.log('');\n console.log(template);\n return;\n }\n \n // Write template to file\n const outputDir = options.output || join(cwd, config.designDir || 'design');\n const outputFile = join(outputDir, `${model.id}-${id}.ts`);\n \n if (existsSync(outputFile)) {\n console.error(chalk.red(` Error: File already exists: ${outputFile}`));\n process.exit(1);\n }\n \n writeFileSync(outputFile, template);\n console.log(chalk.green(` ✓ Created: ${outputFile}`));\n}\n\n// ============================================================================\n// Template Generation\n// ============================================================================\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction generateTemplate(model: any, id: string): string {\n const typeName = model.name;\n const lines: string[] = [];\n \n lines.push(`/**`);\n lines.push(` * ${typeName}: ${id}`);\n lines.push(` * `);\n lines.push(` * Generated by speckeeper new`);\n lines.push(` */`);\n lines.push(`import type { ${typeName} } from './_models/${model.id}';`);\n lines.push('');\n lines.push(`export const ${camelCase(id)}: ${typeName} = {`);\n lines.push(` id: '${id}',`);\n lines.push(` // TODO: Fill in the required fields`);\n lines.push(`};`);\n lines.push('');\n \n return lines.join('\\n');\n}\n\nfunction camelCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[-_](.)/g, (_, c) => c.toUpperCase());\n}\n","/**\n * Impact Command\n * \n * Analyze the impact scope of changes\n */\n\nimport chalk from 'chalk';\nimport { loadConfig } from '../utils/config-loader.js';\nimport { buildRegistryFromConfig, findModelTypeFromConfig } from '../core/model.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ImpactCommandOptions {\n config?: string;\n depth?: string;\n direction?: 'upstream' | 'downstream' | 'both';\n format?: 'text' | 'json' | 'mermaid';\n}\n\nexport interface ImpactNode {\n id: string;\n type: string;\n depth: number;\n impactType: 'direct' | 'indirect';\n}\n\nexport interface ImpactResult {\n target: string;\n targetType: string;\n impactedNodes: ImpactNode[];\n}\n\n// ============================================================================\n// Impact Command\n// ============================================================================\n\nexport async function impactCommand(targetId: string, options: ImpactCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper impact'));\n console.log('');\n \n if (!targetId) {\n console.error(chalk.red('Error: ID is required'));\n console.log(chalk.gray(' Usage: speckeeper impact <id>'));\n process.exit(1);\n }\n \n const config = await loadConfig(options.config);\n const maxDepth = options.depth ? parseInt(options.depth, 10) : 3;\n \n console.log(chalk.gray(` Target: ${targetId}`));\n console.log(chalk.gray(` Depth: ${maxDepth}`));\n console.log('');\n \n try {\n const specs = config.specs;\n const registry = buildRegistryFromConfig(specs);\n \n const targetType = findModelTypeFromConfig(specs, targetId);\n if (!targetType) {\n console.error(chalk.red(` Error: Target '${targetId}' not found`));\n process.exit(1);\n }\n \n console.log(chalk.blue(' Analyzing impact...'));\n const result = analyzeImpact(registry, targetId, targetType, maxDepth);\n \n outputImpactResults(result, options);\n \n } catch (error) {\n console.error(chalk.red('Impact analysis failed:'), error);\n process.exit(1);\n }\n}\n\n// ============================================================================\n// Impact Analysis\n// ============================================================================\n\nfunction analyzeImpact(\n registry: Record<string, Map<string, unknown>>,\n targetId: string,\n targetType: string,\n maxDepth: number\n): ImpactResult {\n const impactedNodes: ImpactNode[] = [];\n const visited = new Set<string>([targetId]);\n \n function findReferences(id: string, depth: number): void {\n if (depth > maxDepth) return;\n \n for (const [type, map] of Object.entries(registry)) {\n for (const [itemId, item] of map) {\n if (visited.has(itemId)) continue;\n \n const itemStr = JSON.stringify(item);\n if (itemStr.includes(`\"${id}\"`)) {\n visited.add(itemId);\n impactedNodes.push({\n id: itemId,\n type,\n depth,\n impactType: depth === 1 ? 'direct' : 'indirect',\n });\n \n findReferences(itemId, depth + 1);\n }\n }\n }\n }\n \n findReferences(targetId, 1);\n \n return {\n target: targetId,\n targetType,\n impactedNodes,\n };\n}\n\n// ============================================================================\n// Output\n// ============================================================================\n\nfunction outputImpactResults(result: ImpactResult, options: ImpactCommandOptions): void {\n console.log('');\n \n if (options.format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n \n if (options.format === 'mermaid') {\n console.log('```mermaid');\n console.log('graph TD');\n console.log(` ${result.target}[${result.target}]`);\n for (const node of result.impactedNodes) {\n const style = node.impactType === 'direct' ? '-->|direct|' : '-.->|indirect|';\n console.log(` ${result.target} ${style} ${node.id}[${node.id}]`);\n }\n console.log('```');\n return;\n }\n \n if (result.impactedNodes.length === 0) {\n console.log(chalk.green(' No impacted elements found'));\n return;\n }\n \n const direct = result.impactedNodes.filter(n => n.impactType === 'direct');\n const indirect = result.impactedNodes.filter(n => n.impactType === 'indirect');\n \n if (direct.length > 0) {\n console.log(chalk.yellow(` Direct impact (${direct.length}):`));\n for (const node of direct) {\n console.log(chalk.yellow(` → ${node.id} (${node.type})`));\n }\n }\n \n if (indirect.length > 0) {\n console.log(chalk.gray(` Indirect impact (${indirect.length}):`));\n for (const node of indirect) {\n console.log(chalk.gray(` ⤳ ${node.id} (${node.type}, depth: ${node.depth})`));\n }\n }\n \n console.log('');\n console.log(chalk.gray(` Total: ${result.impactedNodes.length} impacted elements`));\n}\n","/**\n * speckeeper init command\n * \n * Generate starter templates for a new speckeeper project\n */\nimport chalk from 'chalk';\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport async function runInit(options: InitOptions = {}): Promise<void> {\n const cwd = process.cwd();\n \n console.log(chalk.cyan('speckeeper init'));\n console.log('');\n \n // Check if already initialized\n const designDir = join(cwd, 'design');\n const configFile = join(cwd, 'speckeeper.config.ts');\n \n if (!options.force && (existsSync(designDir) || existsSync(configFile))) {\n console.log(chalk.yellow(' Project already initialized.'));\n console.log(chalk.gray(' Use --force to overwrite existing files.'));\n return;\n }\n \n // Get project name from directory\n const projectName = cwd.split('/').pop() || 'my-project';\n \n // Find templates directory\n const templatesDir = join(__dirname, 'templates', 'init');\n \n if (!existsSync(templatesDir)) {\n console.log(chalk.red(` Error: Templates directory not found at ${templatesDir}`));\n console.log(chalk.gray(' Please ensure the package is properly installed.'));\n return;\n }\n \n // Copy template files\n let packageJsonCreated = false;\n copyTemplateDir(templatesDir, cwd, projectName, options.force || false, (relativePath, created) => {\n if (created) {\n console.log(chalk.green(` Created: ${relativePath}`));\n if (relativePath === 'package.json') {\n packageJsonCreated = true;\n }\n } else {\n console.log(chalk.yellow(` Skipped: ${relativePath} (already exists)`));\n }\n });\n \n console.log('');\n console.log(chalk.cyan(' Project initialized successfully!'));\n console.log('');\n console.log(' Next steps:');\n if (packageJsonCreated) {\n console.log(chalk.gray(' 1. Run `npm install` to install dependencies'));\n console.log(chalk.gray(' 2. Add spec data in design/*.ts using defineSpecs()'));\n console.log(chalk.gray(' 3. Import new spec files in design/index.ts'));\n console.log(chalk.gray(' 4. Run `npx speckeeper lint` to validate'));\n } else {\n console.log(chalk.gray(' 1. Add speckeeper and zod to your package.json dependencies'));\n console.log(chalk.gray(' 2. Ensure \"type\": \"module\" is set in package.json'));\n console.log(chalk.gray(' 3. Add spec data in design/*.ts using defineSpecs()'));\n console.log(chalk.gray(' 4. Import new spec files in design/index.ts'));\n console.log(chalk.gray(' 5. Run `npx speckeeper lint` to validate'));\n }\n}\n\n/**\n * Recursively copy template directory\n */\nfunction copyTemplateDir(\n srcDir: string,\n destDir: string,\n projectName: string,\n force: boolean,\n onFile: (relativePath: string, created: boolean) => void,\n relativePath: string = ''\n): void {\n const entries = readdirSync(srcDir);\n \n for (const entry of entries) {\n const srcPath = join(srcDir, entry);\n const stat = statSync(srcPath);\n \n // Handle .template extension\n const destEntry = entry.endsWith('.template') ? entry.slice(0, -9) : entry;\n const destPath = join(destDir, destEntry);\n const relPath = relativePath ? join(relativePath, destEntry) : destEntry;\n \n if (stat.isDirectory()) {\n // Create directory if it doesn't exist\n if (!existsSync(destPath)) {\n mkdirSync(destPath, { recursive: true });\n onFile(relPath + '/', true);\n }\n // Recurse into directory\n copyTemplateDir(srcPath, destPath, projectName, force, onFile, relPath);\n } else {\n // Skip if file exists and not force\n if (!force && existsSync(destPath)) {\n onFile(relPath, false);\n continue;\n }\n \n // Read and process template\n let content = readFileSync(srcPath, 'utf-8');\n \n // Replace template variables\n content = content.replace(/\\{\\{PROJECT_NAME\\}\\}/g, projectName);\n \n // Write file\n const dir = dirname(destPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(destPath, content);\n onFile(relPath, true);\n }\n }\n}\n","/**\n * Mermaid flowchart parser\n *\n * Extracts nodes, edges, classDefs, and class assignments\n * from a mermaid flowchart block embedded in Markdown.\n */\nimport type {\n ArrowDirection,\n MermaidNode,\n MermaidEdge,\n MermaidClassDef,\n MermaidClassAssignment,\n SubgraphInfo,\n ParsedFlowchart,\n} from './types.js';\n\n/**\n * Extract mermaid code blocks from Markdown content\n */\nexport function extractMermaidBlocks(markdown: string): string[] {\n const blocks: string[] = [];\n const regex = /```mermaid\\s*\\n([\\s\\S]*?)```/g;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(markdown)) !== null) {\n blocks.push(match[1]);\n }\n return blocks;\n}\n\n/**\n * Parse a mermaid flowchart block into structured data\n */\nexport function parseFlowchart(mermaidSource: string): ParsedFlowchart {\n const lines = mermaidSource.split('\\n');\n const nodes = new Map<string, MermaidNode>();\n const edges: MermaidEdge[] = [];\n const classDefs: MermaidClassDef[] = [];\n const classAssignments: MermaidClassAssignment[] = [];\n const subgraphs: SubgraphInfo[] = [];\n let direction = 'TB';\n\n const subgraphStack: SubgraphInfo[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.trim();\n\n if (!line || line.startsWith('%%')) continue;\n\n const flowchartMatch = line.match(/^flowchart\\s+(\\w+)/);\n if (flowchartMatch) {\n direction = flowchartMatch[1];\n continue;\n }\n\n if (line.startsWith('graph ')) {\n const gMatch = line.match(/^graph\\s+(\\w+)/);\n if (gMatch) direction = gMatch[1];\n continue;\n }\n\n // subgraph id [Label] or subgraph id\n const subgraphMatch = line.match(/^subgraph\\s+(\\S+)(?:\\s*\\[([^\\]]*)\\])?/);\n if (subgraphMatch) {\n const sg: SubgraphInfo = {\n id: subgraphMatch[1],\n label: subgraphMatch[2] || undefined,\n nodeIds: [],\n };\n subgraphStack.push(sg);\n continue;\n }\n\n if (line === 'end' && subgraphStack.length > 0) {\n const completed = subgraphStack.pop()!;\n subgraphs.push(completed);\n for (const nodeId of completed.nodeIds) {\n const node = nodes.get(nodeId);\n if (node) {\n node.subgraph = completed.id;\n }\n }\n continue;\n }\n\n const classDefMatch = line.match(/^classDef\\s+(\\S+)\\s+(.*)/);\n if (classDefMatch) {\n classDefs.push({ name: classDefMatch[1], styles: classDefMatch[2] });\n continue;\n }\n\n const classAssignMatch = line.match(/^class\\s+(\\S+)\\s+(\\S+)/);\n if (classAssignMatch) {\n const nodeIds = classAssignMatch[1].split(',').map(s => s.trim());\n classAssignments.push({ nodeIds, className: classAssignMatch[2] });\n for (const id of nodeIds) {\n ensureNode(nodes, id);\n const node = nodes.get(id)!;\n if (!node.classes.includes(classAssignMatch[2])) {\n node.classes.push(classAssignMatch[2]);\n }\n }\n continue;\n }\n\n const edgeParsed = tryParseEdgeLine(line);\n if (edgeParsed) {\n for (const { sourceId, sourceLabel, targetId, targetLabel, label, direction: dir } of edgeParsed) {\n ensureNode(nodes, sourceId, sourceLabel);\n ensureNode(nodes, targetId, targetLabel);\n edges.push({\n sourceId,\n targetId,\n rawLabel: label,\n direction: dir,\n });\n if (subgraphStack.length > 0) {\n const current = subgraphStack[subgraphStack.length - 1];\n if (!current.nodeIds.includes(sourceId)) current.nodeIds.push(sourceId);\n if (!current.nodeIds.includes(targetId)) current.nodeIds.push(targetId);\n }\n }\n continue;\n }\n\n const standaloneNode = tryParseStandaloneNode(line);\n if (standaloneNode) {\n ensureNode(nodes, standaloneNode.id, standaloneNode.label);\n if (subgraphStack.length > 0) {\n const current = subgraphStack[subgraphStack.length - 1];\n if (!current.nodeIds.includes(standaloneNode.id)) current.nodeIds.push(standaloneNode.id);\n }\n }\n }\n\n return { direction, nodes, edges, classDefs, classAssignments, subgraphs };\n}\n\n/**\n * Parse Markdown and return the first flowchart found\n */\nexport function parseMarkdownFlowchart(markdown: string): ParsedFlowchart | null {\n const blocks = extractMermaidBlocks(markdown);\n for (const block of blocks) {\n const trimmed = block.trim();\n if (trimmed.startsWith('flowchart') || trimmed.startsWith('graph')) {\n return parseFlowchart(trimmed);\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction ensureNode(nodes: Map<string, MermaidNode>, id: string, label?: string): void {\n const existing = nodes.get(id);\n if (existing) {\n if (label && !existing.label) {\n existing.label = label;\n }\n } else {\n nodes.set(id, { id, label, classes: [] });\n }\n}\n\n/** Node with optional label: ID[Label text] or ID */\nconst NODE_PATTERN = /([A-Za-z_]\\w*)(?:\\[([^\\]]*)\\])?/;\n\ninterface ParsedEdgeResult {\n sourceId: string;\n sourceLabel: string | undefined;\n targetId: string;\n targetLabel: string | undefined;\n label: string | undefined;\n direction: ArrowDirection;\n}\n\n/**\n * Try to parse an edge line. Returns array of edges (a line can have chained edges).\n *\n * Supported arrow patterns:\n * --> ---> ----> forward\n * <--> <---> <----> bidirectional\n * -.-> forward (dotted)\n * ==> forward (thick)\n * -->|label| forward with label\n * <-->|label| bidirectional with label\n */\nfunction tryParseEdgeLine(line: string): ParsedEdgeResult[] | null {\n // Arrow patterns, ordered longest-first to avoid partial matches\n const arrowPatterns = [\n { regex: /<-{2,}>/, direction: 'bidirectional' as ArrowDirection },\n { regex: /<={2,}>/, direction: 'bidirectional' as ArrowDirection },\n { regex: /-{2,}>/, direction: 'forward' as ArrowDirection },\n { regex: /={2,}>/, direction: 'forward' as ArrowDirection },\n { regex: /-\\.->/, direction: 'forward' as ArrowDirection },\n ];\n\n // Try to find any arrow in the line\n let bestMatch: {\n index: number;\n length: number;\n direction: ArrowDirection;\n } | null = null;\n\n for (const ap of arrowPatterns) {\n const m = line.match(ap.regex);\n if (m && m.index !== undefined) {\n if (!bestMatch || m.index < bestMatch.index) {\n bestMatch = { index: m.index, length: m[0].length, direction: ap.direction };\n }\n }\n }\n\n if (!bestMatch) return null;\n\n // Split line at the arrow\n const leftPart = line.substring(0, bestMatch.index).trim();\n const rightPart = line.substring(bestMatch.index + bestMatch.length).trim();\n\n // Extract source node from left part\n const sourceMatch = leftPart.match(NODE_PATTERN);\n if (!sourceMatch) return null;\n const sourceId = sourceMatch[1];\n const sourceLabel = sourceMatch[2] || undefined;\n\n // Right part may be: |label| TargetNode or just TargetNode\n let label: string | undefined;\n let targetStr = rightPart;\n\n const labelMatch = rightPart.match(/^\\|([^|]*)\\|\\s*(.*)/);\n if (labelMatch) {\n label = labelMatch[1].trim();\n targetStr = labelMatch[2];\n }\n\n // Extract target node\n const targetMatch = targetStr.match(NODE_PATTERN);\n if (!targetMatch) return null;\n const targetId = targetMatch[1];\n const targetLabel = targetMatch[2] || undefined;\n\n return [{\n sourceId,\n sourceLabel,\n targetId,\n targetLabel,\n label,\n direction: bestMatch.direction,\n }];\n}\n\nfunction tryParseStandaloneNode(line: string): { id: string; label: string | undefined } | null {\n const m = line.match(/^([A-Za-z_]\\w*)\\[([^\\]]*)\\]\\s*$/);\n if (m) {\n return { id: m[1], label: m[2] };\n }\n return null;\n}\n","/**\n * Edge label controlled vocabulary (logic-driven)\n *\n * Only edges that trigger specific speckeeper logic are defined here.\n * Other speckeeper↔speckeeper edges use generic reference integrity.\n */\nimport type {\n EdgeVocabularyEntry,\n MermaidEdge,\n MermaidNode,\n ResolvedEdge,\n ScaffoldDiagnostic,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Vocabulary definitions\n// ---------------------------------------------------------------------------\n\n/**\n * Speckeeper-managed vocabulary — labels that trigger specific logic.\n *\n * - implements (check): speckeeper → external SSOT, triggers external checker\n * - verifiedBy (check): speckeeper → external test, triggers test checker\n * - refines (lint): speckeeper → speckeeper, reference integrity + level constraint\n * - All other speckeeper↔speckeeper edges: generic reference integrity (lint)\n */\nexport const EDGE_VOCABULARY: EdgeVocabularyEntry[] = [\n // check: speckeeper → external SSOT\n {\n label: 'implements',\n expectedDirection: 'forward',\n relationType: 'implements',\n category: 'check',\n description: 'Spec is implemented as external artifact (OpenAPI, DDL, etc.)',\n },\n {\n label: 'verifiedBy',\n expectedDirection: 'forward',\n relationType: 'verifiedBy',\n category: 'check',\n description: 'Spec is verified by external test code',\n },\n\n // lint: speckeeper ↔ speckeeper with level constraint\n {\n label: 'refines',\n expectedDirection: 'forward',\n relationType: 'refines',\n category: 'lint',\n description: 'Decompose higher-level item into lower-level detail',\n },\n\n // lint: speckeeper ↔ speckeeper generic reference integrity\n {\n label: 'relatedTo',\n expectedDirection: 'bidirectional',\n relationType: 'relatedTo',\n category: 'lint',\n description: 'Bidirectional association or consistency constraint',\n },\n {\n label: 'uses',\n expectedDirection: 'forward',\n relationType: 'uses',\n category: 'lint',\n description: 'Reference / dependency',\n },\n {\n label: 'dependsOn',\n expectedDirection: 'forward',\n relationType: 'dependsOn',\n category: 'lint',\n description: 'Dependency relationship',\n },\n {\n label: 'satisfies',\n expectedDirection: 'forward',\n relationType: 'satisfies',\n category: 'lint',\n description: 'Satisfies business/requirements',\n },\n {\n label: 'includes',\n expectedDirection: 'forward',\n relationType: 'includes',\n category: 'lint',\n description: 'Parent contains child items',\n },\n {\n label: 'traces',\n expectedDirection: 'forward',\n relationType: 'traces',\n category: 'lint',\n description: 'Derive target from source',\n },\n\n // external: test code → implementation code (no checker generated)\n {\n label: 'verifies',\n expectedDirection: 'forward',\n relationType: 'verifies',\n category: 'external',\n description: 'Test code tests implementation code (external → external, no checker)',\n },\n];\n\n/**\n * Well-known labels for edges between non-speckeeper nodes.\n */\nexport const EXTERNAL_LABELS: EdgeVocabularyEntry[] = [\n {\n label: 'generate',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'drift',\n description: 'Automated generation (external tool)',\n },\n {\n label: 'apply',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'external',\n description: 'Apply to external system',\n },\n {\n label: 'deploy',\n expectedDirection: 'forward',\n relationType: undefined,\n category: 'external',\n description: 'Deploy artifact',\n },\n];\n\nconst ALL_VOCABULARY = [...EDGE_VOCABULARY, ...EXTERNAL_LABELS];\n\nconst SORTED_VOCABULARY = [...ALL_VOCABULARY].sort(\n (a, b) => b.label.length - a.label.length,\n);\n\nconst SORTED_SPECKEEPER_VOCABULARY = [...EDGE_VOCABULARY].sort(\n (a, b) => b.label.length - a.label.length,\n);\n\n// ---------------------------------------------------------------------------\n// Label normalisation\n// ---------------------------------------------------------------------------\n\n/**\n * Normalise a raw edge label to its canonical vocabulary entry.\n */\nexport function normalizeLabel(\n rawLabel: string | undefined,\n vocabulary: EdgeVocabularyEntry[] = SORTED_VOCABULARY,\n): { entry: EdgeVocabularyEntry; modifier: string | undefined } | null {\n if (!rawLabel) return null;\n\n const lower = rawLabel.toLowerCase().trim();\n\n for (const entry of vocabulary) {\n if (lower === entry.label.toLowerCase()) {\n return { entry, modifier: undefined };\n }\n }\n\n for (const entry of vocabulary) {\n const entryLower = entry.label.toLowerCase();\n if (lower.endsWith(entryLower)) {\n const mod = rawLabel.slice(0, rawLabel.length - entry.label.length).trim();\n return { entry, modifier: mod || undefined };\n }\n }\n\n for (const entry of vocabulary) {\n const entryLower = entry.label.toLowerCase();\n if (lower.includes(entryLower)) {\n const idx = lower.indexOf(entryLower);\n const before = rawLabel.slice(0, idx).trim();\n const after = rawLabel.slice(idx + entry.label.length).trim();\n const mod = [before, after].filter(Boolean).join(' ');\n return { entry, modifier: mod || undefined };\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Edge resolution\n// ---------------------------------------------------------------------------\n\n/** Known test-like node classes */\nconst TEST_CLASSES = new Set(['test', 'e2e-test', 'unit-test', 'integration-test']);\n\nfunction isTestLikeByClass(node: MermaidNode | undefined): boolean {\n if (!node) return false;\n return node.classes.some(c => TEST_CLASSES.has(c) || c.includes('test'));\n}\n\n/**\n * Resolve raw edges to vocabulary-backed ResolvedEdges,\n * collecting diagnostics along the way.\n */\nexport function resolveEdges(\n edges: MermaidEdge[],\n nodes: Map<string, MermaidNode>,\n speckeeperClassName: string,\n): { resolved: ResolvedEdge[]; diagnostics: ScaffoldDiagnostic[] } {\n const diagnostics: ScaffoldDiagnostic[] = [];\n const resolved: ResolvedEdge[] = [];\n\n const isSpk = (id: string): boolean =>\n nodes.get(id)?.classes.includes(speckeeperClassName) ?? false;\n\n const fallback = EDGE_VOCABULARY.find(v => v.label === 'relatedTo')!;\n\n for (const edge of edges) {\n const involvesSpeckeeper = isSpk(edge.sourceId) || isSpk(edge.targetId);\n\n const norm = normalizeLabel(edge.rawLabel);\n\n if (!norm) {\n if (involvesSpeckeeper) {\n diagnostics.push({\n severity: 'warning',\n message: `Edge label \"${edge.rawLabel}\" is not a valid speckeeper RelationType — falling back to \"relatedTo\"`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n resolved.push({\n ...edge,\n normalizedLabel: 'relatedTo',\n vocabulary: fallback,\n modifier: undefined,\n });\n } else {\n resolved.push({\n ...edge,\n normalizedLabel: edge.rawLabel ?? '',\n vocabulary: { label: edge.rawLabel ?? '', expectedDirection: 'forward', relationType: undefined, category: 'external', description: '' },\n modifier: undefined,\n });\n }\n continue;\n }\n\n if (involvesSpeckeeper && !norm.entry.relationType) {\n const spkNorm = normalizeLabel(edge.rawLabel, SORTED_SPECKEEPER_VOCABULARY);\n if (!spkNorm) {\n diagnostics.push({\n severity: 'warning',\n message: `Edge label \"${edge.rawLabel}\" is not a valid speckeeper RelationType — falling back to \"relatedTo\"`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n resolved.push({\n ...edge,\n normalizedLabel: 'relatedTo',\n vocabulary: fallback,\n modifier: undefined,\n });\n continue;\n }\n }\n\n resolved.push({\n ...edge,\n normalizedLabel: norm.entry.label,\n vocabulary: norm.entry,\n modifier: norm.modifier,\n });\n\n // Validate arrow direction\n if (involvesSpeckeeper && edge.direction !== norm.entry.expectedDirection) {\n const expected = norm.entry.expectedDirection === 'bidirectional' ? '<-->' : '-->';\n diagnostics.push({\n severity: 'warning',\n message: `\"${norm.entry.label}\" expects ${expected} arrow but got ${edge.direction === 'bidirectional' ? '<-->' : '-->'}`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n\n // Validate: \"implements\" should be speckeeper → external only\n if (norm.entry.label === 'implements') {\n if (isSpk(edge.sourceId) && isSpk(edge.targetId)) {\n diagnostics.push({\n severity: 'warning',\n message: '\"implements\" should be speckeeper → external; consider using \"refines\" for speckeeper → speckeeper edges',\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n }\n\n // Validate: \"verifiedBy\" should be speckeeper → external only\n if (norm.entry.label === 'verifiedBy') {\n if (isSpk(edge.sourceId) && isSpk(edge.targetId)) {\n diagnostics.push({\n severity: 'warning',\n message: '\"verifiedBy\" should be speckeeper → external; it represents verification by external test code',\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n\n // Warn if target is not a test-like node\n const targetNode = nodes.get(edge.targetId);\n if (targetNode && !isTestLikeByClass(targetNode)) {\n const targetId = edge.targetId.toUpperCase();\n const looksLikeTest = ['UT', 'IT', 'DUT', 'E2ET'].includes(targetId) ||\n targetId.includes('TEST') ||\n (targetNode.label ?? '').toLowerCase().includes('test');\n if (!looksLikeTest) {\n diagnostics.push({\n severity: 'warning',\n message: `\"verifiedBy\" target \"${edge.targetId}\" does not appear to be a test node; verifiedBy is intended for test targets`,\n context: `${edge.sourceId} → ${edge.targetId}`,\n });\n }\n }\n }\n }\n\n return { resolved, diagnostics };\n}\n\n// ---------------------------------------------------------------------------\n// Category helpers\n// ---------------------------------------------------------------------------\n\nexport function isLintEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'lint';\n}\n\nexport function isCheckEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'check';\n}\n\nexport function isCoverageEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'coverage';\n}\n\nexport function isDriftEdge(entry: EdgeVocabularyEntry): boolean {\n return entry.category === 'drift';\n}\n\n/**\n * Determine whether a node is test-like (by ID, label, or class).\n */\nexport function isTestLikeNode(node: MermaidNode | undefined): boolean {\n if (!node) return false;\n if (isTestLikeByClass(node)) return true;\n const id = node.id.toUpperCase();\n const testIds = ['UT', 'IT', 'DUT', 'E2ET'];\n if (testIds.includes(id)) return true;\n if (id.includes('TEST')) return true;\n const label = (node.label ?? '').toLowerCase();\n if (label.includes('テスト') || label.includes('test')) return true;\n return false;\n}\n","/**\n * Template registry\n *\n * Resolves mermaid node classes to model template info.\n * All classes use the common base template (FR-SCF-028).\n * Class name is used only for model name / file name derivation\n * and node grouping — no class-specific templates exist.\n */\n\nimport type { ModelLevel } from '../core/relation.js';\n\n// ---------------------------------------------------------------------------\n// Model template metadata\n// ---------------------------------------------------------------------------\n\nexport interface ModelTemplateInfo {\n /** Template identifier — always 'base' (FR-SCF-028) */\n templateName: 'base';\n /** Default model level (inferred from subgraph) */\n defaultLevel: ModelLevel;\n /** ID prefix for spec instances (= node ID) */\n defaultIdPrefix: string;\n /** Human-readable model name (PascalCase) */\n modelName: string;\n /** kebab-case file name (without .ts) */\n fileName: string;\n}\n\n// ---------------------------------------------------------------------------\n// Subgraph → Level inference\n// ---------------------------------------------------------------------------\n\nconst LEVEL_PATTERNS: Array<{ pattern: RegExp; level: ModelLevel }> = [\n { pattern: /^L0$|business|domain/i, level: 'L0' },\n { pattern: /^L1$|requirement/i, level: 'L1' },\n { pattern: /^L2$|design|architecture/i, level: 'L2' },\n { pattern: /^L3$|implementation|external/i, level: 'L3' },\n];\n\nexport function inferLevelFromSubgraph(subgraphId: string | undefined): ModelLevel {\n if (!subgraphId) return 'L0';\n for (const { pattern, level } of LEVEL_PATTERNS) {\n if (pattern.test(subgraphId)) return level;\n }\n return 'L0';\n}\n\n// ---------------------------------------------------------------------------\n// Class-based resolution\n// ---------------------------------------------------------------------------\n\nconst SPECKEEPER_CLASS = 'speckeeper';\n\n/**\n * Resolve a mermaid node to a model template.\n *\n * Always uses the base template (FR-SCF-028). The artifact class\n * (first non-speckeeper class) determines only model name and file name.\n * Level is inferred from subgraph membership.\n */\nexport function resolveModelTemplate(\n nodeId: string,\n nodeClasses?: string[],\n subgraphId?: string,\n): ModelTemplateInfo {\n const level = inferLevelFromSubgraph(subgraphId);\n\n const artifactClass = nodeClasses\n ?.find(c => c !== SPECKEEPER_CLASS);\n\n if (!artifactClass) {\n return {\n templateName: 'base',\n defaultLevel: level,\n defaultIdPrefix: nodeId,\n modelName: toPascalCase(nodeId),\n fileName: toKebabCase(nodeId),\n };\n }\n\n return {\n templateName: 'base',\n defaultLevel: level,\n defaultIdPrefix: nodeId,\n modelName: toPascalCase(artifactClass),\n fileName: toKebabCase(artifactClass),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toPascalCase(s: string): string {\n return s\n .split(/[-_]/)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())\n .join('');\n}\n\nfunction toKebabCase(s: string): string {\n return s\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[_\\s]+/g, '-')\n .toLowerCase();\n}\n","import type { ModelTemplateParams } from './types.js';\n\nexport function generateBaseModel(params: ModelTemplateParams): string {\n const schemaName = `${params.modelName}Schema`;\n const className = `${params.modelName}Model`;\n\n const dslImportLine = `import { requireField } from 'speckeeper/dsl';`;\n\n return `/**\n * ${params.modelName} Model Definition\n *\n * Generated by speckeeper scaffold — customise as needed.\n */\nimport { z } from 'zod';\nimport { Model, RelationSchema } from 'speckeeper';\nimport type { LintRule, Exporter, ModelLevel } from 'speckeeper';\n${dslImportLine}\n\n// =============================================================================\n// Schema Definition\n// =============================================================================\n\nexport const ${schemaName} = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\n// =============================================================================\n// Type Export\n// =============================================================================\n\nexport type ${params.modelName} = z.input<typeof ${schemaName}>;\n\n// =============================================================================\n// Model Class\n// =============================================================================\n\nclass ${className} extends Model<typeof ${schemaName}> {\n readonly id = '${params.modelId}';\n readonly name = '${params.modelName}';\n readonly idPrefix = '${params.idPrefix}';\n readonly schema = ${schemaName};\n readonly description = '${params.description}';\n // TODO: adjust modelLevel\n protected modelLevel: ModelLevel = '${params.level}';\n\n protected lintRules: LintRule<${params.modelName}>[] = [\n requireField<${params.modelName}>('description'),\n ];\n\n protected exporters: Exporter<${params.modelName}>[] = [];\n}\n\nexport { ${className} };\n`;\n}\n","/**\n * Template registry — base template only\n *\n * All artifact classes use the same base template (FR-SCF-028).\n * Class-specific schemas, lint rules, and exporters are not pre-defined;\n * users customise the generated model after scaffold.\n */\nimport type { ModelTemplateParams } from './types.js';\nimport { generateBaseModel } from './base.js';\n\nexport type ModelTemplateFunction = (params: ModelTemplateParams) => string;\n\nexport const MODEL_TEMPLATE_FUNCTIONS: Record<string, ModelTemplateFunction> = {\n base: generateBaseModel,\n};\n","/**\n * Model file generator\n *\n * Generates _models/*.ts files for speckeeper-managed nodes\n * by resolving artifact class from mermaid node classes.\n */\nimport type {\n MermaidNode,\n ResolvedEdge,\n GeneratedFile,\n} from './types.js';\nimport { resolveModelTemplate } from './template-registry.js';\nimport { MODEL_TEMPLATE_FUNCTIONS } from './templates/index.js';\n\nexport { ARTIFACT_CLASS_DEFAULTS } from './artifact-defaults.js';\n\n// ---------------------------------------------------------------------------\n// Model file generation\n// ---------------------------------------------------------------------------\n\n/**\n * Generate _models/*.ts file for a single speckeeper-managed node.\n */\nexport function generateModelFile(\n node: MermaidNode,\n _incomingEdges: ResolvedEdge[],\n _outgoingEdges: ResolvedEdge[],\n _allNodes?: Map<string, MermaidNode>,\n): GeneratedFile {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const templateFn = MODEL_TEMPLATE_FUNCTIONS[templateInfo.templateName];\n\n const params = {\n modelId: templateInfo.fileName,\n modelName: templateInfo.modelName,\n idPrefix: templateInfo.defaultIdPrefix,\n level: templateInfo.defaultLevel,\n description: node.label ?? node.id,\n };\n\n const content =\n !templateFn ? MODEL_TEMPLATE_FUNCTIONS['base'](params) : templateFn(params);\n\n return {\n relativePath: `_models/${templateInfo.fileName}.ts`,\n content,\n };\n}\n\n/**\n * Generate a spec data file that exports a SpecModule via defineSpecs().\n */\nexport function generateSpecDataFile(\n node: MermaidNode,\n): GeneratedFile {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const className = `${templateInfo.modelName}Model`;\n const typeName = templateInfo.modelName;\n const varName = toCamelCase(templateInfo.modelName) + 's';\n const fileName = templateInfo.fileName;\n\n const content = `/**\n * ${templateInfo.modelName} Specifications\n *\n * Generated by speckeeper scaffold — add your specs below.\n */\nimport { defineSpecs } from 'speckeeper';\nimport type { ${typeName} } from './_models/${fileName}';\nimport { ${className} } from './_models/${fileName}';\n\nconst ${varName}: ${typeName}[] = [\n // { id: '${templateInfo.defaultIdPrefix}-001', name: '...', description: '...' },\n];\n\nexport default defineSpecs(\n [${className}.instance, ${varName}],\n);\n`;\n\n return {\n relativePath: `${fileName}.ts`,\n content,\n };\n}\n\nfunction toCamelCase(pascalCase: string): string {\n return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);\n}\n\n/**\n * Generate design/index.ts that merges all spec data files.\n */\nexport function generateDesignIndex(\n speckeeperNodes: MermaidNode[],\n): GeneratedFile {\n const generated = new Set<string>();\n const specFiles: { varName: string; fileName: string }[] = [];\n\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const hasArtifactClass = node.classes.some(c => c !== 'speckeeper');\n const key = hasArtifactClass ? templateInfo.fileName : `base:${node.id}`;\n\n if (generated.has(key)) continue;\n generated.add(key);\n\n specFiles.push({\n varName: toCamelCase(templateInfo.modelName),\n fileName: templateInfo.fileName,\n });\n }\n\n const imports = specFiles\n .map(f => `import ${f.varName} from './${f.fileName}';`)\n .join('\\n');\n const args = specFiles.map(f => f.varName).join(', ');\n\n const content = `/**\n * Design entry point — generated by speckeeper scaffold\n */\nimport { mergeSpecs } from 'speckeeper';\n${imports}\n\nexport default mergeSpecs(${args});\n`;\n\n return {\n relativePath: 'index.ts',\n content,\n };\n}\n\n/**\n * Generate all model files for speckeeper-managed nodes.\n *\n * Multiple nodes with the same artifact class are de-duplicated\n * into a single model file (e.g. FR, SR, NFR with class 'requirement').\n */\nexport function generateAllModelFiles(\n speckeeperNodes: MermaidNode[],\n resolvedEdges: ResolvedEdge[],\n allNodes?: Map<string, MermaidNode>,\n): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n const generated = new Set<string>();\n\n const templateNodeGroups = new Map<string, MermaidNode[]>();\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const hasArtifactClass = node.classes.some(c => c !== 'speckeeper');\n const key = hasArtifactClass ? templateInfo.fileName : `base:${node.id}`;\n const group = templateNodeGroups.get(key) ?? [];\n group.push(node);\n templateNodeGroups.set(key, group);\n }\n\n for (const node of speckeeperNodes) {\n const templateInfo = resolveModelTemplate(node.id, node.classes, node.subgraph);\n const hasArtifactClass = node.classes.some(c => c !== 'speckeeper');\n const key = hasArtifactClass ? templateInfo.fileName : `base:${node.id}`;\n\n if (generated.has(key)) continue;\n generated.add(key);\n\n const groupNodes = templateNodeGroups.get(key) ?? [node];\n const groupNodeIds = new Set(groupNodes.map(n => n.id));\n const incoming = resolvedEdges.filter(e => groupNodeIds.has(e.targetId));\n const outgoing = resolvedEdges.filter(e => groupNodeIds.has(e.sourceId));\n files.push(generateModelFile(node, incoming, outgoing, allNodes));\n files.push(generateSpecDataFile(node));\n }\n\n files.push(generateDesignIndex(speckeeperNodes));\n\n return files;\n}\n","/**\n * Index file generator\n *\n * Generates _models/index.ts that re-exports all model classes\n * and provides an allModels array.\n */\nimport type { GeneratedFile } from './types.js';\n\ninterface ModelExportEntry {\n /** File name without .ts (e.g. 'requirement') */\n fileName: string;\n /** Class names to export (e.g. ['RequirementModel']) */\n classNames: string[];\n}\n\n/**\n * Derive model class names from generated model file content.\n *\n * Looks for `export { ClassName }` or `export { A, B }` at end of file.\n */\nfunction extractExportedClassNames(content: string): string[] {\n const match = content.match(/export\\s*\\{([^}]+)\\}\\s*;?\\s*$/m);\n if (!match) return [];\n return match[1].split(',').map(s => s.trim()).filter(Boolean);\n}\n\n/**\n * Generate _models/index.ts from a list of generated model files.\n */\nexport function generateModelsIndex(modelFiles: GeneratedFile[]): GeneratedFile {\n const entries: ModelExportEntry[] = [];\n\n for (const file of modelFiles) {\n const fileName = file.relativePath\n .replace(/^_models\\//, '')\n .replace(/\\.ts$/, '');\n const classNames = extractExportedClassNames(file.content);\n if (classNames.length > 0) {\n entries.push({ fileName, classNames });\n }\n }\n\n entries.sort((a, b) => a.fileName.localeCompare(b.fileName));\n\n const lines: string[] = [];\n lines.push('/**');\n lines.push(' * Model index — generated by speckeeper scaffold');\n lines.push(' */');\n lines.push('');\n\n for (const entry of entries) {\n lines.push(`export { ${entry.classNames.join(', ')} } from './${entry.fileName}.js';`);\n }\n\n lines.push('');\n\n const modelInstanceNames = entries.flatMap(e =>\n e.classNames.filter(n => n.endsWith('Model')),\n );\n\n if (modelInstanceNames.length > 0) {\n lines.push('import { Model } from \\'speckeeper\\';');\n lines.push('import type { ZodType } from \\'zod\\';');\n lines.push('');\n\n for (const entry of entries) {\n const models = entry.classNames.filter(n => n.endsWith('Model'));\n if (models.length > 0) {\n lines.push(`import { ${models.join(', ')} } from './${entry.fileName}.js';`);\n }\n }\n\n lines.push('');\n lines.push('// eslint-disable-next-line @typescript-eslint/no-explicit-any');\n lines.push('export const allModels: Model<ZodType>[] = [');\n\n for (const name of modelInstanceNames) {\n lines.push(` ${name}.instance as Model<ZodType>,`);\n }\n\n lines.push('];');\n }\n\n lines.push('');\n\n return {\n relativePath: '_models/index.ts',\n content: lines.join('\\n'),\n };\n}\n","/**\n * Scaffold Command\n *\n * Generate _models/ from a mermaid flowchart definition.\n * Checker logic is integrated into model definitions via core DSL factories.\n */\nimport chalk from 'chalk';\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { parseMarkdownFlowchart } from '../scaffold/mermaid-parser.js';\nimport { resolveEdges } from '../scaffold/edge-vocabulary.js';\nimport { generateAllModelFiles } from '../scaffold/model-generator.js';\nimport { generateModelsIndex } from '../scaffold/index-generator.js';\nimport type { GeneratedFile, MermaidNode, ScaffoldDiagnostic } from '../scaffold/types.js';\n\nconst SPECKEEPER_CLASS = 'speckeeper';\n\nexport interface ScaffoldCommandOptions {\n source: string;\n output?: string;\n force?: boolean;\n dryRun?: boolean;\n}\n\nexport async function scaffoldCommand(options: ScaffoldCommandOptions): Promise<void> {\n console.log(chalk.blue('speckeeper scaffold'));\n console.log('');\n\n const sourcePath = resolve(options.source);\n if (!existsSync(sourcePath)) {\n console.error(chalk.red(` Error: Source file not found: ${sourcePath}`));\n process.exit(1);\n }\n\n const markdown = readFileSync(sourcePath, 'utf-8');\n\n const flowchart = parseMarkdownFlowchart(markdown);\n if (!flowchart) {\n console.error(chalk.red(' Error: No mermaid flowchart found in the source file'));\n process.exit(1);\n }\n\n console.log(chalk.gray(` Parsed: ${flowchart.nodes.size} nodes, ${flowchart.edges.length} edges`));\n\n const speckeeperNodes: MermaidNode[] = [];\n for (const node of flowchart.nodes.values()) {\n if (node.classes.includes(SPECKEEPER_CLASS)) {\n speckeeperNodes.push(node);\n }\n }\n\n if (speckeeperNodes.length === 0) {\n console.error(chalk.red(` Error: No nodes with class \"${SPECKEEPER_CLASS}\" found`));\n console.log(chalk.gray(' Add `classDef speckeeper ...` and `class NODE1,NODE2 speckeeper` to your flowchart'));\n process.exit(1);\n }\n\n console.log(chalk.gray(` speckeeper-managed nodes: ${speckeeperNodes.map(n => n.id).join(', ')}`));\n\n const { resolved, diagnostics } = resolveEdges(\n flowchart.edges,\n flowchart.nodes,\n SPECKEEPER_CLASS,\n );\n\n printDiagnostics(diagnostics);\n\n const outputDir = options.output\n ? resolve(options.output)\n : join(process.cwd(), 'design');\n\n const modelFiles = generateAllModelFiles(speckeeperNodes, resolved, flowchart.nodes);\n const indexFile = generateModelsIndex(modelFiles);\n\n const allFiles: GeneratedFile[] = [...modelFiles, indexFile];\n\n console.log('');\n console.log(chalk.cyan(` Files to generate (${allFiles.length}):`));\n for (const file of allFiles) {\n console.log(chalk.gray(` ${file.relativePath}`));\n }\n\n if (options.dryRun) {\n console.log('');\n console.log(chalk.yellow(' Dry run — no files written'));\n console.log('');\n for (const file of allFiles) {\n console.log(chalk.cyan(` === ${file.relativePath} ===`));\n console.log(file.content);\n }\n return;\n }\n\n console.log('');\n let created = 0;\n let skipped = 0;\n\n for (const file of allFiles) {\n const fullPath = join(outputDir, file.relativePath);\n const dir = dirname(fullPath);\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n if (existsSync(fullPath) && !options.force) {\n console.log(chalk.yellow(` Skipped: ${file.relativePath} (already exists, use --force to overwrite)`));\n skipped++;\n continue;\n }\n\n writeFileSync(fullPath, file.content);\n console.log(chalk.green(` Created: ${file.relativePath}`));\n created++;\n }\n\n console.log('');\n console.log(chalk.cyan(` Done: ${created} created, ${skipped} skipped`));\n}\n\nfunction printDiagnostics(diagnostics: ScaffoldDiagnostic[]): void {\n if (diagnostics.length === 0) return;\n\n console.log('');\n console.log(chalk.cyan(' Diagnostics:'));\n\n for (const diag of diagnostics) {\n const prefix = diag.severity === 'error'\n ? chalk.red(' ERROR')\n : diag.severity === 'warning'\n ? chalk.yellow(' WARN ')\n : chalk.gray(' INFO ');\n const ctx = diag.context ? chalk.gray(` [${diag.context}]`) : '';\n console.log(`${prefix} ${diag.message}${ctx}`);\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { buildCommand } from './build.js';\nimport { lintCommand } from './lint.js';\nimport { driftCommand } from './drift.js';\nimport { checkCommand } from './check.js';\nimport { newCommand } from './new.js';\nimport { impactCommand } from './impact.js';\nimport { runInit } from './init.js';\nimport { scaffoldCommand } from './scaffold.js';\n\nfunction getVersion(): string {\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\n return pkg.version;\n } catch {\n return '0.0.0';\n }\n}\n\nconst program = new Command();\n\nprogram\n .name('speckeeper')\n .description('Requirements and design management framework with TypeScript DSL')\n .version(getVersion());\n\n// Build command\n// Spec: design/cli-commands.ts CMD-BUILD\nprogram\n .command('build')\n .description('Generate docs/ and specs/ from TypeScript models')\n .option('-c, --config <path>', 'Path to config file')\n .option('-o, --output <path>', 'Base output directory path', '.')\n .option('-f, --format <format>', 'Output format: markdown, json, both', 'both')\n .option('-w, --watch', 'Watch for changes and auto-regenerate')\n .option('-v, --verbose', 'Show detailed output')\n .action(buildCommand);\n\n// Lint command\n// Spec: design/cli-commands.ts CMD-LINT\nprogram\n .command('lint')\n .description('Check design integrity (ID duplicates, references, layer violations, etc.)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-p, --phase <phase>', 'Phase gate to check against (REQ, HLD, LLD, OPS)')\n .option('-s, --strict', 'Treat warnings as errors')\n .option('--fix', 'Attempt to fix auto-fixable issues')\n .option('-f, --format <format>', 'Output format: text, json, github', 'text')\n .action(lintCommand);\n\n// Drift command\n// Spec: design/cli-commands.ts CMD-DRIFT\nprogram\n .command('drift')\n .description('Check if generated files have been manually edited')\n .option('-c, --config <path>', 'Path to config file')\n .option('-u, --update', 'Auto-update if differences are found')\n .option('-f, --format <format>', 'Output format: text, json, diff', 'text')\n .option('--fail-on-drift', 'Exit with code 1 if drift is detected (for CI)')\n .action(driftCommand);\n\n// Check command\n// Spec: design/cli-commands.ts CMD-CHECK\nprogram\n .command('check')\n .description('Check external SSOT conformance (including custom models)')\n .argument('[type]', 'Type of check: external-ssot, openapi, ddl, iac, custom, all, test')\n .option('-c, --config <path>', 'Path to config file')\n .option('--strict', 'Treat warnings as errors')\n .option('-v, --verbose', 'Show detailed output')\n .option('--coverage', 'Check if all testable acceptance criteria are covered by TestRefs')\n .action(checkCommand);\n\n// New command\n// Spec: design/cli-commands.ts CMD-NEW\nprogram\n .command('new')\n .description('Create a new element with auto-generated ID')\n .argument('<type>', 'Type: requirement, usecase, entity, component, screen, flow, error-case, term')\n .option('-k, --kind <kind>', 'Sub-kind (e.g., functional, non-functional for requirements)')\n .option('-n, --name <name>', 'Name of the element')\n .option('-o, --output <path>', 'Output directory path')\n .option('-t, --template <path>', 'Path to template file')\n .action(newCommand);\n\n// Impact command\n// Spec: design/cli-commands.ts CMD-IMPACT\nprogram\n .command('impact')\n .description('Analyze impact of changes to an ID')\n .argument('<id>', 'ID to analyze (e.g., REQ-001, ENT-ORDER)')\n .option('-c, --config <path>', 'Path to config file')\n .option('-d, --depth <depth>', 'Analysis depth (reference tracking level)', '3')\n .option('--direction <direction>', 'Analysis direction: upstream, downstream, both', 'both')\n .option('-f, --format <format>', 'Output format: text, json, mermaid', 'text')\n .action(impactCommand);\n\n// Init command\nprogram\n .command('init')\n .description('Initialize a new speckeeper project with starter templates')\n .option('-f, --force', 'Overwrite existing files')\n .action(runInit);\n\n// Scaffold command\nprogram\n .command('scaffold')\n .description('Generate _models/ from a mermaid flowchart definition')\n .requiredOption('-s, --source <path>', 'Path to Markdown file containing mermaid flowchart')\n .option('-o, --output <path>', 'Output directory (default: design/)')\n .option('-f, --force', 'Overwrite existing files')\n .option('--dry-run', 'Preview generated files without writing')\n .action(scaffoldCommand);\n\n// Parse arguments\nprogram.parse();\n"]}