speckeeper 0.4.2 → 0.7.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.
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
1
+ {"version":3,"sources":["../../src/core/relation.ts","../../src/core/dsl/schema.ts","../../src/core/dsl/lint-rules.ts","../../src/core/dsl/exporters.ts","../../src/core/dsl/type-compat.ts","../../src/core/dsl/checkers.ts","../../src/core/dsl/relation-schemas.ts"],"names":["z","parseYaml"],"mappings":"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","file":"index.js","sourcesContent":["/**\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 * Core DSL — Base spec schema\n *\n * Common schema fields shared by all models: id, name, description, relations.\n * Models extend this with domain-specific fields via `.extend()`.\n */\nimport { z } from 'zod';\nimport { RelationSchema } from '../relation.js';\n\nexport const baseSpecSchema = z.object({\n id: z.string(),\n name: z.string().min(1),\n description: z.string(),\n relations: z.array(RelationSchema).optional(),\n});\n\nexport type BaseSpec = z.infer<typeof baseSpecSchema>;\n","/**\n * Core DSL — Lint rule factories\n *\n * Factory functions that produce LintRule<T> objects for common patterns.\n * Users compose these in their model's `lintRules` array.\n */\nimport type { LintRule } from '../model.js';\n\n/**\n * Require a string field to be non-empty.\n */\nexport function requireField<T>(\n field: keyof T & string,\n severity: 'error' | 'warning' | 'info' = 'warning',\n): LintRule<T> {\n return {\n id: `has-${field}`,\n severity,\n message: `${field} must not be empty`,\n check: (spec) => {\n const value = (spec as Record<string, unknown>)[field];\n return !value || (typeof value === 'string' && value.trim() === '');\n },\n };\n}\n\n/**\n * Require an array field to have at least `min` elements.\n */\nexport function arrayMinLength<T>(\n field: keyof T & string,\n min: number,\n severity: 'error' | 'warning' = 'error',\n): LintRule<T> {\n return {\n id: `${field}-min-${min}`,\n severity,\n message: `${field} must have at least ${min} item(s)`,\n check: (spec) => {\n const value = (spec as Record<string, unknown>)[field];\n return !Array.isArray(value) || value.length < min;\n },\n };\n}\n\n/**\n * Require the `id` field to match a prefix-based format.\n *\n * Default pattern: `{prefix}-{NNN}` (e.g. `FR-001`).\n * Override with `opts.pattern` for custom formats.\n */\nexport function idFormat<T>(\n prefix: string,\n opts?: { digits?: number; pattern?: RegExp },\n): LintRule<T> {\n const pattern = opts?.pattern\n ?? new RegExp(`^${prefix}-\\\\d{${opts?.digits ?? 3}}$`);\n\n return {\n id: 'id-format',\n severity: 'warning',\n message: `ID should match format ${pattern}`,\n check: (spec) => {\n const id = (spec as Record<string, unknown>)['id'];\n return typeof id !== 'string' || !pattern.test(id);\n },\n };\n}\n\n/**\n * Require child element IDs to follow parent ID (e.g. `FR-001-01`).\n */\nexport function childIdFormat<T>(\n arrayField: keyof T & string,\n idField: string,\n): LintRule<T> {\n return {\n id: `${arrayField}-id-format`,\n severity: 'warning',\n message: `${arrayField} IDs should follow parent ID pattern`,\n check: (spec) => {\n const parentId = (spec as Record<string, unknown>)['id'] as string;\n const children = (spec as Record<string, unknown>)[arrayField];\n if (!Array.isArray(children) || !parentId) return false;\n return children.some((child: Record<string, unknown>) => {\n const childId = child[idField];\n return typeof childId === 'string' && !childId.startsWith(parentId + '-');\n });\n },\n };\n}\n","/**\n * Core DSL — Exporter factories\n *\n * Factory functions that produce Exporter<T> objects from declarative config.\n */\nimport type { Exporter } from '../model.js';\n\ninterface MetaField<T> {\n key: keyof T & string;\n label?: string;\n}\n\ninterface SectionConfig<T> {\n heading: string;\n field?: keyof T & string;\n render?: (spec: T) => string;\n optional?: boolean;\n}\n\ninterface ColumnConfig<T> {\n key: keyof T & string;\n label?: string;\n render?: (value: unknown, spec: T) => string;\n}\n\nexport interface MarkdownExporterConfig<T> {\n outputDir: string;\n single?: {\n title: keyof T & string | ((spec: T) => string);\n meta?: Array<keyof T & string | MetaField<T>>;\n sections?: SectionConfig<T>[];\n };\n index?: {\n title?: string;\n columns: Array<keyof T & string | ColumnConfig<T>>;\n };\n}\n\n/**\n * Create a markdown exporter from declarative configuration.\n */\nexport function markdownExporter<T extends { id: string }>(\n config: MarkdownExporterConfig<T>,\n): Exporter<T> {\n const exporter: Exporter<T> = {\n format: 'markdown',\n outputDir: config.outputDir,\n filename: (spec) => spec.id,\n };\n\n if (config.single) {\n const singleCfg = config.single;\n exporter.single = (spec) => {\n const lines: string[] = [];\n\n const title = typeof singleCfg.title === 'function'\n ? singleCfg.title(spec)\n : String((spec as Record<string, unknown>)[singleCfg.title] ?? '');\n lines.push(`# ${title}`, '');\n\n if (singleCfg.meta) {\n for (const m of singleCfg.meta) {\n const key = typeof m === 'string' ? m : m.key;\n const label = typeof m === 'string' ? key : (m.label ?? m.key);\n const value = (spec as Record<string, unknown>)[key];\n if (value !== undefined && value !== null) {\n lines.push(`**${label}**: ${String(value)}`);\n }\n }\n lines.push('');\n }\n\n if (singleCfg.sections) {\n for (const section of singleCfg.sections) {\n let content: string | undefined;\n if (section.render) {\n content = section.render(spec);\n } else if (section.field) {\n const value = (spec as Record<string, unknown>)[section.field];\n if (typeof value === 'string') content = value;\n }\n if (section.optional && !content) continue;\n lines.push(`## ${section.heading}`, '');\n if (content) lines.push(content, '');\n }\n }\n\n return lines.join('\\n');\n };\n }\n\n if (config.index) {\n const indexCfg = config.index;\n exporter.index = (specs) => {\n const lines: string[] = [];\n const title = indexCfg.title ?? 'Index';\n lines.push(`# ${title}`, '');\n\n const columns = indexCfg.columns.map(c =>\n typeof c === 'string' ? { key: c, label: c } : { key: c.key, label: c.label ?? c.key, render: c.render },\n );\n\n lines.push('| ' + columns.map(c => c.label).join(' | ') + ' |');\n lines.push('| ' + columns.map(() => '---').join(' | ') + ' |');\n\n for (const spec of specs) {\n const cells = columns.map(col => {\n const value = (spec as Record<string, unknown>)[col.key];\n if ('render' in col && col.render) return col.render(value, spec);\n if (col.key === 'id') return `[${value}](./${value}.md)`;\n return String(value ?? '-');\n });\n lines.push('| ' + cells.join(' | ') + ' |');\n }\n\n return lines.join('\\n');\n };\n }\n\n return exporter;\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 * Core DSL — Checker and coverage factories\n *\n * Target-class-specific external checkers and relation-based coverage checkers.\n * Scaffold auto-binds these based on edge type and target node class.\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 { ExternalChecker, CheckResult, CoverageChecker, CoverageResult } from '../model.js';\nimport { isTypeContainedBy } from './type-compat.js';\n\n// ---------------------------------------------------------------------------\n// Test checker (target class: \"test\")\n// ---------------------------------------------------------------------------\n\nexport interface TestCheckerConfig<T> {\n sourcePath?: (spec: T) => string;\n}\n\n/**\n * Creates an ExternalChecker that verifies test file existence and spec ID references.\n */\nexport function testChecker<T extends { id: string }>(\n config?: TestCheckerConfig<T>,\n): ExternalChecker<T> {\n return {\n targetType: 'test',\n sourcePath: config?.sourcePath ?? (() => '.'),\n check: (spec): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n const basePath = process.cwd();\n\n const testPatterns = [\n 'test/**/*.test.ts',\n 'test/**/*.spec.ts',\n 'tests/**/*.test.ts',\n 'tests/**/*.spec.ts',\n ];\n\n let testFiles: string[] = [];\n for (const pattern of testPatterns) {\n testFiles = testFiles.concat(glob.sync(pattern, { cwd: basePath }));\n }\n\n if (testFiles.length === 0) {\n warnings.push({ message: `No test files found for ${spec.id}`, specId: spec.id });\n return { success: true, errors, warnings };\n }\n\n let specIdFound = false;\n for (const testFile of testFiles) {\n const fullPath = join(basePath, testFile);\n try {\n const content = readFileSync(fullPath, 'utf-8');\n const patterns = [\n new RegExp(`describe\\\\s*\\\\(\\\\s*['\"\\`].*${spec.id}`, 'm'),\n new RegExp(`it\\\\s*\\\\(\\\\s*['\"\\`].*${spec.id}`, 'm'),\n new RegExp(`test\\\\s*\\\\(\\\\s*['\"\\`].*${spec.id}`, 'm'),\n ];\n if (patterns.some(p => p.test(content))) {\n specIdFound = true;\n break;\n }\n } catch {\n // skip unreadable files\n }\n }\n\n if (!specIdFound) {\n warnings.push({\n message: `Spec ID \"${spec.id}\" not found in any test file`,\n specId: spec.id,\n });\n }\n\n return { success: errors.length === 0, errors, warnings };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// OpenAPI checker (target class: \"openapi\")\n// ---------------------------------------------------------------------------\n\nexport interface OpenAPICheckerConfig<T> {\n sourcePath?: (spec: T) => string;\n mapper: (spec: T) => {\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\n/**\n * Resolve a local $ref pointer (e.g., \"#/components/schemas/User\") within a document.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction 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/**\n * Resolve $ref if the value is a reference object, otherwise return as-is.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction 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/**\n * Search for a spec ID in an OpenAPI document.\n * Returns the matched path key and operation (if found).\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\n/**\n * Creates an ExternalChecker that verifies consistency with an OpenAPI spec file.\n *\n * Three validation levels:\n * 1. Existence: spec ID found in operationId, path segment, schema name, or x-spec-id\n * 2. Structural: HTTP method matches the matched path\n * 3. Type: parameter/response property names and types match\n */\nexport function externalOpenAPIChecker<T extends { id: string }>(\n config?: OpenAPICheckerConfig<T>,\n): ExternalChecker<T> {\n return {\n targetType: 'openapi',\n sourcePath: config?.sourcePath ?? (() => 'api/openapi.yaml'),\n check: (spec): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n const filePath = (config?.sourcePath ?? (() => 'api/openapi.yaml'))(spec);\n const fullPath = isAbsolute(filePath) ? filePath : join(process.cwd(), filePath);\n\n if (!existsSync(fullPath)) {\n errors.push({ message: `OpenAPI file not found: ${filePath}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n let content: string;\n try {\n content = readFileSync(fullPath, 'utf-8');\n } catch {\n errors.push({ message: `Failed to read OpenAPI file: ${filePath}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n if (content.length === 0) {\n errors.push({ message: `OpenAPI file is empty: ${filePath}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let doc: any;\n try {\n if (fullPath.endsWith('.json')) {\n doc = JSON.parse(content);\n } else {\n doc = parseYaml(content);\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n errors.push({ message: `Failed to parse OpenAPI file ${filePath}: ${msg}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n const match = findSpecIdInOpenAPI(doc, spec.id);\n if (!match) {\n warnings.push({ message: `Spec ID \"${spec.id}\" not found in OpenAPI document ${filePath}`, specId: spec.id });\n return { success: true, errors, warnings };\n }\n\n if (!config?.mapper) {\n return { success: errors.length === 0, errors, warnings };\n }\n\n const mapping = config.mapper(spec);\n\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 \"${spec.id}\": expected ${expectedMethod.toUpperCase()}, found ${actualMethod.toUpperCase()}`,\n specId: spec.id,\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 \"${spec.id}\"`,\n specId: spec.id,\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: spec.id,\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 \"${spec.id}\"`,\n specId: spec.id,\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: spec.id,\n field: expectedProp.name,\n });\n }\n }\n }\n }\n\n return { success: errors.length === 0, errors, warnings };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// SQL Schema checker (target class: \"sqlschema\")\n// ---------------------------------------------------------------------------\n\nexport interface SqlSchemaCheckerConfig<T> {\n sourcePath?: (spec: T) => string;\n mapper: (spec: T) => {\n tableName: string;\n columns?: Array<{ name: string; type?: string }>;\n };\n checkTypes?: boolean;\n}\n\ninterface TableDefinition {\n name: string;\n columns: Array<{ name: string; type: string }>;\n}\n\n/**\n * Parse DDL using node-sql-parser. Returns table definitions.\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 tableName: 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\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\n/**\n * Regex-based fallback for DDL parsing when node-sql-parser fails.\n * Extracts CREATE TABLE ... (...columns...) patterns.\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\\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\n/**\n * Creates an ExternalChecker that verifies consistency with a SQL schema (DDL).\n *\n * Three validation levels:\n * 1. Existence: table name found in DDL\n * 2. Structural: column names exist in the DDL table\n * 3. Type: column types use containment-based comparison\n */\nexport function externalSqlSchemaChecker<T extends { id: string }>(\n config?: SqlSchemaCheckerConfig<T>,\n): ExternalChecker<T> {\n return {\n targetType: 'ddl',\n sourcePath: config?.sourcePath ?? (() => 'db/schema.sql'),\n check: (spec): CheckResult => {\n const errors: CheckResult['errors'] = [];\n const warnings: CheckResult['warnings'] = [];\n\n const filePath = (config?.sourcePath ?? (() => 'db/schema.sql'))(spec);\n const fullPath = isAbsolute(filePath) ? filePath : join(process.cwd(), filePath);\n\n if (!existsSync(fullPath)) {\n errors.push({ message: `DDL file not found: ${filePath}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n let content: string;\n try {\n content = readFileSync(fullPath, 'utf-8');\n } catch {\n errors.push({ message: `Failed to read DDL file: ${filePath}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n if (content.length === 0) {\n errors.push({ message: `DDL file is empty: ${filePath}`, specId: spec.id });\n return { success: false, errors, warnings };\n }\n\n let tables = parseDDLWithParser(content);\n if (!tables) {\n warnings.push({ message: `DDL parser failed for ${filePath}, using regex fallback`, specId: spec.id });\n tables = parseDDLWithRegex(content);\n }\n\n if (!config?.mapper) {\n return { success: errors.length === 0, errors, warnings };\n }\n\n const mapping = config.mapper(spec);\n\n const table = tables.find(\n (t) => t.name.toLowerCase() === mapping.tableName.toLowerCase(),\n );\n\n if (!table) {\n warnings.push({\n message: `Table \"${mapping.tableName}\" not found in DDL file ${filePath}`,\n specId: spec.id,\n });\n return { success: errors.length === 0, errors, warnings };\n }\n\n if (!mapping.columns) {\n return { success: errors.length === 0, errors, warnings };\n }\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: spec.id,\n field: expectedCol.name,\n });\n continue;\n }\n\n if (config.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: spec.id,\n field: expectedCol.name,\n });\n }\n }\n }\n\n return { success: errors.length === 0, errors, warnings };\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Relation-based coverage checker\n// ---------------------------------------------------------------------------\n\nexport interface RelationCoverageConfig {\n targetModel: string;\n description: string;\n relationType?: string;\n targetPrefix?: string;\n}\n\n/**\n * Creates a CoverageChecker that computes coverage of a target model via relations.\n */\nexport function relationCoverage<T extends { id: string; relations?: Array<{ type: string; target: string }> }>(\n config: RelationCoverageConfig,\n): CoverageChecker<T> {\n return {\n targetModel: config.targetModel,\n description: config.description,\n check: (specs, registry): CoverageResult => {\n const targets = registry[config.targetModel];\n if (!targets) {\n return { total: 0, covered: 0, uncovered: 0, coveragePercent: 100, coveredItems: [], uncoveredItems: [] };\n }\n\n const allTargetIds = new Set<string>();\n const targetDescriptions = new Map<string, string>();\n for (const t of targets.values() as IterableIterator<{ id: string; name?: string; description?: string }>) {\n if (config.targetPrefix && !t.id.startsWith(config.targetPrefix)) continue;\n allTargetIds.add(t.id);\n targetDescriptions.set(t.id, t.name ?? t.description ?? t.id);\n }\n\n const coveredIds = new Set<string>();\n for (const spec of specs) {\n if (!spec.relations) continue;\n for (const rel of spec.relations) {\n if (config.relationType && rel.type !== config.relationType) continue;\n if (allTargetIds.has(rel.target)) coveredIds.add(rel.target);\n }\n }\n\n const coveredItems: CoverageResult['coveredItems'] = [];\n const uncoveredItems: CoverageResult['uncoveredItems'] = [];\n for (const id of allTargetIds) {\n const desc = targetDescriptions.get(id);\n if (coveredIds.has(id)) {\n coveredItems.push({ id, description: desc });\n } else {\n uncoveredItems.push({ id, description: desc });\n }\n }\n\n const total = allTargetIds.size;\n const covered = coveredItems.length;\n const coveragePercent = total > 0 ? Math.round((covered / total) * 100) : 100;\n\n return { total, covered, uncovered: total - covered, coveragePercent, coveredItems, uncoveredItems };\n },\n };\n}\n","/**\n * Core DSL — Edge-typed relation schemas\n *\n * Specialized relation schemas for `implements` and `verifiedBy` edges.\n * These carry additional properties beyond the generic RelationSchema.\n */\nimport { z } from 'zod';\n\nexport const ImplementsRelationSchema = z.object({\n target: z.string(),\n targetType: z.string(),\n sourcePath: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport type ImplementsRelation = z.infer<typeof ImplementsRelationSchema>;\n\nexport const VerifiedByRelationSchema = z.object({\n target: z.string(),\n testPath: z.string().optional(),\n framework: z.string().optional(),\n description: z.string().optional(),\n});\n\nexport type VerifiedByRelation = z.infer<typeof VerifiedByRelationSchema>;\n"]}