qfai 0.7.2 → 0.8.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/LICENSE +21 -0
- package/README.md +1 -1
- package/assets/init/.qfai/README.md +4 -1
- package/assets/init/.qfai/promptpack/steering/compatibility-vs-change.md +34 -0
- package/assets/init/.qfai/prompts.local/README.md +5 -0
- package/dist/cli/index.cjs +122 -51
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +122 -51
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +109 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +109 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -2
package/dist/cli/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/doctor.ts","../../src/core/doctor.ts","../../src/core/config.ts","../../src/core/discovery.ts","../../src/core/fs.ts","../../src/core/specLayout.ts","../../src/core/paths.ts","../../src/core/traceability.ts","../../src/core/gherkin/parse.ts","../../src/core/scenarioModel.ts","../../src/core/version.ts","../../src/cli/lib/logger.ts","../../src/cli/commands/init.ts","../../src/cli/lib/fs.ts","../../src/cli/lib/assets.ts","../../src/cli/commands/report.ts","../../src/core/normalize.ts","../../src/core/report.ts","../../src/core/contractIndex.ts","../../src/core/contractsDecl.ts","../../src/core/ids.ts","../../src/core/parse/contractRefs.ts","../../src/core/parse/markdown.ts","../../src/core/parse/spec.ts","../../src/core/validators/contracts.ts","../../src/core/contracts.ts","../../src/core/validators/delta.ts","../../src/core/validators/ids.ts","../../src/core/validators/scenario.ts","../../src/core/validators/spec.ts","../../src/core/validators/traceability.ts","../../src/core/validate.ts","../../src/cli/commands/validate.ts","../../src/cli/lib/failOn.ts","../../src/cli/lib/args.ts","../../src/cli/main.ts","../../src/cli/index.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { createDoctorData } from \"../../core/doctor.js\";\nimport { info } from \"../lib/logger.js\";\n\nexport type DoctorCommandOptions = {\n root: string;\n rootExplicit: boolean;\n format: \"text\" | \"json\";\n outPath?: string;\n failOn?: \"warning\" | \"error\";\n};\n\nfunction formatDoctorText(\n data: Awaited<ReturnType<typeof createDoctorData>>,\n): string {\n const lines: string[] = [];\n lines.push(\n `qfai doctor: root=${data.root} config=${data.config.configPath} (${data.config.found ? \"found\" : \"missing\"})`,\n );\n for (const check of data.checks) {\n lines.push(`[${check.severity}] ${check.id}: ${check.message}`);\n }\n lines.push(\n `summary: ok=${data.summary.ok} info=${data.summary.info} warning=${data.summary.warning} error=${data.summary.error}`,\n );\n return lines.join(\"\\n\");\n}\n\nfunction formatDoctorJson(data: unknown): string {\n return JSON.stringify(data, null, 2);\n}\n\nexport async function runDoctor(\n options: DoctorCommandOptions,\n): Promise<number> {\n const data = await createDoctorData({\n startDir: options.root,\n rootExplicit: options.rootExplicit,\n });\n\n const output =\n options.format === \"json\" ? formatDoctorJson(data) : formatDoctorText(data);\n const exitCode = shouldFailDoctor(data.summary, options.failOn) ? 1 : 0;\n\n if (options.outPath) {\n const outAbs = path.isAbsolute(options.outPath)\n ? options.outPath\n : path.resolve(process.cwd(), options.outPath);\n await mkdir(path.dirname(outAbs), { recursive: true });\n await writeFile(outAbs, `${output}\\n`, \"utf-8\");\n info(`doctor: wrote ${outAbs}`);\n return exitCode;\n }\n\n info(output);\n return exitCode;\n}\n\nfunction shouldFailDoctor(\n summary: { warning: number; error: number },\n failOn?: \"warning\" | \"error\",\n): boolean {\n if (!failOn) {\n return false;\n }\n if (failOn === \"error\") {\n return summary.error > 0;\n }\n return summary.warning + summary.error > 0;\n}\n","import { access } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n findConfigRoot,\n getConfigPath,\n loadConfig,\n resolvePath,\n} from \"./config.js\";\nimport { collectScenarioFiles } from \"./discovery.js\";\nimport { collectFilesByGlobs } from \"./fs.js\";\nimport { toRelativePath } from \"./paths.js\";\nimport { collectSpecEntries } from \"./specLayout.js\";\nimport { DEFAULT_TEST_FILE_EXCLUDE_GLOBS } from \"./traceability.js\";\nimport { resolveToolVersion } from \"./version.js\";\n\nexport type DoctorSeverity = \"ok\" | \"info\" | \"warning\" | \"error\";\n\nexport type DoctorCheck = {\n id: string;\n severity: DoctorSeverity;\n title: string;\n message: string;\n details?: Record<string, unknown>;\n};\n\nexport type DoctorData = {\n tool: \"qfai\";\n version: string;\n generatedAt: string;\n root: string;\n config: {\n startDir: string;\n found: boolean;\n configPath: string;\n };\n summary: { ok: number; info: number; warning: number; error: number };\n checks: DoctorCheck[];\n};\n\ntype CreateDoctorDataOptions = {\n startDir: string;\n rootExplicit: boolean;\n};\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction addCheck(checks: DoctorCheck[], check: DoctorCheck): void {\n checks.push(check);\n}\n\nfunction summarize(checks: DoctorCheck[]): DoctorData[\"summary\"] {\n const summary = { ok: 0, info: 0, warning: 0, error: 0 };\n for (const check of checks) {\n summary[check.severity] += 1;\n }\n return summary;\n}\n\nfunction normalizeGlobs(values: string[]): string[] {\n return values.map((glob) => glob.trim()).filter((glob) => glob.length > 0);\n}\n\nexport async function createDoctorData(\n options: CreateDoctorDataOptions,\n): Promise<DoctorData> {\n const startDir = path.resolve(options.startDir);\n const checks: DoctorCheck[] = [];\n\n const configPath = getConfigPath(startDir);\n const search = options.rootExplicit\n ? {\n root: startDir,\n configPath,\n found: await exists(configPath),\n }\n : await findConfigRoot(startDir);\n\n const root = search.root;\n const version = await resolveToolVersion();\n const generatedAt = new Date().toISOString();\n\n addCheck(checks, {\n id: \"config.search\",\n severity: search.found ? \"ok\" : \"warning\",\n title: \"Config search\",\n message: search.found\n ? \"qfai.config.yaml found\"\n : \"qfai.config.yaml not found (default config will be used)\",\n details: { configPath: toRelativePath(root, search.configPath) },\n });\n\n const {\n config,\n issues,\n configPath: resolvedConfigPath,\n } = await loadConfig(root);\n if (issues.length === 0) {\n addCheck(checks, {\n id: \"config.load\",\n severity: \"ok\",\n title: \"Config load\",\n message: \"Loaded and normalized with 0 issues\",\n details: { configPath: toRelativePath(root, resolvedConfigPath) },\n });\n } else {\n addCheck(checks, {\n id: \"config.load\",\n severity: \"warning\",\n title: \"Config load\",\n message: `Loaded with ${issues.length} issue(s) (normalized with defaults when needed)`,\n details: {\n configPath: toRelativePath(root, resolvedConfigPath),\n issues,\n },\n });\n }\n\n const pathKeys = [\n \"specsDir\",\n \"contractsDir\",\n \"outDir\",\n \"srcDir\",\n \"testsDir\",\n \"rulesDir\",\n \"promptsDir\",\n ] as const;\n\n for (const key of pathKeys) {\n const resolved = resolvePath(root, config, key);\n const ok = await exists(resolved);\n addCheck(checks, {\n id: `paths.${key}`,\n severity: ok ? \"ok\" : \"warning\",\n title: `Path exists: ${key}`,\n message: ok\n ? `${key} exists`\n : `${key} is missing (did you run 'qfai init'?)`,\n details: { path: toRelativePath(root, resolved) },\n });\n\n if (key === \"promptsDir\") {\n const promptsLocalDir = path.join(\n path.dirname(resolved),\n `${path.basename(resolved)}.local`,\n );\n const found = await exists(promptsLocalDir);\n addCheck(checks, {\n id: \"paths.promptsLocalDir\",\n severity: \"info\",\n title: \"Prompts overlay (prompts.local)\",\n message: found\n ? \"prompts.local exists (overlay can be used)\"\n : \"prompts.local is optional (create it to override prompts)\",\n details: { path: toRelativePath(root, promptsLocalDir) },\n });\n }\n }\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n let missingFiles = 0;\n\n for (const entry of entries) {\n const requiredFiles = [entry.specPath, entry.deltaPath, entry.scenarioPath];\n for (const filePath of requiredFiles) {\n if (!(await exists(filePath))) {\n missingFiles += 1;\n }\n }\n }\n\n addCheck(checks, {\n id: \"spec.layout\",\n severity: missingFiles === 0 ? \"ok\" : \"warning\",\n title: \"Spec pack shape\",\n message:\n missingFiles === 0\n ? `All spec packs have required files (count=${entries.length})`\n : `Missing required files in spec packs (missingFiles=${missingFiles})`,\n details: { specPacks: entries.length, missingFiles },\n });\n\n const validateJsonAbs = path.isAbsolute(config.output.validateJsonPath)\n ? config.output.validateJsonPath\n : path.resolve(root, config.output.validateJsonPath);\n const validateJsonExists = await exists(validateJsonAbs);\n addCheck(checks, {\n id: \"output.validateJson\",\n severity: validateJsonExists ? \"ok\" : \"warning\",\n title: \"validate.json\",\n message: validateJsonExists\n ? \"validate.json exists (report can run)\"\n : \"validate.json is missing (run 'qfai validate' before 'qfai report')\",\n details: { path: toRelativePath(root, validateJsonAbs) },\n });\n\n const outDirAbs = resolvePath(root, config, \"outDir\");\n const rel = path.relative(outDirAbs, validateJsonAbs);\n const inside = rel !== \"\" && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n addCheck(checks, {\n id: \"output.pathAlignment\",\n severity: inside ? \"ok\" : \"warning\",\n title: \"Output path alignment\",\n message: inside\n ? \"validateJsonPath is under outDir\"\n : \"validateJsonPath is not under outDir (may be intended, but check configuration)\",\n details: {\n outDir: toRelativePath(root, outDirAbs),\n validateJsonPath: toRelativePath(root, validateJsonAbs),\n },\n });\n\n if (options.rootExplicit) {\n addCheck(checks, await buildOutDirCollisionCheck(root));\n }\n\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const globs = normalizeGlobs(config.validation.traceability.testFileGlobs);\n const exclude = normalizeGlobs([\n ...DEFAULT_TEST_FILE_EXCLUDE_GLOBS,\n ...config.validation.traceability.testFileExcludeGlobs,\n ]);\n\n try {\n const matched =\n globs.length === 0\n ? []\n : await collectFilesByGlobs(root, { globs, ignore: exclude });\n const matchedCount = matched.length;\n\n const severity: DoctorSeverity =\n globs.length === 0\n ? \"warning\"\n : scenarioFiles.length > 0 &&\n config.validation.traceability.scMustHaveTest &&\n matchedCount === 0\n ? \"warning\"\n : \"ok\";\n\n addCheck(checks, {\n id: \"traceability.testGlobs\",\n severity,\n title: \"Test file globs\",\n message:\n globs.length === 0\n ? \"testFileGlobs is empty (SC→Test cannot be verified)\"\n : `matchedFileCount=${matchedCount}`,\n details: {\n globs,\n excludeGlobs: exclude,\n scenarioFiles: scenarioFiles.length,\n scMustHaveTest: config.validation.traceability.scMustHaveTest,\n },\n });\n } catch (error) {\n addCheck(checks, {\n id: \"traceability.testGlobs\",\n severity: \"error\",\n title: \"Test file globs\",\n message: \"Glob scan failed (invalid pattern or filesystem error)\",\n details: { globs, excludeGlobs: exclude, error: String(error) },\n });\n }\n\n return {\n tool: \"qfai\",\n version,\n generatedAt,\n root: toRelativePath(process.cwd(), root),\n config: {\n startDir: toRelativePath(process.cwd(), startDir),\n found: search.found,\n configPath: toRelativePath(root, search.configPath) || \"qfai.config.yaml\",\n },\n summary: summarize(checks),\n checks,\n };\n}\n\nconst DEFAULT_CONFIG_SEARCH_IGNORE_GLOBS = [\n ...DEFAULT_TEST_FILE_EXCLUDE_GLOBS,\n \"**/.pnpm/**\",\n \"**/tmp/**\",\n \"**/.mcp-tools/**\",\n];\n\ntype OutDirCollision = {\n outDir: string;\n roots: string[];\n};\n\ntype OutDirCollisionResult = {\n monorepoRoot: string;\n configRoots: string[];\n collisions: OutDirCollision[];\n};\n\nasync function buildOutDirCollisionCheck(root: string): Promise<DoctorCheck> {\n try {\n const result = await detectOutDirCollisions(root);\n const relativeRoot = toRelativePath(process.cwd(), result.monorepoRoot);\n const configRoots = result.configRoots\n .map((configRoot) => toRelativePath(result.monorepoRoot, configRoot))\n .sort((a, b) => a.localeCompare(b));\n const collisions = result.collisions\n .map((item) => ({\n outDir: toRelativePath(result.monorepoRoot, item.outDir),\n roots: item.roots\n .map((collisionRoot) =>\n toRelativePath(result.monorepoRoot, collisionRoot),\n )\n .sort((a, b) => a.localeCompare(b)),\n }))\n .sort((a, b) => a.outDir.localeCompare(b.outDir));\n const severity: DoctorSeverity = collisions.length > 0 ? \"warning\" : \"ok\";\n const message =\n collisions.length > 0\n ? `outDir collision detected (count=${collisions.length})`\n : `outDir collision not detected (configs=${configRoots.length})`;\n\n return {\n id: \"output.outDirCollision\",\n severity,\n title: \"OutDir collision\",\n message,\n details: {\n monorepoRoot: relativeRoot,\n configRoots,\n collisions,\n },\n };\n } catch (error) {\n return {\n id: \"output.outDirCollision\",\n severity: \"error\",\n title: \"OutDir collision\",\n message: \"OutDir collision scan failed\",\n details: { error: String(error) },\n };\n }\n}\n\nasync function detectOutDirCollisions(\n root: string,\n): Promise<OutDirCollisionResult> {\n const monorepoRoot = await findMonorepoRoot(root);\n const configPaths = await collectFilesByGlobs(monorepoRoot, {\n globs: [\"**/qfai.config.yaml\"],\n ignore: DEFAULT_CONFIG_SEARCH_IGNORE_GLOBS,\n });\n const configRoots = Array.from(\n new Set(configPaths.map((configPath) => path.dirname(configPath))),\n ).sort((a, b) => a.localeCompare(b));\n const outDirToRoots = new Map<string, Set<string>>();\n\n for (const configRoot of configRoots) {\n const { config } = await loadConfig(configRoot);\n const outDir = path.normalize(resolvePath(configRoot, config, \"outDir\"));\n const roots = outDirToRoots.get(outDir) ?? new Set<string>();\n roots.add(configRoot);\n outDirToRoots.set(outDir, roots);\n }\n\n const collisions: OutDirCollision[] = [];\n for (const [outDir, roots] of outDirToRoots.entries()) {\n if (roots.size > 1) {\n collisions.push({\n outDir,\n roots: Array.from(roots).sort((a, b) => a.localeCompare(b)),\n });\n }\n }\n\n return { monorepoRoot, configRoots, collisions };\n}\n\nasync function findMonorepoRoot(startDir: string): Promise<string> {\n let current = path.resolve(startDir);\n while (true) {\n const gitPath = path.join(current, \".git\");\n const workspacePath = path.join(current, \"pnpm-workspace.yaml\");\n if ((await exists(gitPath)) || (await exists(workspacePath))) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return path.resolve(startDir);\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { Issue } from \"./types.js\";\n\nexport type FailOn = \"never\" | \"warning\" | \"error\";\nexport type OutputFormat = \"text\" | \"github\";\nexport type TraceabilitySeverity = \"warning\" | \"error\";\nexport type OrphanContractsPolicy = \"error\" | \"warning\" | \"allow\";\n\nexport type QfaiPaths = {\n contractsDir: string;\n specsDir: string;\n rulesDir: string;\n outDir: string;\n promptsDir: string;\n srcDir: string;\n testsDir: string;\n};\n\nexport type QfaiValidationConfig = {\n failOn: FailOn;\n require: {\n specSections: string[];\n };\n traceability: {\n brMustHaveSc: boolean;\n scMustHaveTest: boolean;\n testFileGlobs: string[];\n testFileExcludeGlobs: string[];\n scNoTestSeverity: TraceabilitySeverity;\n orphanContractsPolicy: OrphanContractsPolicy;\n unknownContractIdSeverity: TraceabilitySeverity;\n };\n};\n\nexport type QfaiOutputConfig = {\n validateJsonPath: string;\n};\n\nexport type QfaiConfig = {\n paths: QfaiPaths;\n validation: QfaiValidationConfig;\n output: QfaiOutputConfig;\n};\n\nexport type ConfigPathKey = keyof QfaiPaths;\n\nexport type ConfigLoadResult = {\n config: QfaiConfig;\n issues: Issue[];\n configPath: string;\n};\n\nexport type ConfigSearchResult = {\n root: string;\n configPath: string;\n found: boolean;\n};\n\nexport const defaultConfig: QfaiConfig = {\n paths: {\n contractsDir: \".qfai/contracts\",\n specsDir: \".qfai/specs\",\n rulesDir: \".qfai/rules\",\n outDir: \".qfai/out\",\n promptsDir: \".qfai/prompts\",\n srcDir: \"src\",\n testsDir: \"tests\",\n },\n validation: {\n failOn: \"error\",\n require: {\n specSections: [\n \"背景\",\n \"スコープ\",\n \"非ゴール\",\n \"用語\",\n \"前提\",\n \"決定事項\",\n \"業務ルール\",\n ],\n },\n traceability: {\n brMustHaveSc: true,\n scMustHaveTest: true,\n testFileGlobs: [],\n testFileExcludeGlobs: [],\n scNoTestSeverity: \"error\",\n orphanContractsPolicy: \"error\",\n unknownContractIdSeverity: \"error\",\n },\n },\n output: {\n validateJsonPath: \".qfai/out/validate.json\",\n },\n};\n\nexport function getConfigPath(root: string): string {\n return path.join(root, \"qfai.config.yaml\");\n}\n\nexport async function findConfigRoot(\n startDir: string,\n): Promise<ConfigSearchResult> {\n const resolvedStart = path.resolve(startDir);\n let current = resolvedStart;\n\n while (true) {\n const configPath = getConfigPath(current);\n if (await exists(configPath)) {\n return { root: current, configPath, found: true };\n }\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n return {\n root: resolvedStart,\n configPath: getConfigPath(resolvedStart),\n found: false,\n };\n}\n\nexport async function loadConfig(root: string): Promise<ConfigLoadResult> {\n const configPath = getConfigPath(root);\n const issues: Issue[] = [];\n\n let parsed: unknown;\n try {\n const raw = await readFile(configPath, \"utf-8\");\n parsed = parseYaml(raw);\n } catch (error) {\n if (isMissingFile(error)) {\n return { config: defaultConfig, issues, configPath };\n }\n issues.push(configIssue(configPath, formatError(error)));\n return { config: defaultConfig, issues, configPath };\n }\n\n const normalized = normalizeConfig(parsed, configPath, issues);\n return { config: normalized, issues, configPath };\n}\n\nexport function resolvePath(\n root: string,\n config: QfaiConfig,\n key: ConfigPathKey,\n): string {\n return path.resolve(root, config.paths[key]);\n}\n\nfunction normalizeConfig(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiConfig {\n if (!isRecord(raw)) {\n issues.push(configIssue(configPath, \"設定ファイルの形式が不正です。\"));\n return defaultConfig;\n }\n\n return {\n paths: normalizePaths(raw.paths, configPath, issues),\n validation: normalizeValidation(raw.validation, configPath, issues),\n output: normalizeOutput(raw.output, configPath, issues),\n };\n}\n\nfunction normalizePaths(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiPaths {\n const base = defaultConfig.paths;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"paths はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n contractsDir: readString(\n raw.contractsDir,\n base.contractsDir,\n \"paths.contractsDir\",\n configPath,\n issues,\n ),\n specsDir: readString(\n raw.specsDir,\n base.specsDir,\n \"paths.specsDir\",\n configPath,\n issues,\n ),\n rulesDir: readString(\n raw.rulesDir,\n base.rulesDir,\n \"paths.rulesDir\",\n configPath,\n issues,\n ),\n outDir: readString(\n raw.outDir,\n base.outDir,\n \"paths.outDir\",\n configPath,\n issues,\n ),\n promptsDir: readString(\n raw.promptsDir,\n base.promptsDir,\n \"paths.promptsDir\",\n configPath,\n issues,\n ),\n srcDir: readString(\n raw.srcDir,\n base.srcDir,\n \"paths.srcDir\",\n configPath,\n issues,\n ),\n testsDir: readString(\n raw.testsDir,\n base.testsDir,\n \"paths.testsDir\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction normalizeValidation(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiValidationConfig {\n const base = defaultConfig.validation;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(\n configPath,\n \"validation はオブジェクトである必要があります。\",\n ),\n );\n return base;\n }\n\n let requireRaw: Record<string, unknown> | undefined;\n if (raw.require === undefined) {\n requireRaw = undefined;\n } else if (isRecord(raw.require)) {\n requireRaw = raw.require;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.require はオブジェクトである必要があります。\",\n ),\n );\n requireRaw = undefined;\n }\n\n let traceabilityRaw: Record<string, unknown> | undefined;\n if (raw.traceability === undefined) {\n traceabilityRaw = undefined;\n } else if (isRecord(raw.traceability)) {\n traceabilityRaw = raw.traceability;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.traceability はオブジェクトである必要があります。\",\n ),\n );\n traceabilityRaw = undefined;\n }\n\n return {\n failOn: readFailOn(\n raw.failOn,\n base.failOn,\n \"validation.failOn\",\n configPath,\n issues,\n ),\n require: {\n specSections: readStringArray(\n requireRaw?.specSections,\n base.require.specSections,\n \"validation.require.specSections\",\n configPath,\n issues,\n ),\n },\n traceability: {\n brMustHaveSc: readBoolean(\n traceabilityRaw?.brMustHaveSc,\n base.traceability.brMustHaveSc,\n \"validation.traceability.brMustHaveSc\",\n configPath,\n issues,\n ),\n scMustHaveTest: readBoolean(\n traceabilityRaw?.scMustHaveTest,\n base.traceability.scMustHaveTest,\n \"validation.traceability.scMustHaveTest\",\n configPath,\n issues,\n ),\n testFileGlobs: readStringArray(\n traceabilityRaw?.testFileGlobs,\n base.traceability.testFileGlobs,\n \"validation.traceability.testFileGlobs\",\n configPath,\n issues,\n ),\n testFileExcludeGlobs: readStringArray(\n traceabilityRaw?.testFileExcludeGlobs,\n base.traceability.testFileExcludeGlobs,\n \"validation.traceability.testFileExcludeGlobs\",\n configPath,\n issues,\n ),\n scNoTestSeverity: readTraceabilitySeverity(\n traceabilityRaw?.scNoTestSeverity,\n base.traceability.scNoTestSeverity,\n \"validation.traceability.scNoTestSeverity\",\n configPath,\n issues,\n ),\n orphanContractsPolicy: readOrphanContractsPolicy(\n traceabilityRaw?.orphanContractsPolicy,\n base.traceability.orphanContractsPolicy,\n \"validation.traceability.orphanContractsPolicy\",\n configPath,\n issues,\n ),\n unknownContractIdSeverity: readTraceabilitySeverity(\n traceabilityRaw?.unknownContractIdSeverity,\n base.traceability.unknownContractIdSeverity,\n \"validation.traceability.unknownContractIdSeverity\",\n configPath,\n issues,\n ),\n },\n };\n}\n\nfunction normalizeOutput(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiOutputConfig {\n const base = defaultConfig.output;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"output はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n validateJsonPath: readString(\n raw.validateJsonPath,\n base.validateJsonPath,\n \"output.validateJsonPath\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction readString(\n value: unknown,\n fallback: string,\n label: string,\n configPath: string,\n issues: Issue[],\n): string {\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readStringArray(\n value: unknown,\n fallback: string[],\n label: string,\n configPath: string,\n issues: Issue[],\n): string[] {\n if (Array.isArray(value) && value.every((item) => typeof item === \"string\")) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列配列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readBoolean(\n value: unknown,\n fallback: boolean,\n label: string,\n configPath: string,\n issues: Issue[],\n): boolean {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は真偽値である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readFailOn(\n value: unknown,\n fallback: FailOn,\n label: string,\n configPath: string,\n issues: Issue[],\n): FailOn {\n if (value === \"never\" || value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は never|warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction readTraceabilitySeverity(\n value: unknown,\n fallback: TraceabilitySeverity,\n label: string,\n configPath: string,\n issues: Issue[],\n): TraceabilitySeverity {\n if (value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction readOrphanContractsPolicy(\n value: unknown,\n fallback: OrphanContractsPolicy,\n label: string,\n configPath: string,\n issues: Issue[],\n): OrphanContractsPolicy {\n if (value === \"error\" || value === \"warning\" || value === \"allow\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は error|warning|allow のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction configIssue(file: string, message: string): Issue {\n return {\n code: \"QFAI_CONFIG_INVALID\",\n severity: \"error\",\n message,\n file,\n rule: \"config.invalid\",\n };\n}\n\nfunction isMissingFile(error: unknown): boolean {\n if (error && typeof error === \"object\" && \"code\" in error) {\n return (error as { code?: string }).code === \"ENOENT\";\n }\n return false;\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { access } from \"node:fs/promises\";\n\nimport { collectFiles } from \"./fs.js\";\nimport { collectSpecEntries } from \"./specLayout.js\";\n\nexport type ContractFiles = {\n api: string[];\n ui: string[];\n db: string[];\n};\n\nexport async function collectSpecPackDirs(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return entries.map((entry) => entry.dir);\n}\n\nexport async function collectSpecFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.specPath));\n}\n\nexport async function collectDeltaFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.deltaPath));\n}\n\nexport async function collectScenarioFiles(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.scenarioPath));\n}\n\nexport async function collectUiContractFiles(\n uiRoot: string,\n): Promise<string[]> {\n return collectFiles(uiRoot, { extensions: [\".yaml\", \".yml\"] });\n}\n\nexport async function collectApiContractFiles(\n apiRoot: string,\n): Promise<string[]> {\n return collectFiles(apiRoot, { extensions: [\".yaml\", \".yml\", \".json\"] });\n}\n\nexport async function collectDbContractFiles(\n dbRoot: string,\n): Promise<string[]> {\n return collectFiles(dbRoot, { extensions: [\".sql\"] });\n}\n\nexport async function collectContractFiles(\n uiRoot: string,\n apiRoot: string,\n dbRoot: string,\n): Promise<ContractFiles> {\n const [ui, api, db] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDbContractFiles(dbRoot),\n ]);\n return { ui, api, db };\n}\n\nasync function filterExisting(files: string[]): Promise<string[]> {\n const existing: string[] = [];\n for (const file of files) {\n if (await exists(file)) {\n existing.push(file);\n }\n }\n return existing;\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { access, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport fg from \"fast-glob\";\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \".pnpm\",\n \"tmp\",\n \".mcp-tools\",\n]);\n\nexport type CollectFilesOptions = {\n extensions?: string[];\n ignoreDirs?: string[];\n};\n\nexport type CollectFilesByGlobOptions = {\n globs: string[];\n ignore?: string[];\n};\n\nexport async function collectFiles(\n root: string,\n options: CollectFilesOptions = {},\n): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const ignoreDirs = new Set([\n ...DEFAULT_IGNORE_DIRS,\n ...(options.ignoreDirs ?? []),\n ]);\n const extensions = options.extensions?.map((ext) => ext.toLowerCase()) ?? [];\n\n await walk(root, root, ignoreDirs, extensions, entries);\n return entries;\n}\n\nexport async function collectFilesByGlobs(\n root: string,\n options: CollectFilesByGlobOptions,\n): Promise<string[]> {\n if (options.globs.length === 0) {\n return [];\n }\n return fg(options.globs, {\n cwd: root,\n ignore: options.ignore ?? [],\n onlyFiles: true,\n absolute: true,\n unique: true,\n });\n}\n\nasync function walk(\n base: string,\n current: string,\n ignoreDirs: Set<string>,\n extensions: string[],\n out: string[],\n): Promise<void> {\n const items = await readdir(current, { withFileTypes: true });\n\n for (const item of items) {\n const fullPath = path.join(current, item.name);\n\n if (item.isDirectory()) {\n if (ignoreDirs.has(item.name)) {\n continue;\n }\n await walk(base, fullPath, ignoreDirs, extensions, out);\n continue;\n }\n\n if (item.isFile()) {\n if (extensions.length > 0) {\n const ext = path.extname(item.name).toLowerCase();\n if (!extensions.includes(ext)) {\n continue;\n }\n }\n out.push(fullPath);\n }\n }\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst SPEC_DIR_RE = /^spec-\\d{4}$/;\n\nexport type SpecEntry = {\n dir: string;\n specPath: string;\n deltaPath: string;\n scenarioPath: string;\n};\n\nexport async function collectSpecEntries(\n specsRoot: string,\n): Promise<SpecEntry[]> {\n const dirs = await listSpecDirs(specsRoot);\n const entries = dirs.map((dir) => ({\n dir,\n specPath: path.join(dir, \"spec.md\"),\n deltaPath: path.join(dir, \"delta.md\"),\n scenarioPath: path.join(dir, \"scenario.md\"),\n }));\n return entries.sort((a, b) => a.dir.localeCompare(b.dir));\n}\n\nasync function listSpecDirs(specsRoot: string): Promise<string[]> {\n try {\n const items = await readdir(specsRoot, { withFileTypes: true });\n return items\n .filter((item) => item.isDirectory())\n .map((item) => item.name)\n .filter((name) => SPEC_DIR_RE.test(name.toLowerCase()))\n .map((name) => path.join(specsRoot, name));\n } catch (error) {\n if (isMissingFileError(error)) {\n return [];\n }\n throw error;\n }\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import path from \"node:path\";\n\nexport function toRelativePath(root: string, target: string): string {\n if (!target) {\n return target;\n }\n if (!path.isAbsolute(target)) {\n return toPosixPath(target);\n }\n const relative = path.relative(root, target);\n if (!relative) {\n return \".\";\n }\n return toPosixPath(relative);\n}\n\nfunction toPosixPath(value: string): string {\n return value.replace(/\\\\/g, \"/\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { collectFilesByGlobs } from \"./fs.js\";\nimport { parseScenarioDocument } from \"./scenarioModel.js\";\n\nexport const SC_TAG_RE = /^SC-\\d{4}$/;\nexport const SC_TEST_ANNOTATION_RE = /\\bQFAI:SC-(\\d{4})\\b/g;\nexport const DEFAULT_TEST_FILE_EXCLUDE_GLOBS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/.qfai/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/.next/**\",\n \"**/out/**\",\n];\n\nexport type ScCoverage = {\n total: number;\n covered: number;\n missing: number;\n missingIds: string[];\n refs: Record<string, string[]>;\n};\n\nexport type TestFileScan = {\n globs: string[];\n excludeGlobs: string[];\n matchedFileCount: number;\n};\n\nexport type ScTestReferenceResult = {\n refs: Map<string, Set<string>>;\n scan: TestFileScan;\n error?: string;\n};\n\nexport function extractAnnotatedScIds(text: string): string[] {\n const ids = new Set<string>();\n for (const match of text.matchAll(SC_TEST_ANNOTATION_RE)) {\n const suffix = match[1];\n if (suffix) {\n ids.add(`SC-${suffix}`);\n }\n }\n return Array.from(ids);\n}\n\nexport async function collectScIdsFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Set<string>> {\n const scIds = new Set<string>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n scIds.add(tag);\n }\n }\n }\n }\n return scIds;\n}\n\nexport async function collectScIdSourcesFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Map<string, Set<string>>> {\n const sources = new Map<string, Set<string>>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (!SC_TAG_RE.test(tag)) {\n continue;\n }\n const current = sources.get(tag) ?? new Set<string>();\n current.add(file);\n sources.set(tag, current);\n }\n }\n }\n return sources;\n}\n\nexport async function collectScTestReferences(\n root: string,\n globs: string[],\n excludeGlobs: string[],\n): Promise<ScTestReferenceResult> {\n const refs = new Map<string, Set<string>>();\n const normalizedGlobs = normalizeGlobs(globs);\n const normalizedExcludeGlobs = normalizeGlobs(excludeGlobs);\n const mergedExcludeGlobs = Array.from(\n new Set([...DEFAULT_TEST_FILE_EXCLUDE_GLOBS, ...normalizedExcludeGlobs]),\n );\n if (normalizedGlobs.length === 0) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n };\n }\n\n let files: string[] = [];\n try {\n files = await collectFilesByGlobs(root, {\n globs: normalizedGlobs,\n ignore: mergedExcludeGlobs,\n });\n } catch (error) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n error: formatError(error),\n };\n }\n\n const normalizedFiles = Array.from(\n new Set(files.map((file) => path.normalize(file))),\n );\n for (const file of normalizedFiles) {\n const text = await readFile(file, \"utf-8\");\n const scIds = extractAnnotatedScIds(text);\n if (scIds.length === 0) {\n continue;\n }\n for (const scId of scIds) {\n const current = refs.get(scId) ?? new Set<string>();\n current.add(file);\n refs.set(scId, current);\n }\n }\n\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: normalizedFiles.length,\n },\n };\n}\n\nexport function buildScCoverage(\n scIds: Iterable<string>,\n refs: Map<string, Set<string>>,\n): ScCoverage {\n const sortedScIds = toSortedArray(scIds);\n const refsRecord: Record<string, string[]> = {};\n const missingIds: string[] = [];\n let covered = 0;\n\n for (const scId of sortedScIds) {\n const files = refs.get(scId);\n const sortedFiles = files ? toSortedArray(files) : [];\n refsRecord[scId] = sortedFiles;\n if (sortedFiles.length === 0) {\n missingIds.push(scId);\n } else {\n covered += 1;\n }\n }\n\n return {\n total: sortedScIds.length,\n covered,\n missing: missingIds.length,\n missingIds,\n refs: refsRecord,\n };\n}\n\nfunction toSortedArray(values: Iterable<string>): string[] {\n return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));\n}\n\nfunction normalizeGlobs(globs: string[]): string[] {\n return globs.map((glob) => glob.trim()).filter((glob) => glob.length > 0);\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import {\n AstBuilder,\n GherkinClassicTokenMatcher,\n Parser,\n} from \"@cucumber/gherkin\";\nimport type { GherkinDocument } from \"@cucumber/messages\";\nimport { randomUUID } from \"node:crypto\";\n\nexport type ParsedGherkin = {\n gherkinDocument: GherkinDocument | null;\n errors: string[];\n};\n\nexport function parseGherkin(source: string, uri: string): ParsedGherkin {\n const errors: string[] = [];\n const uuidFn = () => randomUUID();\n const builder = new AstBuilder(uuidFn);\n const matcher = new GherkinClassicTokenMatcher();\n const parser = new Parser(builder, matcher);\n\n try {\n const gherkinDocument = parser.parse(source);\n gherkinDocument.uri = uri;\n return { gherkinDocument, errors };\n } catch (error) {\n errors.push(formatError(error));\n return { gherkinDocument: null, errors };\n }\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import type * as Messages from \"@cucumber/messages\";\n\nimport { parseGherkin } from \"./gherkin/parse.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\nexport type ScenarioKind = \"Scenario\" | \"ScenarioOutline\";\n\nexport type ScenarioNode = {\n name: string;\n kind: ScenarioKind;\n line?: number;\n tags: string[];\n steps: readonly Messages.Step[];\n};\n\nexport type ScenarioDocument = {\n uri: string;\n featureName?: string;\n featureTags: string[];\n scenarios: ScenarioNode[];\n};\n\nexport type ScenarioParseResult = {\n document: ScenarioDocument | null;\n errors: string[];\n};\n\nexport type ScenarioAtom = {\n uri: string;\n featureName: string;\n scenarioName: string;\n kind: ScenarioKind;\n specId?: string;\n scId?: string;\n brIds: string[];\n contractIds: string[];\n line?: number;\n};\n\nexport function parseScenarioDocument(\n text: string,\n uri: string,\n): ScenarioParseResult {\n const { gherkinDocument, errors } = parseGherkin(text, uri);\n if (!gherkinDocument) {\n return { document: null, errors };\n }\n\n const feature = gherkinDocument.feature;\n if (!feature) {\n return {\n document: { uri, featureTags: [], scenarios: [] },\n errors,\n };\n }\n\n const featureTags = collectTagNames(feature.tags);\n const scenarios = collectScenarioNodes(feature, featureTags);\n return {\n document: {\n uri,\n featureName: feature.name,\n featureTags,\n scenarios,\n },\n errors,\n };\n}\n\nexport function buildScenarioAtoms(\n document: ScenarioDocument,\n contractIds: string[] = [],\n): ScenarioAtom[] {\n const uniqueContractIds = unique(contractIds).sort((a, b) =>\n a.localeCompare(b),\n );\n return document.scenarios.map((scenario) => {\n const specIds = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const scIds = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n const brIds = unique(scenario.tags.filter((tag) => BR_TAG_RE.test(tag)));\n\n const atom: ScenarioAtom = {\n uri: document.uri,\n featureName: document.featureName ?? \"\",\n scenarioName: scenario.name,\n kind: scenario.kind,\n brIds,\n contractIds: uniqueContractIds,\n };\n\n if (scenario.line !== undefined) {\n atom.line = scenario.line;\n }\n if (specIds.length === 1) {\n const specId = specIds[0];\n if (specId) {\n atom.specId = specId;\n }\n }\n if (scIds.length === 1) {\n const scId = scIds[0];\n if (scId) {\n atom.scId = scId;\n }\n }\n\n return atom;\n });\n}\n\nfunction collectScenarioNodes(\n feature: Messages.Feature,\n featureTags: string[],\n): ScenarioNode[] {\n const scenarios: ScenarioNode[] = [];\n\n for (const child of feature.children) {\n if (child.scenario) {\n scenarios.push(buildScenarioNode(child.scenario, featureTags, []));\n }\n if (child.rule) {\n const ruleTags = collectTagNames(child.rule.tags);\n for (const ruleChild of child.rule.children) {\n if (ruleChild.scenario) {\n scenarios.push(\n buildScenarioNode(ruleChild.scenario, featureTags, ruleTags),\n );\n }\n }\n }\n }\n\n return scenarios;\n}\n\nfunction buildScenarioNode(\n scenario: Messages.Scenario,\n featureTags: string[],\n ruleTags: string[],\n): ScenarioNode {\n const tags = [...featureTags, ...ruleTags, ...collectTagNames(scenario.tags)];\n const kind: ScenarioKind =\n scenario.examples.length > 0 ? \"ScenarioOutline\" : \"Scenario\";\n return {\n name: scenario.name,\n kind,\n line: scenario.location?.line,\n tags,\n steps: scenario.steps,\n };\n}\n\nfunction collectTagNames(tags: readonly Messages.Tag[]): string[] {\n return tags.map((tag) => tag.name.replace(/^@/, \"\"));\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ndeclare const __QFAI_TOOL_VERSION__: string | undefined;\n\nexport async function resolveToolVersion(): Promise<string> {\n if (\n typeof __QFAI_TOOL_VERSION__ === \"string\" &&\n __QFAI_TOOL_VERSION__.length > 0\n ) {\n return __QFAI_TOOL_VERSION__;\n }\n\n try {\n const packagePath = resolvePackageJsonPath();\n const raw = await readFile(packagePath, \"utf-8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n const version = typeof parsed.version === \"string\" ? parsed.version : \"\";\n return version.length > 0 ? version : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction resolvePackageJsonPath(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n return path.resolve(path.dirname(basePath), \"../../package.json\");\n}\n","export function info(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function warn(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function error(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n","import path from \"node:path\";\n\nimport { copyTemplateTree } from \"../lib/fs.js\";\nimport { getInitAssetsDir } from \"../lib/assets.js\";\nimport { info } from \"../lib/logger.js\";\n\nexport type InitOptions = {\n dir: string;\n force: boolean;\n dryRun: boolean;\n yes: boolean;\n};\n\nexport async function runInit(options: InitOptions): Promise<void> {\n const assetsRoot = getInitAssetsDir();\n const rootAssets = path.join(assetsRoot, \"root\");\n const qfaiAssets = path.join(assetsRoot, \".qfai\");\n\n const destRoot = path.resolve(options.dir);\n const destQfai = path.join(destRoot, \".qfai\");\n\n const rootResult = await copyTemplateTree(rootAssets, destRoot, {\n force: options.force,\n dryRun: options.dryRun,\n });\n const qfaiResult = await copyTemplateTree(qfaiAssets, destQfai, {\n force: options.force,\n dryRun: options.dryRun,\n protect: [\"prompts.local\"],\n });\n\n report(\n [...rootResult.copied, ...qfaiResult.copied],\n [...rootResult.skipped, ...qfaiResult.skipped],\n options.dryRun,\n \"init\",\n );\n}\n\nfunction report(\n copied: string[],\n skipped: string[],\n dryRun: boolean,\n label: string,\n): void {\n info(`qfai ${label}: ${dryRun ? \"dry-run\" : \"done\"}`);\n if (copied.length > 0) {\n info(` created: ${copied.length}`);\n }\n if (skipped.length > 0) {\n info(` skipped: ${skipped.length}`);\n }\n}\n","import { access, copyFile, mkdir, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type CopyOptions = {\n force: boolean;\n dryRun: boolean;\n /**\n * Protect specific relative paths from overwriting.\n * - Even when force=true, existing files under these paths are never overwritten.\n * - When force=false, existing files under these paths do not block the copy.\n */\n protect?: string[];\n};\n\nexport type CopyResult = {\n copied: string[];\n skipped: string[];\n};\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const files = await collectTemplateFiles(sourceRoot);\n return copyFiles(files, sourceRoot, destRoot, options);\n}\n\nexport async function copyTemplatePaths(\n sourceRoot: string,\n destRoot: string,\n relativePaths: string[],\n options: CopyOptions,\n): Promise<CopyResult> {\n const allFiles: string[] = [];\n for (const relPath of relativePaths) {\n const fullPath = path.join(sourceRoot, relPath);\n const files = await collectTemplateFiles(fullPath);\n allFiles.push(...files);\n }\n\n return copyFiles(allFiles, sourceRoot, destRoot, options);\n}\n\nasync function copyFiles(\n files: string[],\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const copied: string[] = [];\n const skipped: string[] = [];\n const conflicts: string[] = [];\n\n const protectPrefixes = (options.protect ?? [])\n .map((p) => p.replace(/^[\\\\/]+/, \"\").replace(/[\\\\/]+$/, \"\"))\n .filter((p) => p.length > 0)\n .map((p) => p + path.sep);\n\n const isProtectedRelative = (relative: string): boolean => {\n if (protectPrefixes.length === 0) {\n return false;\n }\n const normalized = relative.replace(/[\\\\/]+/g, path.sep);\n return protectPrefixes.some(\n (prefix) =>\n normalized === prefix.slice(0, -1) || normalized.startsWith(prefix),\n );\n };\n\n if (!options.force) {\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n if (isProtectedRelative(relative)) {\n continue;\n }\n const dest = path.join(destRoot, relative);\n if (!(await shouldWrite(dest, options.force))) {\n conflicts.push(dest);\n }\n }\n\n if (conflicts.length > 0) {\n throw new Error(formatConflictMessage(conflicts));\n }\n }\n\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n const dest = path.join(destRoot, relative);\n\n const forceForThisFile = isProtectedRelative(relative)\n ? false\n : options.force;\n\n if (!(await shouldWrite(dest, forceForThisFile))) {\n skipped.push(dest);\n continue;\n }\n\n if (!options.dryRun) {\n await mkdir(path.dirname(dest), { recursive: true });\n await copyFile(file, dest);\n }\n copied.push(dest);\n }\n\n return { copied, skipped };\n}\n\nfunction formatConflictMessage(conflicts: string[]): string {\n return [\n \"既存ファイルと衝突しました。安全のため停止します。\",\n \"\",\n \"衝突ファイル:\",\n ...conflicts.map((conflict) => `- ${conflict}`),\n \"\",\n \"上書きして続行する場合は --force を付けて再実行してください。\",\n ].join(\"\\n\");\n}\n\nasync function collectTemplateFiles(root: string): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const items = await readdir(root, { withFileTypes: true });\n for (const item of items) {\n const fullPath = path.join(root, item.name);\n if (item.isDirectory()) {\n const nested = await collectTemplateFiles(fullPath);\n entries.push(...nested);\n continue;\n }\n if (item.isFile()) {\n entries.push(fullPath);\n }\n }\n\n return entries;\n}\n\nasync function shouldWrite(target: string, force: boolean): Promise<boolean> {\n if (force) {\n return true;\n }\n return !(await exists(target));\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function getInitAssetsDir(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n const baseDir = path.dirname(basePath);\n // src/cli/lib と dist/cli/lib からの解決を想定する。\n const candidates = [\n path.resolve(baseDir, \"../../../assets/init\"),\n path.resolve(baseDir, \"../../assets/init\"),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n [\n \"init 用テンプレートが見つかりません。Template assets not found.\",\n \"確認したパス / Checked paths:\",\n ...candidates.map((candidate) => `- ${candidate}`),\n ].join(\"\\n\"),\n );\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { loadConfig, resolvePath } from \"../../core/config.js\";\nimport { normalizeValidationResult } from \"../../core/normalize.js\";\nimport {\n createReportData,\n formatReportJson,\n formatReportMarkdown,\n} from \"../../core/report.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\nimport { validateProject } from \"../../core/validate.js\";\nimport { error, info, warn } from \"../lib/logger.js\";\n\nexport type ReportOptions = {\n root: string;\n format: \"md\" | \"json\";\n outPath?: string;\n inputPath?: string;\n runValidate?: boolean;\n};\n\nexport async function runReport(options: ReportOptions): Promise<void> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n let validation: ValidationResult;\n if (options.runValidate) {\n if (options.inputPath) {\n warn(\"report: --run-validate が指定されたため --in は無視します。\");\n }\n const result = await validateProject(root, configResult);\n const normalized = normalizeValidationResult(root, result);\n await writeValidationResult(\n root,\n configResult.config.output.validateJsonPath,\n normalized,\n );\n validation = normalized;\n } else {\n const input =\n options.inputPath ?? configResult.config.output.validateJsonPath;\n const inputPath = path.isAbsolute(input)\n ? input\n : path.resolve(root, input);\n try {\n validation = await readValidationResult(inputPath);\n } catch (err) {\n if (isMissingFileError(err)) {\n error(\n [\n `qfai report: 入力ファイルが見つかりません: ${inputPath}`,\n \"\",\n \"まず qfai validate を実行してください。例:\",\n \" qfai validate\",\n \"(デフォルトの出力先: .qfai/out/validate.json)\",\n \"\",\n \"または report に --run-validate を指定してください。\",\n \"GitHub Actions テンプレを使っている場合は、workflow の validate ジョブを先に実行してください。\",\n ].join(\"\\n\"),\n );\n process.exitCode = 2;\n return;\n }\n throw err;\n }\n }\n\n const data = await createReportData(root, validation, configResult);\n const output =\n options.format === \"json\"\n ? formatReportJson(data)\n : formatReportMarkdown(data);\n\n const outRoot = resolvePath(root, configResult.config, \"outDir\");\n const defaultOut =\n options.format === \"json\"\n ? path.join(outRoot, \"report.json\")\n : path.join(outRoot, \"report.md\");\n const out = options.outPath ?? defaultOut;\n const outPath = path.isAbsolute(out) ? out : path.resolve(root, out);\n\n await mkdir(path.dirname(outPath), { recursive: true });\n await writeFile(outPath, `${output}\\n`, \"utf-8\");\n\n info(\n `report: info=${validation.counts.info} warning=${validation.counts.warning} error=${validation.counts.error}`,\n );\n info(`wrote report: ${outPath}`);\n}\n\nasync function readValidationResult(\n inputPath: string,\n): Promise<ValidationResult> {\n const raw = await readFile(inputPath, \"utf-8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!isValidationResult(parsed)) {\n throw new Error(`validate.json の形式が不正です: ${inputPath}`);\n }\n return parsed;\n}\n\nfunction isValidationResult(value: unknown): value is ValidationResult {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.toolVersion !== \"string\") {\n return false;\n }\n if (!Array.isArray(record.issues)) {\n return false;\n }\n const counts = record.counts as Record<string, unknown> | undefined;\n if (!counts) {\n return false;\n }\n if (\n typeof counts.info !== \"number\" ||\n typeof counts.warning !== \"number\" ||\n typeof counts.error !== \"number\"\n ) {\n return false;\n }\n\n const traceability = record.traceability as\n | Record<string, unknown>\n | undefined;\n if (!traceability || typeof traceability !== \"object\") {\n return false;\n }\n\n const sc = traceability.sc as Record<string, unknown> | undefined;\n const testFiles = traceability.testFiles as\n | Record<string, unknown>\n | undefined;\n if (!sc || !testFiles) {\n return false;\n }\n if (\n typeof sc.total !== \"number\" ||\n typeof sc.covered !== \"number\" ||\n typeof sc.missing !== \"number\"\n ) {\n return false;\n }\n if (!Array.isArray(sc.missingIds)) {\n return false;\n }\n if (!sc.refs || typeof sc.refs !== \"object\") {\n return false;\n }\n if (\n !Array.isArray(testFiles.globs) ||\n !Array.isArray(testFiles.excludeGlobs) ||\n typeof testFiles.matchedFileCount !== \"number\"\n ) {\n return false;\n }\n\n return true;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n const record = error as { code?: string };\n return record.code === \"ENOENT\";\n}\n\nasync function writeValidationResult(\n root: string,\n outputPath: string,\n result: ValidationResult,\n): Promise<void> {\n const abs = path.isAbsolute(outputPath)\n ? outputPath\n : path.resolve(root, outputPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\n","import type { ScCoverage } from \"./traceability.js\";\nimport type { Issue, ValidationResult } from \"./types.js\";\nimport { toRelativePath } from \"./paths.js\";\n\nexport function normalizeIssuePaths(root: string, issues: Issue[]): Issue[] {\n return issues.map((issue) => {\n if (!issue.file) {\n return issue;\n }\n const normalized = toRelativePath(root, issue.file);\n if (normalized === issue.file) {\n return issue;\n }\n return {\n ...issue,\n file: normalized,\n };\n });\n}\n\nexport function normalizeScCoverage(root: string, sc: ScCoverage): ScCoverage {\n const refs: Record<string, string[]> = {};\n for (const [scId, files] of Object.entries(sc.refs)) {\n refs[scId] = files.map((file) => toRelativePath(root, file));\n }\n return {\n ...sc,\n refs,\n };\n}\n\nexport function normalizeValidationResult(\n root: string,\n result: ValidationResult,\n): ValidationResult {\n return {\n ...result,\n issues: normalizeIssuePaths(root, result.issues),\n traceability: {\n ...result.traceability,\n sc: normalizeScCoverage(root, result.traceability.sc),\n },\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildContractIndex } from \"./contractIndex.js\";\nimport { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport {\n collectContractFiles,\n collectScenarioFiles,\n collectSpecFiles,\n} from \"./discovery.js\";\nimport { collectFiles } from \"./fs.js\";\nimport { extractAllIds, extractIds, type IdPrefix } from \"./ids.js\";\nimport { normalizeValidationResult } from \"./normalize.js\";\nimport { parseSpec } from \"./parse/spec.js\";\nimport { toRelativePath } from \"./paths.js\";\nimport {\n collectScIdSourcesFromScenarioFiles,\n type ScCoverage,\n type TestFileScan,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { validateProject } from \"./validate.js\";\nimport { resolveToolVersion } from \"./version.js\";\n\nexport type ReportSummary = {\n specs: number;\n scenarios: number;\n contracts: {\n api: number;\n ui: number;\n db: number;\n };\n counts: ValidationCounts;\n};\n\nexport type ReportIds = {\n spec: string[];\n br: string[];\n sc: string[];\n ui: string[];\n api: string[];\n db: string[];\n};\n\nexport type ReportContractCoverage = {\n total: number;\n referenced: number;\n orphan: number;\n idToSpecs: Record<string, string[]>;\n};\n\nexport type ReportSpecCoverage = {\n contractRefMissing: number;\n missingRefSpecs: string[];\n specToContracts: Record<string, ReportSpecContractRefs>;\n};\n\nexport type ReportSpecContractRefs = {\n status: \"missing\" | \"declared\";\n ids: string[];\n};\n\nexport type ReportTraceability = {\n upstreamIdsFound: number;\n referencedInCodeOrTests: boolean;\n sc: ScCoverage;\n scSources: Record<string, string[]>;\n testFiles: TestFileScan;\n contracts: ReportContractCoverage;\n specs: ReportSpecCoverage;\n};\n\nexport type ReportData = {\n tool: \"qfai\";\n version: string;\n generatedAt: string;\n root: string;\n configPath: string;\n summary: ReportSummary;\n ids: ReportIds;\n traceability: ReportTraceability;\n issues: Issue[];\n};\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DB\"];\n\nexport async function createReportData(\n root: string,\n validation?: ValidationResult,\n configResult?: ConfigLoadResult,\n): Promise<ReportData> {\n const resolvedRoot = path.resolve(root);\n const resolved = configResult ?? (await loadConfig(resolvedRoot));\n const config = resolved.config;\n const configPath = resolved.configPath;\n\n const specsRoot = resolvePath(resolvedRoot, config, \"specsDir\");\n const contractsRoot = resolvePath(resolvedRoot, config, \"contractsDir\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const dbRoot = path.join(contractsRoot, \"db\");\n const srcRoot = resolvePath(resolvedRoot, config, \"srcDir\");\n const testsRoot = resolvePath(resolvedRoot, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const {\n api: apiFiles,\n ui: uiFiles,\n db: dbFiles,\n } = await collectContractFiles(uiRoot, apiRoot, dbRoot);\n const contractIndex = await buildContractIndex(resolvedRoot, config);\n const contractIdList = Array.from(contractIndex.ids);\n const specContractRefs = await collectSpecContractRefs(\n specFiles,\n contractIdList,\n );\n const referencedContracts = new Set<string>();\n for (const entry of specContractRefs.specToContracts.values()) {\n entry.ids.forEach((id) => referencedContracts.add(id));\n }\n const referencedContractCount = contractIdList.filter((id) =>\n referencedContracts.has(id),\n ).length;\n const orphanContractCount = contractIdList.filter(\n (id) => !referencedContracts.has(id),\n ).length;\n const contractIdToSpecsRecord = mapToSortedRecord(specContractRefs.idToSpecs);\n const specToContractsRecord = mapToSpecContractRecord(\n specContractRefs.specToContracts,\n );\n\n const idsByPrefix = await collectIds([\n ...specFiles,\n ...scenarioFiles,\n ...apiFiles,\n ...uiFiles,\n ...dbFiles,\n ]);\n\n const upstreamIds = await collectUpstreamIds([\n ...specFiles,\n ...scenarioFiles,\n ]);\n const traceability = await evaluateTraceability(\n upstreamIds,\n srcRoot,\n testsRoot,\n );\n const resolvedValidationRaw =\n validation ?? (await validateProject(resolvedRoot, resolved));\n const normalizedValidation = normalizeValidationResult(\n resolvedRoot,\n resolvedValidationRaw,\n );\n const scCoverage = normalizedValidation.traceability.sc;\n const testFiles = normalizedValidation.traceability.testFiles;\n const scSources = await collectScIdSourcesFromScenarioFiles(scenarioFiles);\n const scSourceRecord = mapToSortedRecord(\n normalizeScSources(resolvedRoot, scSources),\n );\n\n const version = await resolveToolVersion();\n const displayRoot = toRelativePath(resolvedRoot, resolvedRoot);\n const displayConfigPath = toRelativePath(resolvedRoot, configPath);\n\n return {\n tool: \"qfai\",\n version,\n generatedAt: new Date().toISOString(),\n root: displayRoot,\n configPath: displayConfigPath,\n summary: {\n specs: specFiles.length,\n scenarios: scenarioFiles.length,\n contracts: {\n api: apiFiles.length,\n ui: uiFiles.length,\n db: dbFiles.length,\n },\n counts: normalizedValidation.counts,\n },\n ids: {\n spec: idsByPrefix.SPEC,\n br: idsByPrefix.BR,\n sc: idsByPrefix.SC,\n ui: idsByPrefix.UI,\n api: idsByPrefix.API,\n db: idsByPrefix.DB,\n },\n traceability: {\n upstreamIdsFound: upstreamIds.size,\n referencedInCodeOrTests: traceability,\n sc: scCoverage,\n scSources: scSourceRecord,\n testFiles,\n contracts: {\n total: contractIdList.length,\n referenced: referencedContractCount,\n orphan: orphanContractCount,\n idToSpecs: contractIdToSpecsRecord,\n },\n specs: {\n contractRefMissing: specContractRefs.missingRefSpecs.size,\n missingRefSpecs: toSortedArray(specContractRefs.missingRefSpecs),\n specToContracts: specToContractsRecord,\n },\n },\n issues: normalizedValidation.issues,\n };\n}\n\nexport function formatReportMarkdown(data: ReportData): string {\n const lines: string[] = [];\n\n lines.push(\"# QFAI Report\");\n lines.push(\"\");\n lines.push(`- 生成日時: ${data.generatedAt}`);\n lines.push(`- ルート: ${data.root}`);\n lines.push(`- 設定: ${data.configPath}`);\n lines.push(`- 版: ${data.version}`);\n lines.push(\"\");\n\n lines.push(\"## 概要\");\n lines.push(\"\");\n lines.push(`- specs: ${data.summary.specs}`);\n lines.push(`- scenarios: ${data.summary.scenarios}`);\n lines.push(\n `- contracts: api ${data.summary.contracts.api} / ui ${data.summary.contracts.ui} / db ${data.summary.contracts.db}`,\n );\n lines.push(\n `- issues: info ${data.summary.counts.info} / warning ${data.summary.counts.warning} / error ${data.summary.counts.error}`,\n );\n lines.push(\"\");\n\n lines.push(\"## ID集計\");\n lines.push(\"\");\n lines.push(formatIdLine(\"SPEC\", data.ids.spec));\n lines.push(formatIdLine(\"BR\", data.ids.br));\n lines.push(formatIdLine(\"SC\", data.ids.sc));\n lines.push(formatIdLine(\"UI\", data.ids.ui));\n lines.push(formatIdLine(\"API\", data.ids.api));\n lines.push(formatIdLine(\"DB\", data.ids.db));\n lines.push(\"\");\n\n lines.push(\"## トレーサビリティ\");\n lines.push(\"\");\n lines.push(`- 上流ID検出数: ${data.traceability.upstreamIdsFound}`);\n lines.push(\n `- コード/テスト参照: ${data.traceability.referencedInCodeOrTests ? \"あり\" : \"なし\"}`,\n );\n lines.push(\"\");\n\n lines.push(\"## 契約カバレッジ\");\n lines.push(\"\");\n lines.push(`- total: ${data.traceability.contracts.total}`);\n lines.push(`- referenced: ${data.traceability.contracts.referenced}`);\n lines.push(`- orphan: ${data.traceability.contracts.orphan}`);\n lines.push(\n `- specContractRefMissing: ${data.traceability.specs.contractRefMissing}`,\n );\n lines.push(\"\");\n\n lines.push(\"## 契約→Spec\");\n lines.push(\"\");\n const contractToSpecs = data.traceability.contracts.idToSpecs;\n const contractIds = Object.keys(contractToSpecs).sort((a, b) =>\n a.localeCompare(b),\n );\n if (contractIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const contractId of contractIds) {\n const specs = contractToSpecs[contractId] ?? [];\n if (specs.length === 0) {\n lines.push(`- ${contractId}: (none)`);\n } else {\n lines.push(`- ${contractId}: ${specs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Spec→契約\");\n lines.push(\"\");\n const specToContracts = data.traceability.specs.specToContracts;\n const specIds = Object.keys(specToContracts).sort((a, b) =>\n a.localeCompare(b),\n );\n if (specIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n const rows = specIds.map((specId) => {\n const entry = specToContracts[specId];\n const contracts =\n entry?.status === \"missing\"\n ? \"(missing)\"\n : entry && entry.ids.length > 0\n ? entry.ids.join(\", \")\n : \"(none)\";\n const status = entry?.status ?? \"missing\";\n return [specId, status, contracts];\n });\n lines.push(...formatMarkdownTable([\"Spec\", \"Status\", \"Contracts\"], rows));\n }\n lines.push(\"\");\n\n lines.push(\"## Specで contract-ref 未宣言\");\n lines.push(\"\");\n const missingRefSpecs = data.traceability.specs.missingRefSpecs;\n if (missingRefSpecs.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const specId of missingRefSpecs) {\n lines.push(`- ${specId}`);\n }\n }\n lines.push(\"\");\n\n lines.push(\"## SCカバレッジ\");\n lines.push(\"\");\n lines.push(`- total: ${data.traceability.sc.total}`);\n lines.push(`- covered: ${data.traceability.sc.covered}`);\n lines.push(`- missing: ${data.traceability.sc.missing}`);\n lines.push(\n `- testFileGlobs: ${formatList(data.traceability.testFiles.globs)}`,\n );\n lines.push(\n `- testFileExcludeGlobs: ${formatList(\n data.traceability.testFiles.excludeGlobs,\n )}`,\n );\n lines.push(\n `- testFileCount: ${data.traceability.testFiles.matchedFileCount}`,\n );\n if (data.traceability.sc.missingIds.length === 0) {\n lines.push(\"- missingIds: (none)\");\n } else {\n const sources = data.traceability.scSources;\n const missingWithSources = data.traceability.sc.missingIds.map((id) => {\n const files = sources[id] ?? [];\n if (files.length === 0) {\n return id;\n }\n return `${id} (${files.join(\", \")})`;\n });\n lines.push(`- missingIds: ${missingWithSources.join(\", \")}`);\n }\n lines.push(\"\");\n\n lines.push(\"## SC→参照テスト\");\n lines.push(\"\");\n const scRefs = data.traceability.sc.refs;\n const scIds = Object.keys(scRefs).sort((a, b) => a.localeCompare(b));\n if (scIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const scId of scIds) {\n const refs = scRefs[scId] ?? [];\n if (refs.length === 0) {\n lines.push(`- ${scId}: (none)`);\n } else {\n lines.push(`- ${scId}: ${refs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Spec:SC=1:1 違反\");\n lines.push(\"\");\n const specScIssues = data.issues.filter(\n (item) => item.code === \"QFAI-TRACE-012\",\n );\n if (specScIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of specScIssues) {\n const location = item.file ?? \"(unknown)\";\n const refs =\n item.refs && item.refs.length > 0 ? item.refs.join(\", \") : item.message;\n lines.push(`- ${location}: ${refs}`);\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Hotspots\");\n lines.push(\"\");\n const hotspots = buildHotspots(data.issues);\n if (hotspots.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const spot of hotspots) {\n lines.push(\n `- ${spot.file}: total ${spot.total} (error ${spot.error} / warning ${spot.warning} / info ${spot.info})`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## トレーサビリティ(検証)\");\n lines.push(\"\");\n const traceIssues = data.issues.filter(\n (item) =>\n item.rule?.startsWith(\"traceability.\") ||\n item.code.startsWith(\"QFAI_TRACE\") ||\n item.code.startsWith(\"QFAI-TRACE-\"),\n );\n if (traceIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of traceIssues) {\n const location = item.file ? ` (${item.file})` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## 検証結果\");\n lines.push(\"\");\n if (data.issues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of data.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}${refs}`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatReportJson(data: ReportData): string {\n return JSON.stringify(data, null, 2);\n}\n\ntype SpecContractRefsResult = {\n specToContracts: Map<string, SpecContractRefEntry>;\n idToSpecs: Map<string, Set<string>>;\n missingRefSpecs: Set<string>;\n};\n\ntype SpecContractRefEntry = {\n status: \"missing\" | \"declared\";\n ids: Set<string>;\n};\n\nasync function collectSpecContractRefs(\n specFiles: string[],\n contractIdList: string[],\n): Promise<SpecContractRefsResult> {\n const specToContracts = new Map<string, SpecContractRefEntry>();\n const idToSpecs = new Map<string, Set<string>>();\n const missingRefSpecs = new Set<string>();\n\n for (const contractId of contractIdList) {\n idToSpecs.set(contractId, new Set<string>());\n }\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n const specKey = parsed.specId;\n if (!specKey) {\n continue;\n }\n const refs = parsed.contractRefs;\n\n if (refs.lines.length === 0) {\n missingRefSpecs.add(specKey);\n specToContracts.set(specKey, { status: \"missing\", ids: new Set() });\n continue;\n }\n\n const current =\n specToContracts.get(specKey) ??\n ({\n status: \"declared\",\n ids: new Set<string>(),\n } satisfies SpecContractRefEntry);\n for (const id of refs.ids) {\n current.ids.add(id);\n const specs = idToSpecs.get(id);\n if (specs) {\n specs.add(specKey);\n }\n }\n specToContracts.set(specKey, current);\n }\n\n return {\n specToContracts,\n idToSpecs,\n missingRefSpecs,\n };\n}\n\nasync function collectIds(\n files: string[],\n): Promise<Record<IdPrefix, string[]>> {\n const result: Record<IdPrefix, Set<string>> = {\n SPEC: new Set(),\n BR: new Set(),\n SC: new Set(),\n UI: new Set(),\n API: new Set(),\n DB: new Set(),\n };\n\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n for (const prefix of ID_PREFIXES) {\n const ids = extractIds(text, prefix);\n ids.forEach((id) => result[prefix].add(id));\n }\n }\n\n return {\n SPEC: toSortedArray(result.SPEC),\n BR: toSortedArray(result.BR),\n SC: toSortedArray(result.SC),\n UI: toSortedArray(result.UI),\n API: toSortedArray(result.API),\n DB: toSortedArray(result.DB),\n };\n}\n\nasync function collectUpstreamIds(files: string[]): Promise<Set<string>> {\n const ids = new Set<string>();\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => ids.add(id));\n }\n return ids;\n}\n\nasync function evaluateTraceability(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<boolean> {\n if (upstreamIds.size === 0) {\n return false;\n }\n\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n return false;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction formatIdLine(label: string, values: string[]): string {\n if (values.length === 0) {\n return `- ${label}: (none)`;\n }\n return `- ${label}: ${values.join(\", \")}`;\n}\n\nfunction formatList(values: string[]): string {\n if (values.length === 0) {\n return \"(none)\";\n }\n return values.join(\", \");\n}\n\nfunction formatMarkdownTable(headers: string[], rows: string[][]): string[] {\n const widths = headers.map((header, index) => {\n const candidates = rows.map((row) => row[index] ?? \"\");\n return Math.max(header.length, ...candidates.map((item) => item.length));\n });\n\n const formatRow = (cells: string[]): string => {\n const padded = cells.map((cell, index) =>\n (cell ?? \"\").padEnd(widths[index] ?? 0),\n );\n return `| ${padded.join(\" | \")} |`;\n };\n\n const separator = `| ${widths.map((width) => \"-\".repeat(width)).join(\" | \")} |`;\n\n return [formatRow(headers), separator, ...rows.map(formatRow)];\n}\n\nfunction toSortedArray(values: Set<string>): string[] {\n return Array.from(values).sort((a, b) => a.localeCompare(b));\n}\n\nfunction mapToSortedRecord(\n values: Map<string, Set<string>>,\n): Record<string, string[]> {\n const record: Record<string, string[]> = {};\n for (const [key, files] of values.entries()) {\n record[key] = Array.from(files).sort((a, b) => a.localeCompare(b));\n }\n return record;\n}\n\nfunction mapToSpecContractRecord(\n values: Map<string, SpecContractRefEntry>,\n): Record<string, ReportSpecContractRefs> {\n const record: Record<string, ReportSpecContractRefs> = {};\n for (const [key, entry] of values.entries()) {\n record[key] = {\n status: entry.status,\n ids: toSortedArray(entry.ids),\n };\n }\n return record;\n}\n\nfunction normalizeScSources(\n root: string,\n sources: Map<string, Set<string>>,\n): Map<string, Set<string>> {\n const normalized = new Map<string, Set<string>>();\n for (const [id, files] of sources.entries()) {\n const mapped = new Set<string>();\n for (const file of files) {\n mapped.add(toRelativePath(root, file));\n }\n normalized.set(id, mapped);\n }\n return normalized;\n}\n\ntype Hotspot = {\n file: string;\n total: number;\n error: number;\n warning: number;\n info: number;\n};\n\nfunction buildHotspots(issues: Issue[]): Hotspot[] {\n const map = new Map<string, Hotspot>();\n for (const issue of issues) {\n if (!issue.file) {\n continue;\n }\n const current =\n map.get(issue.file) ??\n ({\n file: issue.file,\n total: 0,\n error: 0,\n warning: 0,\n info: 0,\n } satisfies Hotspot);\n current.total += 1;\n current[issue.severity] += 1;\n map.set(issue.file, current);\n }\n\n return Array.from(map.values()).sort((a, b) =>\n b.total !== a.total ? b.total - a.total : a.file.localeCompare(b.file),\n );\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"./config.js\";\nimport { resolvePath } from \"./config.js\";\nimport {\n collectApiContractFiles,\n collectDbContractFiles,\n collectUiContractFiles,\n} from \"./discovery.js\";\nimport { extractDeclaredContractIds } from \"./contractsDecl.js\";\n\nexport type ContractIndex = {\n ids: Set<string>;\n idToFiles: Map<string, Set<string>>;\n files: { ui: string[]; api: string[]; db: string[] };\n};\n\nexport async function buildContractIndex(\n root: string,\n config: QfaiConfig,\n): Promise<ContractIndex> {\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const dbRoot = path.join(contractsRoot, \"db\");\n\n const [uiFiles, apiFiles, dbFiles] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDbContractFiles(dbRoot),\n ]);\n\n const index: ContractIndex = {\n ids: new Set<string>(),\n idToFiles: new Map<string, Set<string>>(),\n files: { ui: uiFiles, api: apiFiles, db: dbFiles },\n };\n\n await indexContractFiles(uiFiles, index);\n await indexContractFiles(apiFiles, index);\n await indexContractFiles(dbFiles, index);\n\n return index;\n}\n\nasync function indexContractFiles(\n files: string[],\n index: ContractIndex,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractDeclaredContractIds(text).forEach((id) => record(index, id, file));\n }\n}\n\nfunction record(index: ContractIndex, id: string, file: string): void {\n index.ids.add(id);\n const current = index.idToFiles.get(id) ?? new Set<string>();\n current.add(file);\n index.idToFiles.set(id, current);\n}\n","const CONTRACT_DECLARATION_RE =\n /^\\s*(?:#|\\/\\/|--|\\/\\*+|\\*+)?\\s*QFAI-CONTRACT-ID:\\s*((?:API|UI|DB)-\\d{4})\\s*(?:\\*\\/)?\\s*$/gm;\nconst CONTRACT_DECLARATION_LINE_RE =\n /^\\s*(?:#|\\/\\/|--|\\/\\*+|\\*+)?\\s*QFAI-CONTRACT-ID:\\s*(?:API|UI|DB)-\\d{4}\\s*(?:\\*\\/)?\\s*$/;\n\nexport function extractDeclaredContractIds(text: string): string[] {\n const ids: string[] = [];\n for (const match of text.matchAll(CONTRACT_DECLARATION_RE)) {\n const id = match[1];\n if (id) {\n ids.push(id);\n }\n }\n return ids;\n}\n\nexport function stripContractDeclarationLines(text: string): string {\n return text\n .split(/\\r?\\n/)\n .filter((line) => !CONTRACT_DECLARATION_LINE_RE.test(line))\n .join(\"\\n\");\n}\n","export type IdPrefix = \"SPEC\" | \"BR\" | \"SC\" | \"UI\" | \"API\" | \"DB\";\nexport type IdFormatPrefix = IdPrefix | \"ADR\";\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DB\"];\n\nconst STRICT_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-\\d{4}\\b/g,\n BR: /\\bBR-\\d{4}\\b/g,\n SC: /\\bSC-\\d{4}\\b/g,\n UI: /\\bUI-\\d{4}\\b/g,\n API: /\\bAPI-\\d{4}\\b/g,\n DB: /\\bDB-\\d{4}\\b/g,\n ADR: /\\bADR-\\d{4}\\b/g,\n};\n\nconst LOOSE_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-[A-Za-z0-9_-]+\\b/gi,\n BR: /\\bBR-[A-Za-z0-9_-]+\\b/gi,\n SC: /\\bSC-[A-Za-z0-9_-]+\\b/gi,\n UI: /\\bUI-[A-Za-z0-9_-]+\\b/gi,\n API: /\\bAPI-[A-Za-z0-9_-]+\\b/gi,\n DB: /\\bDB-[A-Za-z0-9_-]+\\b/gi,\n ADR: /\\bADR-[A-Za-z0-9_-]+\\b/gi,\n};\n\nexport function extractIds(text: string, prefix: IdPrefix): string[] {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const matches = text.match(pattern);\n return unique(matches ?? []);\n}\n\nexport function extractAllIds(text: string): string[] {\n const all: string[] = [];\n ID_PREFIXES.forEach((prefix) => {\n all.push(...extractIds(text, prefix));\n });\n return unique(all);\n}\n\nexport function extractInvalidIds(\n text: string,\n prefixes: IdFormatPrefix[],\n): string[] {\n const invalid: string[] = [];\n for (const prefix of prefixes) {\n const candidates = text.match(LOOSE_ID_PATTERNS[prefix]) ?? [];\n for (const candidate of candidates) {\n if (!isValidId(candidate, prefix)) {\n invalid.push(candidate);\n }\n }\n }\n return unique(invalid);\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction isValidId(value: string, prefix: IdFormatPrefix): boolean {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const strict = new RegExp(pattern.source);\n return strict.test(value);\n}\n","export type ParsedContractRefs = {\n lines: string[];\n ids: string[];\n invalidTokens: string[];\n hasNone: boolean;\n};\n\nexport type ContractRefParseOptions = {\n allowCommentPrefix?: boolean;\n};\n\nconst CONTRACT_REF_ID_RE = /^(?:API|UI|DB)-\\d{4}$/;\n\nexport function parseContractRefs(\n text: string,\n options: ContractRefParseOptions = {},\n): ParsedContractRefs {\n const linePattern = buildLinePattern(options);\n const lines: string[] = [];\n for (const match of text.matchAll(linePattern)) {\n lines.push((match[1] ?? \"\").trim());\n }\n\n const ids: string[] = [];\n const invalidTokens: string[] = [];\n let hasNone = false;\n\n for (const line of lines) {\n if (line.length === 0) {\n invalidTokens.push(\"(empty)\");\n continue;\n }\n const tokens = line.split(\",\").map((token) => token.trim());\n for (const token of tokens) {\n if (token.length === 0) {\n invalidTokens.push(\"(empty)\");\n continue;\n }\n if (token === \"none\") {\n hasNone = true;\n continue;\n }\n if (CONTRACT_REF_ID_RE.test(token)) {\n ids.push(token);\n continue;\n }\n invalidTokens.push(token);\n }\n }\n\n return {\n lines,\n ids: unique(ids),\n invalidTokens: unique(invalidTokens),\n hasNone,\n };\n}\n\nfunction buildLinePattern(options: ContractRefParseOptions): RegExp {\n // Scenario uses a comment line, so require \"#\" when the comment prefix is enabled.\n const prefix = options.allowCommentPrefix ? \"#\" : \"\";\n return new RegExp(\n `^[ \\\\t]*${prefix}[ \\\\t]*QFAI-CONTRACT-REF:[ \\\\t]*([^\\\\r\\\\n]*)[ \\\\t]*$`,\n \"gm\",\n );\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","export type Heading = { level: number; title: string; line: number };\n\nexport type H2Section = {\n title: string;\n startLine: number;\n endLine: number;\n body: string;\n};\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\nexport function parseHeadings(md: string): Heading[] {\n const lines = md.split(/\\r?\\n/);\n const headings: Heading[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const match = line.match(HEADING_RE);\n if (!match) continue;\n const levelToken = match[1];\n const title = match[2];\n if (!levelToken || !title) continue;\n headings.push({\n level: levelToken.length,\n title: title.trim(),\n line: i + 1,\n });\n }\n return headings;\n}\n\nexport function extractH2Sections(md: string): Map<string, H2Section> {\n const lines = md.split(/\\r?\\n/);\n const headings = parseHeadings(md).filter((heading) => heading.level === 2);\n const sections = new Map<string, H2Section>();\n\n for (let i = 0; i < headings.length; i++) {\n const current = headings[i];\n if (!current) continue;\n const next = headings[i + 1];\n const startLine = current.line + 1;\n const endLine = (next?.line ?? lines.length + 1) - 1;\n const body =\n startLine <= endLine\n ? lines.slice(startLine - 1, endLine).join(\"\\n\")\n : \"\";\n\n sections.set(current.title.trim(), {\n title: current.title.trim(),\n startLine,\n endLine,\n body,\n });\n }\n\n return sections;\n}\n","import { parseContractRefs, type ParsedContractRefs } from \"./contractRefs.js\";\nimport { extractH2Sections, parseHeadings } from \"./markdown.js\";\n\nexport type BrPriority = \"P0\" | \"P1\" | \"P2\" | \"P3\";\n\nexport type ParsedBr = {\n id: string;\n priority: BrPriority;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithoutPriority = {\n id: string;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithInvalidPriority = {\n id: string;\n priority: string;\n text: string;\n line: number;\n};\n\nexport type ParsedSpec = {\n file: string;\n specId?: string;\n sections: Set<string>;\n brs: ParsedBr[];\n brsWithoutPriority: ParsedBrWithoutPriority[];\n brsWithInvalidPriority: ParsedBrWithInvalidPriority[];\n contractRefs: ParsedContractRefs;\n};\n\nconst SPEC_ID_RE = /\\bSPEC-\\d{4}\\b/;\nconst BR_LINE_RE = /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[0-3])\\]\\s*(.+)$/;\nconst BR_LINE_ANY_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[^\\]]+)\\]\\s*(.+)$/;\nconst BR_LINE_NO_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\](?!\\s*\\[P)\\s*(.*\\S.*)$/;\nconst BR_SECTION_TITLE = \"業務ルール\";\nconst VALID_PRIORITIES = new Set<BrPriority>([\"P0\", \"P1\", \"P2\", \"P3\"]);\n\nexport function parseSpec(md: string, file: string): ParsedSpec {\n const headings = parseHeadings(md);\n const h1 = headings.find((heading) => heading.level === 1);\n const specId = h1?.title.match(SPEC_ID_RE)?.[0];\n\n const sections = extractH2Sections(md);\n const sectionNames = new Set(Array.from(sections.keys()));\n const brSection = sections.get(BR_SECTION_TITLE);\n const brLines = brSection ? brSection.body.split(/\\r?\\n/) : [];\n const startLine = brSection?.startLine ?? 1;\n\n const brs: ParsedBr[] = [];\n const brsWithoutPriority: ParsedBrWithoutPriority[] = [];\n const brsWithInvalidPriority: ParsedBrWithInvalidPriority[] = [];\n\n for (let i = 0; i < brLines.length; i++) {\n const lineText = brLines[i] ?? \"\";\n const lineNumber = startLine + i;\n\n const validMatch = lineText.match(BR_LINE_RE);\n if (validMatch) {\n const id = validMatch[1];\n const priority = validMatch[2];\n const text = validMatch[3];\n if (!id || !priority || !text) continue;\n brs.push({\n id,\n priority: priority as BrPriority,\n text: text.trim(),\n line: lineNumber,\n });\n continue;\n }\n\n const anyPriorityMatch = lineText.match(BR_LINE_ANY_PRIORITY_RE);\n if (anyPriorityMatch) {\n const id = anyPriorityMatch[1];\n const priority = anyPriorityMatch[2];\n const text = anyPriorityMatch[3];\n if (!id || !priority || !text) continue;\n if (!VALID_PRIORITIES.has(priority as BrPriority)) {\n brsWithInvalidPriority.push({\n id,\n priority,\n text: text.trim(),\n line: lineNumber,\n });\n }\n continue;\n }\n\n const noPriorityMatch = lineText.match(BR_LINE_NO_PRIORITY_RE);\n if (noPriorityMatch) {\n const id = noPriorityMatch[1];\n const text = noPriorityMatch[2];\n if (!id || !text) continue;\n brsWithoutPriority.push({\n id,\n text: text.trim(),\n line: lineNumber,\n });\n }\n }\n\n const parsed: ParsedSpec = {\n file,\n sections: sectionNames,\n brs,\n brsWithoutPriority,\n brsWithInvalidPriority,\n contractRefs: parseContractRefs(md),\n };\n if (specId) {\n parsed.specId = specId;\n }\n return parsed;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { parseStructuredContract } from \"../contracts.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport {\n extractDeclaredContractIds,\n stripContractDeclarationLines,\n} from \"../contractsDecl.js\";\nimport {\n collectApiContractFiles,\n collectDbContractFiles,\n collectUiContractFiles,\n} from \"../discovery.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SQL_DANGEROUS_PATTERNS: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /\\bDROP\\s+TABLE\\b/i, label: \"DROP TABLE\" },\n { pattern: /\\bDROP\\s+DATABASE\\b/i, label: \"DROP DATABASE\" },\n { pattern: /\\bTRUNCATE\\b/i, label: \"TRUNCATE\" },\n {\n pattern: /\\bALTER\\s+TABLE\\b[\\s\\S]*\\bDROP\\b/i,\n label: \"ALTER TABLE ... DROP\",\n },\n];\n\nexport async function validateContracts(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n\n issues.push(...(await validateUiContracts(path.join(contractsRoot, \"ui\"))));\n issues.push(...(await validateApiContracts(path.join(contractsRoot, \"api\"))));\n issues.push(...(await validateDbContracts(path.join(contractsRoot, \"db\"))));\n const contractIndex = await buildContractIndex(root, config);\n issues.push(...validateDuplicateContractIds(contractIndex));\n\n return issues;\n}\n\nasync function validateUiContracts(uiRoot: string): Promise<Issue[]> {\n const files = await collectUiContractFiles(uiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-UI-000\",\n \"UI 契約ファイルが見つかりません。\",\n \"info\",\n uiRoot,\n \"contracts.ui.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"UI\"));\n try {\n parseStructuredContract(file, stripContractDeclarationLines(text));\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `UI 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.ui.parse\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateApiContracts(apiRoot: string): Promise<Issue[]> {\n const files = await collectApiContractFiles(apiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-API-000\",\n \"API 契約ファイルが見つかりません。\",\n \"info\",\n apiRoot,\n \"contracts.api.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"API\"));\n let doc: Record<string, unknown>;\n try {\n doc = parseStructuredContract(file, stripContractDeclarationLines(text));\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `API 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.api.parse\",\n ),\n );\n continue;\n }\n\n if (!hasOpenApi(doc)) {\n issues.push(\n issue(\n \"QFAI-API-001\",\n \"OpenAPI 定義が見つかりません。\",\n \"error\",\n file,\n \"contracts.api.openapi\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateDbContracts(dbRoot: string): Promise<Issue[]> {\n const files = await collectDbContractFiles(dbRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-DB-000\",\n \"DB 契約ファイルが見つかりません。\",\n \"info\",\n dbRoot,\n \"contracts.db.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"DB\"));\n issues.push(...lintSql(text, file));\n }\n\n return issues;\n}\n\nexport function lintSql(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n for (const { pattern, label } of SQL_DANGEROUS_PATTERNS) {\n if (pattern.test(text)) {\n issues.push(\n issue(\n \"QFAI-DB-001\",\n `危険な SQL 操作が含まれています: ${label}`,\n \"warning\",\n file,\n \"contracts.db.sql\",\n ),\n );\n }\n }\n return issues;\n}\n\ntype ContractKind = \"UI\" | \"API\" | \"DB\";\n\nfunction validateDeclaredContractIds(\n ids: string[],\n file: string,\n kind: ContractKind,\n): Issue[] {\n const issues: Issue[] = [];\n if (ids.length === 0) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-010\",\n `契約ファイルに QFAI-CONTRACT-ID がありません: ${file}`,\n \"error\",\n file,\n \"contracts.declaration\",\n ),\n );\n return issues;\n }\n if (ids.length > 1) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-011\",\n `契約ファイルに複数の QFAI-CONTRACT-ID が宣言されています: ${ids.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"contracts.declaration\",\n ids,\n ),\n );\n return issues;\n }\n\n const [id] = ids;\n if (id && !id.startsWith(`${kind}-`)) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-013\",\n `契約ファイルの QFAI-CONTRACT-ID が ${kind}- ではありません: ${id}`,\n \"error\",\n file,\n \"contracts.declarationPrefix\",\n [id],\n ),\n );\n }\n\n return issues;\n}\n\nfunction validateDuplicateContractIds(contractIndex: {\n idToFiles: Map<string, Set<string>>;\n}): Issue[] {\n const issues: Issue[] = [];\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sortedFiles = Array.from(files).sort((a, b) => a.localeCompare(b));\n issues.push(\n issue(\n \"QFAI-CONTRACT-012\",\n `契約 ID が複数ファイルで宣言されています: ${id} (${sortedFiles.join(\n \", \",\n )})`,\n \"error\",\n sortedFiles[0],\n \"contracts.idDuplicate\",\n [id],\n ),\n );\n }\n return issues;\n}\n\nfunction hasOpenApi(doc: Record<string, unknown>): boolean {\n return typeof doc.openapi === \"string\" && doc.openapi.length > 0;\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport { extractIds } from \"./ids.js\";\n\nexport function parseStructuredContract(\n file: string,\n text: string,\n): Record<string, unknown> {\n const ext = path.extname(file).toLowerCase();\n if (ext === \".json\") {\n return JSON.parse(text) as Record<string, unknown>;\n }\n return parseYaml(text) as Record<string, unknown>;\n}\n\nexport function extractUiContractIds(doc: Record<string, unknown>): string[] {\n const id = typeof doc.id === \"string\" ? doc.id : \"\";\n return extractIds(id, \"UI\");\n}\n\nexport function extractApiContractIds(doc: Record<string, unknown>): string[] {\n const operationIds = new Set<string>();\n collectOperationIds(doc, operationIds);\n\n const ids = new Set<string>();\n for (const operationId of operationIds) {\n extractIds(operationId, \"API\").forEach((id) => ids.add(id));\n }\n return Array.from(ids);\n}\n\nexport function collectOperationIds(value: unknown, out: Set<string>): void {\n if (!value || typeof value !== \"object\") {\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectOperationIds(item, out);\n }\n return;\n }\n\n for (const [key, entry] of Object.entries(value)) {\n if (key === \"operationId\" && typeof entry === \"string\") {\n out.add(entry);\n continue;\n }\n collectOperationIds(entry, out);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { collectSpecPackDirs } from \"../discovery.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SECTION_RE = /^##\\s+変更区分/m;\nconst COMPAT_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Change\\/Improvement\\b/m;\nconst COMPAT_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Change\\/Improvement\\b/m;\n\nexport async function validateDeltas(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const packs = await collectSpecPackDirs(specsRoot);\n if (packs.length === 0) {\n return [];\n }\n\n const issues: Issue[] = [];\n for (const pack of packs) {\n const deltaPath = path.join(pack, \"delta.md\");\n let text: string;\n try {\n text = await readFile(deltaPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-DELTA-001\",\n \"delta.md が見つかりません。\",\n \"error\",\n deltaPath,\n \"delta.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n\n const hasSection = SECTION_RE.test(text);\n const hasCompatibility = COMPAT_LINE_RE.test(text);\n const hasChange = CHANGE_LINE_RE.test(text);\n if (!hasSection || !hasCompatibility || !hasChange) {\n issues.push(\n issue(\n \"QFAI-DELTA-002\",\n \"delta.md の変更区分が不足しています。\",\n \"error\",\n deltaPath,\n \"delta.section\",\n ),\n );\n continue;\n }\n\n const compatibilityChecked = COMPAT_CHECKED_RE.test(text);\n const changeChecked = CHANGE_CHECKED_RE.test(text);\n if (compatibilityChecked === changeChecked) {\n issues.push(\n issue(\n \"QFAI-DELTA-003\",\n \"delta.md の変更区分はどちらか1つだけ選択してください(両方ON/両方OFFは無効です)。\",\n \"error\",\n deltaPath,\n \"delta.classification\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SC_TAG_RE = /^SC-\\d{4}$/;\n\nexport async function validateDefinedIds(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const defined = new Map<string, Set<string>>();\n\n await collectSpecDefinitionIds(specFiles, defined);\n await collectScenarioDefinitionIds(scenarioFiles, defined);\n const contractIndex = await buildContractIndex(root, config);\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n for (const file of files) {\n recordId(defined, id, file);\n }\n }\n\n for (const [id, files] of defined.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sorted = Array.from(files).sort();\n issues.push(\n issue(\n \"QFAI-ID-001\",\n `ID が重複しています: ${id} (${formatFileList(sorted, root)})`,\n \"error\",\n sorted[0],\n \"id.duplicate\",\n ),\n );\n }\n\n return issues;\n}\n\nasync function collectSpecDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n recordId(out, parsed.specId, file);\n }\n parsed.brs.forEach((br) => recordId(out, br.id, file));\n }\n}\n\nasync function collectScenarioDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n recordId(out, tag, file);\n }\n }\n }\n }\n}\n\nfunction recordId(\n out: Map<string, Set<string>>,\n id: string,\n file: string,\n): void {\n const current = out.get(id) ?? new Set<string>();\n current.add(file);\n out.set(id, current);\n}\n\nfunction formatFileList(files: string[], root: string): string {\n return files\n .map((file) => {\n const relative = path.relative(root, file);\n return relative.length > 0 ? relative : file;\n })\n .join(\", \");\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst GIVEN_PATTERN = /\\bGiven\\b/;\nconst WHEN_PATTERN = /\\bWhen\\b/;\nconst THEN_PATTERN = /\\bThen\\b/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\n\nexport async function validateScenarios(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/scenario.md\";\n const legacy = \"spec-001/scenario.md\";\n return [\n issue(\n \"QFAI-SC-000\",\n `Scenario ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"scenario.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.scenarioPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SC-001\",\n \"scenario.md が見つかりません。\",\n \"error\",\n entry.scenarioPath,\n \"scenario.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(...validateScenarioContent(text, entry.scenarioPath));\n }\n\n return issues;\n}\n\nexport function validateScenarioContent(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-010\",\n `Gherkin の解析に失敗しました: ${errors.join(\", \") || \"unknown\"}`,\n \"error\",\n file,\n \"scenario.parse\",\n ),\n );\n return issues;\n }\n\n const featureSpecTags = document.featureTags.filter((tag) =>\n SPEC_TAG_RE.test(tag),\n );\n if (featureSpecTags.length > 1) {\n issues.push(\n issue(\n \"QFAI-SC-009\",\n `Feature の SPEC タグが複数あります: ${featureSpecTags.join(\", \")}`,\n \"error\",\n file,\n \"scenario.featureSpec\",\n featureSpecTags,\n ),\n );\n }\n\n const missingStructure: string[] = [];\n if (!document.featureName) missingStructure.push(\"Feature\");\n if (document.scenarios.length === 0) missingStructure.push(\"Scenario\");\n if (missingStructure.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-006\",\n `Scenario ファイルに必要な構造がありません: ${missingStructure.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"scenario.structure\",\n ),\n );\n }\n\n for (const scenario of document.scenarios) {\n if (scenario.tags.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-007\",\n `Scenario タグが見つかりません: ${scenario.name}`,\n \"error\",\n file,\n \"scenario.tags\",\n ),\n );\n continue;\n }\n\n const missingTags: string[] = [];\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n if (scTags.length === 0) {\n missingTags.push(\"SC(0件)\");\n } else if (scTags.length > 1) {\n missingTags.push(`SC(${scTags.length}件/1件必須)`);\n }\n if (missingTags.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-008\",\n `Scenario タグに不足があります: ${missingTags.join(\", \")} (${\n scenario.name\n })`,\n \"error\",\n file,\n \"scenario.tagIds\",\n ),\n );\n }\n }\n\n for (const scenario of document.scenarios) {\n const missingSteps: string[] = [];\n const keywords = scenario.steps.map((step) => step.keyword.trim());\n if (!keywords.some((keyword) => GIVEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Given\");\n }\n if (!keywords.some((keyword) => WHEN_PATTERN.test(keyword))) {\n missingSteps.push(\"When\");\n }\n if (!keywords.some((keyword) => THEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Then\");\n }\n if (missingSteps.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-005\",\n `Given/When/Then が不足しています: ${missingSteps.join(\", \")} (${\n scenario.name\n })`,\n \"warning\",\n file,\n \"scenario.steps\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractIds, extractInvalidIds } from \"../ids.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nexport async function validateSpecs(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/spec.md\";\n const legacy = \"spec-001/spec.md\";\n return [\n issue(\n \"QFAI-SPEC-000\",\n `Spec ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"spec.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.specPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SPEC-005\",\n \"spec.md が見つかりません。\",\n \"error\",\n entry.specPath,\n \"spec.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(\n ...validateSpecContent(\n text,\n entry.specPath,\n config.validation.require.specSections,\n ),\n );\n }\n\n return issues;\n}\n\nexport function validateSpecContent(\n text: string,\n file: string,\n requiredSections: string[],\n): Issue[] {\n const issues: Issue[] = [];\n\n const parsed = parseSpec(text, file);\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n if (!parsed.specId) {\n issues.push(\n issue(\n \"QFAI-SPEC-001\",\n \"SPEC ID が見つかりません。\",\n \"error\",\n file,\n \"spec.id\",\n ),\n );\n }\n\n if (parsed.brs.length === 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-002\",\n \"BR ID が見つかりません。\",\n \"error\",\n file,\n \"spec.br\",\n ),\n );\n }\n\n for (const br of parsed.brsWithoutPriority) {\n issues.push(\n issue(\n \"QFAI-BR-001\",\n `BR 行に Priority がありません: ${br.id}`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n for (const br of parsed.brsWithInvalidPriority) {\n issues.push(\n issue(\n \"QFAI-BR-002\",\n `BR Priority が不正です: ${br.id} (${br.priority})`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n const scIds = extractIds(text, \"SC\");\n if (scIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-003\",\n \"Spec は SC を参照しないルールです。\",\n \"warning\",\n file,\n \"spec.noSc\",\n scIds,\n ),\n );\n }\n\n for (const section of requiredSections) {\n if (!parsed.sections.has(section)) {\n issues.push(\n issue(\n \"QFAI-SPEC-004\",\n `必須セクションが不足しています: ${section}`,\n \"error\",\n file,\n \"spec.requiredSection\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { collectFiles } from \"../fs.js\";\nimport { extractAllIds } from \"../ids.js\";\nimport { parseContractRefs } from \"../parse/contractRefs.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { buildScenarioAtoms, parseScenarioDocument } from \"../scenarioModel.js\";\nimport { SC_TAG_RE, collectScTestReferences } from \"../traceability.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\n\nexport async function validateTraceability(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const upstreamIds = new Set<string>();\n const specIds = new Set<string>();\n const brIdsInSpecs = new Set<string>();\n const brIdsInScenarios = new Set<string>();\n const scIdsInScenarios = new Set<string>();\n const specContractIds = new Set<string>();\n const specToBrIds = new Map<string, Set<string>>();\n const contractIndex = await buildContractIndex(root, config);\n const contractIds = contractIndex.ids;\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n specIds.add(parsed.specId);\n }\n\n const brIds = parsed.brs.map((br) => br.id);\n brIds.forEach((id) => brIdsInSpecs.add(id));\n\n if (parsed.specId) {\n const current = specToBrIds.get(parsed.specId) ?? new Set<string>();\n brIds.forEach((id) => current.add(id));\n specToBrIds.set(parsed.specId, current);\n }\n\n const contractRefs = parsed.contractRefs;\n if (contractRefs.lines.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-020\",\n \"Spec に QFAI-CONTRACT-REF がありません。\",\n \"error\",\n file,\n \"traceability.specContractRefRequired\",\n ),\n );\n } else {\n if (contractRefs.hasNone && contractRefs.ids.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-023\",\n \"Spec の QFAI-CONTRACT-REF に none と契約 ID が混在しています。\",\n \"error\",\n file,\n \"traceability.specContractRefFormat\",\n ),\n );\n }\n if (contractRefs.invalidTokens.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-021\",\n `Spec の契約 ID が不正です: ${contractRefs.invalidTokens.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"traceability.specContractRefFormat\",\n contractRefs.invalidTokens,\n ),\n );\n }\n }\n\n contractRefs.ids.forEach((id) => {\n specContractIds.add(id);\n });\n\n const unknownContractIds = contractRefs.ids.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-024\",\n `Spec が未知の契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"traceability.specContractExists\",\n unknownContractIds,\n ),\n );\n }\n }\n\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const scenarioContractRefs = parseContractRefs(text, {\n allowCommentPrefix: true,\n });\n if (scenarioContractRefs.lines.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-031\",\n \"Scenario に QFAI-CONTRACT-REF がありません。\",\n \"error\",\n file,\n \"traceability.scenarioContractRefRequired\",\n ),\n );\n } else {\n if (scenarioContractRefs.hasNone && scenarioContractRefs.ids.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-033\",\n \"Scenario の QFAI-CONTRACT-REF に none と契約 ID が混在しています。\",\n \"error\",\n file,\n \"traceability.scenarioContractRefFormat\",\n ),\n );\n }\n if (scenarioContractRefs.invalidTokens.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-032\",\n `Scenario の契約 ID が不正です: ${scenarioContractRefs.invalidTokens.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"traceability.scenarioContractRefFormat\",\n scenarioContractRefs.invalidTokens,\n ),\n );\n }\n }\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n if (document.scenarios.length !== 1) {\n issues.push(\n issue(\n \"QFAI-TRACE-030\",\n `Scenario ファイルは 1ファイル=1シナリオです。現在: ${document.scenarios.length}件 (file=${file})`,\n \"error\",\n file,\n \"traceability.scenarioOnePerFile\",\n ),\n );\n }\n\n const atoms = buildScenarioAtoms(document, scenarioContractRefs.ids);\n const scIdsInFile = new Set<string>();\n\n for (const [index, scenario] of document.scenarios.entries()) {\n const atom = atoms[index];\n if (!atom) {\n continue;\n }\n\n const specTags = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const brTags = scenario.tags.filter((tag) => BR_TAG_RE.test(tag));\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n\n if (specTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-014\",\n `Scenario が SPEC タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioSpecRequired\",\n ),\n );\n }\n if (brTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-015\",\n `Scenario が BR タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioBrRequired\",\n ),\n );\n }\n\n brTags.forEach((id) => brIdsInScenarios.add(id));\n scTags.forEach((id) => {\n scIdsInScenarios.add(id);\n scIdsInFile.add(id);\n });\n const unknownSpecIds = specTags.filter((id) => !specIds.has(id));\n if (unknownSpecIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-005\",\n `Scenario が存在しない SPEC を参照しています: ${unknownSpecIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioSpecExists\",\n unknownSpecIds,\n ),\n );\n }\n\n const unknownBrIds = brTags.filter((id) => !brIdsInSpecs.has(id));\n if (unknownBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-006\",\n `Scenario が存在しない BR を参照しています: ${unknownBrIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrExists\",\n unknownBrIds,\n ),\n );\n }\n\n const unknownContractIds = atom.contractIds.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-008\",\n `Scenario が存在しない契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )} (${scenario.name})`,\n config.validation.traceability.unknownContractIdSeverity,\n file,\n \"traceability.scenarioContractExists\",\n unknownContractIds,\n ),\n );\n }\n\n if (specTags.length > 0 && brTags.length > 0) {\n const allowedBrIds = new Set<string>();\n for (const specId of specTags) {\n const brIdsForSpec = specToBrIds.get(specId);\n if (!brIdsForSpec) {\n continue;\n }\n brIdsForSpec.forEach((id) => allowedBrIds.add(id));\n }\n const invalidBrIds = brTags.filter((id) => !allowedBrIds.has(id));\n if (invalidBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-007\",\n `Scenario の BR が参照 SPEC に属していません: ${invalidBrIds.join(\n \", \",\n )} (SPEC: ${specTags.join(\", \")}) (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrUnderSpec\",\n invalidBrIds,\n ),\n );\n }\n }\n }\n\n if (scIdsInFile.size !== 1) {\n const invalidScIds = Array.from(scIdsInFile).sort((a, b) =>\n a.localeCompare(b),\n );\n const detail =\n invalidScIds.length === 0\n ? \"SC が見つかりません\"\n : `複数の SC が存在します: ${invalidScIds.join(\", \")}`;\n issues.push(\n issue(\n \"QFAI-TRACE-012\",\n `Spec entry が Spec:SC=1:1 を満たしていません: ${detail}`,\n \"error\",\n file,\n \"traceability.specScOneToOne\",\n invalidScIds,\n ),\n );\n }\n }\n\n if (upstreamIds.size === 0) {\n return [\n issue(\n \"QFAI-TRACE-000\",\n \"上流 ID が見つかりません。\",\n \"info\",\n specsRoot,\n \"traceability.upstream\",\n ),\n ];\n }\n\n if (config.validation.traceability.brMustHaveSc && brIdsInSpecs.size > 0) {\n const orphanBrIds = Array.from(brIdsInSpecs).filter(\n (id) => !brIdsInScenarios.has(id),\n );\n if (orphanBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-009\",\n `BR が SC に紐づいていません: ${orphanBrIds.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.brMustHaveSc\",\n orphanBrIds,\n ),\n );\n }\n }\n\n const scRefsResult = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scTestRefs = scRefsResult.refs;\n const testFileScan = scRefsResult.scan;\n const hasScenarios = scIdsInScenarios.size > 0;\n const hasGlobConfig = testFileScan.globs.length > 0;\n const hasMatchedTests = testFileScan.matchedFileCount > 0;\n\n if (\n hasScenarios &&\n (!hasGlobConfig || !hasMatchedTests || scRefsResult.error)\n ) {\n const detail = scRefsResult.error ? `(詳細: ${scRefsResult.error})` : \"\";\n issues.push(\n issue(\n \"QFAI-TRACE-013\",\n `テスト探索 glob が未設定/不正/一致ファイル0のため SC→Test を判定できません。${detail}`,\n \"error\",\n testsRoot,\n \"traceability.testFileGlobs\",\n ),\n );\n } else {\n if (\n config.validation.traceability.scMustHaveTest &&\n scIdsInScenarios.size\n ) {\n const scWithoutTests = Array.from(scIdsInScenarios).filter((id) => {\n const refs = scTestRefs.get(id);\n return !refs || refs.size === 0;\n });\n if (scWithoutTests.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-010\",\n `SC がテストで参照されていません: ${scWithoutTests.join(\n \", \",\n )}。testFileGlobs に一致するテストファイルへ QFAI:SC-xxxx を記載してください。`,\n config.validation.traceability.scNoTestSeverity,\n testsRoot,\n \"traceability.scMustHaveTest\",\n scWithoutTests,\n ),\n );\n }\n }\n\n const unknownScIds = Array.from(scTestRefs.keys()).filter(\n (id) => !scIdsInScenarios.has(id),\n );\n if (unknownScIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-011\",\n `テストが未知の SC をアノテーション参照しています: ${unknownScIds.join(\n \", \",\n )}`,\n \"error\",\n testsRoot,\n \"traceability.scUnknownInTests\",\n unknownScIds,\n ),\n );\n }\n }\n\n const orphanPolicy = config.validation.traceability.orphanContractsPolicy;\n if (orphanPolicy !== \"allow\") {\n if (contractIds.size > 0) {\n const orphanContracts = Array.from(contractIds).filter(\n (id) => !specContractIds.has(id),\n );\n if (orphanContracts.length > 0) {\n const severity: IssueSeverity =\n orphanPolicy === \"warning\" ? \"warning\" : \"error\";\n issues.push(\n issue(\n \"QFAI-TRACE-022\",\n `契約が Spec から参照されていません: ${orphanContracts.join(\", \")}`,\n severity,\n specsRoot,\n \"traceability.contractCoverage\",\n orphanContracts,\n ),\n );\n }\n }\n }\n\n issues.push(\n ...(await validateCodeReferences(upstreamIds, srcRoot, testsRoot)),\n );\n return issues;\n}\n\nasync function validateCodeReferences(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-001\",\n \"参照対象のコード/テストが見つかりません。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n return issues;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n let found = false;\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n issues.push(\n issue(\n \"QFAI-TRACE-002\",\n \"上流 ID がコード/テストに参照されていません(参考情報)。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n }\n\n return issues;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport { collectScenarioFiles } from \"./discovery.js\";\nimport {\n buildScCoverage,\n collectScIdsFromScenarioFiles,\n collectScTestReferences,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { resolveToolVersion } from \"./version.js\";\nimport { validateContracts } from \"./validators/contracts.js\";\nimport { validateDeltas } from \"./validators/delta.js\";\nimport { validateDefinedIds } from \"./validators/ids.js\";\nimport { validateScenarios } from \"./validators/scenario.js\";\nimport { validateSpecs } from \"./validators/spec.js\";\nimport { validateTraceability } from \"./validators/traceability.js\";\n\nexport async function validateProject(\n root: string,\n configResult?: ConfigLoadResult,\n): Promise<ValidationResult> {\n const resolved = configResult ?? (await loadConfig(root));\n const { config, issues: configIssues } = resolved;\n const issues = [\n ...configIssues,\n ...(await validateSpecs(root, config)),\n ...(await validateDeltas(root, config)),\n ...(await validateScenarios(root, config)),\n ...(await validateContracts(root, config)),\n ...(await validateDefinedIds(root, config)),\n ...(await validateTraceability(root, config)),\n ];\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const scIds = await collectScIdsFromScenarioFiles(scenarioFiles);\n const { refs: scTestRefs, scan: testFiles } = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scCoverage = buildScCoverage(scIds, scTestRefs);\n\n const toolVersion = await resolveToolVersion();\n return {\n toolVersion,\n issues,\n counts: countIssues(issues),\n traceability: {\n sc: scCoverage,\n testFiles,\n },\n };\n}\n\nfunction countIssues(issues: Issue[]): ValidationCounts {\n return issues.reduce<ValidationCounts>(\n (acc, issue) => {\n acc[issue.severity] += 1;\n return acc;\n },\n { info: 0, warning: 0, error: 0 },\n );\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { FailOn, OutputFormat } from \"../../core/config.js\";\nimport { loadConfig } from \"../../core/config.js\";\nimport { normalizeValidationResult } from \"../../core/normalize.js\";\nimport { toRelativePath } from \"../../core/paths.js\";\nimport type { Issue, ValidationResult } from \"../../core/types.js\";\nimport { validateProject } from \"../../core/validate.js\";\nimport { shouldFail } from \"../lib/failOn.js\";\n\nexport type ValidateOptions = {\n root: string;\n strict: boolean;\n failOn?: FailOn;\n format?: OutputFormat;\n};\n\nexport async function runValidate(options: ValidateOptions): Promise<number> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const result = await validateProject(root, configResult);\n const normalized = normalizeValidationResult(root, result);\n\n const format = options.format ?? \"text\";\n if (format === \"text\") {\n emitText(normalized);\n }\n if (format === \"github\") {\n const jsonPath = resolveJsonPath(\n root,\n configResult.config.output.validateJsonPath,\n );\n emitGitHubOutput(normalized, root, jsonPath);\n }\n await emitJson(normalized, root, configResult.config.output.validateJsonPath);\n\n const failOn = resolveFailOn(options, configResult.config.validation.failOn);\n return shouldFail(normalized, failOn) ? 1 : 0;\n}\n\nfunction resolveFailOn(options: ValidateOptions, fallback: FailOn): FailOn {\n if (options.failOn) {\n return options.failOn;\n }\n if (options.strict) {\n return \"warning\";\n }\n return fallback;\n}\n\nfunction emitText(result: ValidationResult): void {\n for (const item of result.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n process.stdout.write(\n `[${item.severity}] ${item.code} ${item.message}${location}${refs}\\n`,\n );\n }\n process.stdout.write(\n `counts: info=${result.counts.info} warning=${result.counts.warning} error=${result.counts.error}\\n`,\n );\n}\n\nfunction emitGitHubOutput(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n): void {\n const deduped = dedupeIssues(result.issues);\n const omitted = Math.max(deduped.length - GITHUB_ANNOTATION_LIMIT, 0);\n const dropped = Math.max(result.issues.length - deduped.length, 0);\n\n emitGitHubSummary(result, {\n total: deduped.length,\n omitted,\n dropped,\n jsonPath,\n root,\n });\n\n const issues = deduped.slice(0, GITHUB_ANNOTATION_LIMIT);\n for (const issue of issues) {\n emitGitHub(issue);\n }\n}\n\nfunction emitGitHub(issue: Issue): void {\n const level =\n issue.severity === \"error\"\n ? \"error\"\n : issue.severity === \"warning\"\n ? \"warning\"\n : \"notice\";\n const file = issue.file ? `file=${issue.file}` : \"\";\n const line = issue.loc?.line ? `,line=${issue.loc.line}` : \"\";\n const column = issue.loc?.column ? `,col=${issue.loc.column}` : \"\";\n const location = file ? ` ${file}${line}${column}` : \"\";\n process.stdout.write(\n `::${level}${location}::${issue.code}: ${issue.message}\\n`,\n );\n}\n\nfunction emitGitHubSummary(\n result: ValidationResult,\n options: {\n total: number;\n omitted: number;\n dropped: number;\n jsonPath: string;\n root: string;\n },\n): void {\n const summary = [\n \"qfai validate summary:\",\n `error=${result.counts.error}`,\n `warning=${result.counts.warning}`,\n `info=${result.counts.info}`,\n `annotations=${Math.min(options.total, GITHUB_ANNOTATION_LIMIT)}/${options.total}`,\n ].join(\" \");\n process.stdout.write(`${summary}\\n`);\n\n if (options.dropped > 0 || options.omitted > 0) {\n const details = [\n \"qfai validate note:\",\n options.dropped > 0 ? `重複除外=${options.dropped}` : null,\n options.omitted > 0 ? `上限省略=${options.omitted}` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n process.stdout.write(`${details}\\n`);\n }\n\n const relative = toRelativePath(options.root, options.jsonPath);\n process.stdout.write(\n `qfai validate note: 詳細は ${relative} または --format text を参照してください。\\n`,\n );\n}\n\nfunction dedupeIssues(issues: Issue[]): Issue[] {\n const seen = new Set<string>();\n const deduped: Issue[] = [];\n for (const issue of issues) {\n const key = issueKey(issue);\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n deduped.push(issue);\n }\n return deduped;\n}\n\nfunction issueKey(issue: Issue): string {\n const file = issue.file ?? \"\";\n const line = issue.loc?.line ?? \"\";\n const column = issue.loc?.column ?? \"\";\n return [issue.code, issue.severity, issue.message, file, line, column].join(\n \"|\",\n );\n}\n\nasync function emitJson(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n): Promise<void> {\n const abs = resolveJsonPath(root, jsonPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction resolveJsonPath(root: string, jsonPath: string): string {\n return path.isAbsolute(jsonPath) ? jsonPath : path.resolve(root, jsonPath);\n}\n\nconst GITHUB_ANNOTATION_LIMIT = 100;\n","import type { FailOn } from \"../../core/config.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\n\nexport type { FailOn };\n\nexport function shouldFail(result: ValidationResult, failOn: FailOn): boolean {\n if (failOn === \"never\") {\n return false;\n }\n if (failOn === \"error\") {\n return result.counts.error > 0;\n }\n return result.counts.error + result.counts.warning > 0;\n}\n","export type ParsedArgs = {\n command: string | null;\n options: {\n root: string;\n rootExplicit: boolean;\n dir: string;\n force: boolean;\n yes: boolean;\n dryRun: boolean;\n reportFormat: \"md\" | \"json\";\n reportOut?: string;\n reportIn?: string;\n reportRunValidate: boolean;\n doctorFormat: \"text\" | \"json\";\n doctorOut?: string;\n validateFormat: \"text\" | \"github\";\n strict: boolean;\n failOn?: \"never\" | \"warning\" | \"error\";\n help: boolean;\n };\n};\n\nexport function parseArgs(argv: string[], cwd: string): ParsedArgs {\n const options: ParsedArgs[\"options\"] = {\n root: cwd,\n rootExplicit: false,\n dir: cwd,\n force: false,\n yes: false,\n dryRun: false,\n reportFormat: \"md\",\n reportRunValidate: false,\n doctorFormat: \"text\",\n validateFormat: \"text\",\n strict: false,\n help: false,\n };\n\n const args = [...argv];\n let command = args.shift() ?? null;\n\n if (command === \"--help\" || command === \"-h\") {\n options.help = true;\n command = null;\n }\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n switch (arg) {\n case \"--root\":\n options.root = args[i + 1] ?? options.root;\n options.rootExplicit = true;\n i += 1;\n break;\n case \"--dir\":\n options.dir = args[i + 1] ?? options.dir;\n i += 1;\n break;\n case \"--force\":\n options.force = true;\n break;\n case \"--yes\":\n options.yes = true;\n break;\n case \"--dry-run\":\n options.dryRun = true;\n break;\n case \"--format\": {\n const next = args[i + 1];\n applyFormatOption(command, next, options);\n i += 1;\n break;\n }\n case \"--strict\":\n options.strict = true;\n break;\n case \"--fail-on\": {\n const next = args[i + 1];\n if (next === \"never\" || next === \"warning\" || next === \"error\") {\n options.failOn = next;\n }\n i += 1;\n break;\n }\n case \"--out\":\n {\n const next = args[i + 1];\n if (next) {\n if (command === \"doctor\") {\n options.doctorOut = next;\n } else {\n options.reportOut = next;\n }\n }\n }\n i += 1;\n break;\n case \"--in\":\n {\n const next = args[i + 1];\n if (next) {\n options.reportIn = next;\n }\n }\n i += 1;\n break;\n case \"--run-validate\":\n options.reportRunValidate = true;\n break;\n case \"--help\":\n case \"-h\":\n options.help = true;\n break;\n default:\n break;\n }\n }\n\n return { command, options };\n}\n\nfunction applyFormatOption(\n command: string | null,\n value: string | undefined,\n options: ParsedArgs[\"options\"],\n): void {\n if (!value) {\n return;\n }\n if (command === \"report\") {\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n return;\n }\n if (command === \"validate\") {\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n return;\n }\n if (command === \"doctor\") {\n if (value === \"text\" || value === \"json\") {\n options.doctorFormat = value;\n }\n return;\n }\n\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n}\n","import { runDoctor } from \"./commands/doctor.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runReport } from \"./commands/report.js\";\nimport { runValidate } from \"./commands/validate.js\";\nimport { parseArgs } from \"./lib/args.js\";\nimport { error, info, warn } from \"./lib/logger.js\";\nimport { findConfigRoot } from \"../core/config.js\";\n\nexport async function run(argv: string[], cwd: string): Promise<void> {\n const { command, options } = parseArgs(argv, cwd);\n\n if (!command || options.help) {\n info(usage());\n return;\n }\n\n switch (command) {\n case \"init\":\n await runInit({\n dir: options.dir,\n force: options.force,\n dryRun: options.dryRun,\n yes: options.yes,\n });\n return;\n case \"validate\":\n {\n const resolvedRoot = await resolveRoot(options);\n process.exitCode = await runValidate({\n root: resolvedRoot,\n strict: options.strict,\n format: options.validateFormat,\n ...(options.failOn !== undefined ? { failOn: options.failOn } : {}),\n });\n }\n return;\n case \"report\":\n {\n const resolvedRoot = await resolveRoot(options);\n await runReport({\n root: resolvedRoot,\n format: options.reportFormat,\n ...(options.reportOut !== undefined\n ? { outPath: options.reportOut }\n : {}),\n ...(options.reportIn !== undefined\n ? { inputPath: options.reportIn }\n : {}),\n ...(options.reportRunValidate ? { runValidate: true } : {}),\n });\n }\n return;\n case \"doctor\":\n {\n const exitCode = await runDoctor({\n root: options.root,\n rootExplicit: options.rootExplicit,\n format: options.doctorFormat,\n ...(options.doctorOut !== undefined\n ? { outPath: options.doctorOut }\n : {}),\n ...(options.failOn && options.failOn !== \"never\"\n ? { failOn: options.failOn }\n : {}),\n });\n process.exitCode = exitCode;\n }\n return;\n default:\n error(`Unknown command: ${command}`);\n info(usage());\n return;\n }\n}\n\nfunction usage(): string {\n return `qfai <command> [options]\n\nCommands:\n init テンプレを生成\n validate 仕様/契約/参照の検査\n report 検証結果と集計を出力\n doctor 設定/パス/出力前提の診断\n\nOptions:\n --root <path> 対象ディレクトリ\n --dir <path> init の出力先\n --force 既存ファイルを上書き\n --yes init: 予約フラグ(現状は非対話のため挙動差なし。将来の対話導入時に自動Yes)\n --dry-run 変更を行わず表示のみ\n --format <text|github> validate の出力形式\n --format <md|json> report の出力形式\n --format <text|json> doctor の出力形式\n --strict validate: warning 以上で exit 1\n --fail-on <error|warning|never> validate: 失敗条件\n --fail-on <error|warning> doctor: 失敗条件\n --out <path> report/doctor: 出力先\n --in <path> report: validate.json の入力先(configより優先)\n --run-validate report: validate を実行してから report を生成\n -h, --help ヘルプ表示\n`;\n}\n\nasync function resolveRoot(options: {\n root: string;\n rootExplicit: boolean;\n}): Promise<string> {\n if (options.rootExplicit) {\n return options.root;\n }\n\n const search = await findConfigRoot(options.root);\n if (!search.found) {\n warn(\n `qfai: qfai.config.yaml が見つからないため defaultConfig を使用します (root=${search.root})`,\n );\n }\n return search.root;\n}\n","#!/usr/bin/env node\nimport { run } from \"./main.js\";\n\nrun(process.argv.slice(2), process.cwd()).catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["import_promises","import_node_path","import_promises","import_node_path","path","parseYaml","error","import_promises","import_promises","import_node_path","exists","fg","path","import_promises","import_node_path","path","error","exists","import_node_path","path","import_promises","import_node_path","error","formatError","SC_TAG_RE","error","formatError","path","import_promises","import_node_path","path","exists","normalizeGlobs","path","error","path","import_node_path","import_promises","import_node_path","path","exists","import_node_path","import_node_url","path","path","import_promises","import_node_path","issue","import_promises","import_node_path","import_promises","import_node_path","path","unique","unique","import_promises","import_node_path","import_node_path","import_yaml","path","parseYaml","path","error","formatError","issue","import_promises","import_node_path","path","error","isMissingFileError","issue","import_promises","import_node_path","SC_TAG_RE","issue","path","import_promises","SC_TAG_RE","SPEC_TAG_RE","issue","error","isMissingFileError","import_promises","issue","error","isMissingFileError","import_promises","SPEC_TAG_RE","BR_TAG_RE","issue","SC_TAG_RE","issue","ID_PREFIXES","path","toSortedArray","buildIdPattern","record","issue","path","isMissingFileError","record","error","import_promises","import_node_path","path","issue"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/doctor.ts","../../src/core/doctor.ts","../../src/core/config.ts","../../src/core/discovery.ts","../../src/core/fs.ts","../../src/core/specLayout.ts","../../src/core/paths.ts","../../src/core/traceability.ts","../../src/core/gherkin/parse.ts","../../src/core/scenarioModel.ts","../../src/core/version.ts","../../src/cli/lib/logger.ts","../../src/cli/commands/init.ts","../../src/cli/lib/fs.ts","../../src/cli/lib/assets.ts","../../src/cli/commands/report.ts","../../src/core/normalize.ts","../../src/core/report.ts","../../src/core/contractIndex.ts","../../src/core/contractsDecl.ts","../../src/core/ids.ts","../../src/core/parse/contractRefs.ts","../../src/core/parse/markdown.ts","../../src/core/parse/spec.ts","../../src/core/validators/contracts.ts","../../src/core/contracts.ts","../../src/core/validators/delta.ts","../../src/core/validators/ids.ts","../../src/core/validators/scenario.ts","../../src/core/validators/spec.ts","../../src/core/validators/traceability.ts","../../src/core/validate.ts","../../src/cli/commands/validate.ts","../../src/cli/lib/failOn.ts","../../src/cli/lib/args.ts","../../src/cli/main.ts","../../src/cli/index.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { createDoctorData } from \"../../core/doctor.js\";\nimport { info } from \"../lib/logger.js\";\n\nexport type DoctorCommandOptions = {\n root: string;\n rootExplicit: boolean;\n format: \"text\" | \"json\";\n outPath?: string;\n failOn?: \"warning\" | \"error\";\n};\n\nfunction formatDoctorText(\n data: Awaited<ReturnType<typeof createDoctorData>>,\n): string {\n const lines: string[] = [];\n lines.push(\n `qfai doctor: root=${data.root} config=${data.config.configPath} (${data.config.found ? \"found\" : \"missing\"})`,\n );\n for (const check of data.checks) {\n lines.push(`[${check.severity}] ${check.id}: ${check.message}`);\n }\n lines.push(\n `summary: ok=${data.summary.ok} info=${data.summary.info} warning=${data.summary.warning} error=${data.summary.error}`,\n );\n return lines.join(\"\\n\");\n}\n\nfunction formatDoctorJson(data: unknown): string {\n return JSON.stringify(data, null, 2);\n}\n\nexport async function runDoctor(\n options: DoctorCommandOptions,\n): Promise<number> {\n const data = await createDoctorData({\n startDir: options.root,\n rootExplicit: options.rootExplicit,\n });\n\n const output =\n options.format === \"json\" ? formatDoctorJson(data) : formatDoctorText(data);\n const exitCode = shouldFailDoctor(data.summary, options.failOn) ? 1 : 0;\n\n if (options.outPath) {\n const outAbs = path.isAbsolute(options.outPath)\n ? options.outPath\n : path.resolve(process.cwd(), options.outPath);\n await mkdir(path.dirname(outAbs), { recursive: true });\n await writeFile(outAbs, `${output}\\n`, \"utf-8\");\n info(`doctor: wrote ${outAbs}`);\n return exitCode;\n }\n\n info(output);\n return exitCode;\n}\n\nfunction shouldFailDoctor(\n summary: { warning: number; error: number },\n failOn?: \"warning\" | \"error\",\n): boolean {\n if (!failOn) {\n return false;\n }\n if (failOn === \"error\") {\n return summary.error > 0;\n }\n return summary.warning + summary.error > 0;\n}\n","import { access } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n findConfigRoot,\n getConfigPath,\n loadConfig,\n resolvePath,\n} from \"./config.js\";\nimport { collectScenarioFiles } from \"./discovery.js\";\nimport { collectFilesByGlobs } from \"./fs.js\";\nimport { toRelativePath } from \"./paths.js\";\nimport { collectSpecEntries } from \"./specLayout.js\";\nimport { DEFAULT_TEST_FILE_EXCLUDE_GLOBS } from \"./traceability.js\";\nimport { resolveToolVersion } from \"./version.js\";\n\nexport type DoctorSeverity = \"ok\" | \"info\" | \"warning\" | \"error\";\n\nexport type DoctorCheck = {\n id: string;\n severity: DoctorSeverity;\n title: string;\n message: string;\n details?: Record<string, unknown>;\n};\n\nexport type DoctorData = {\n tool: \"qfai\";\n version: string;\n generatedAt: string;\n root: string;\n config: {\n startDir: string;\n found: boolean;\n configPath: string;\n };\n summary: { ok: number; info: number; warning: number; error: number };\n checks: DoctorCheck[];\n};\n\ntype CreateDoctorDataOptions = {\n startDir: string;\n rootExplicit: boolean;\n};\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction addCheck(checks: DoctorCheck[], check: DoctorCheck): void {\n checks.push(check);\n}\n\nfunction summarize(checks: DoctorCheck[]): DoctorData[\"summary\"] {\n const summary = { ok: 0, info: 0, warning: 0, error: 0 };\n for (const check of checks) {\n summary[check.severity] += 1;\n }\n return summary;\n}\n\nfunction normalizeGlobs(values: string[]): string[] {\n return values.map((glob) => glob.trim()).filter((glob) => glob.length > 0);\n}\n\nexport async function createDoctorData(\n options: CreateDoctorDataOptions,\n): Promise<DoctorData> {\n const startDir = path.resolve(options.startDir);\n const checks: DoctorCheck[] = [];\n\n const configPath = getConfigPath(startDir);\n const search = options.rootExplicit\n ? {\n root: startDir,\n configPath,\n found: await exists(configPath),\n }\n : await findConfigRoot(startDir);\n\n const root = search.root;\n const version = await resolveToolVersion();\n const generatedAt = new Date().toISOString();\n\n addCheck(checks, {\n id: \"config.search\",\n severity: search.found ? \"ok\" : \"warning\",\n title: \"Config search\",\n message: search.found\n ? \"qfai.config.yaml found\"\n : \"qfai.config.yaml not found (default config will be used)\",\n details: { configPath: toRelativePath(root, search.configPath) },\n });\n\n const {\n config,\n issues,\n configPath: resolvedConfigPath,\n } = await loadConfig(root);\n if (issues.length === 0) {\n addCheck(checks, {\n id: \"config.load\",\n severity: \"ok\",\n title: \"Config load\",\n message: \"Loaded and normalized with 0 issues\",\n details: { configPath: toRelativePath(root, resolvedConfigPath) },\n });\n } else {\n addCheck(checks, {\n id: \"config.load\",\n severity: \"warning\",\n title: \"Config load\",\n message: `Loaded with ${issues.length} issue(s) (normalized with defaults when needed)`,\n details: {\n configPath: toRelativePath(root, resolvedConfigPath),\n issues,\n },\n });\n }\n\n const pathKeys = [\n \"specsDir\",\n \"contractsDir\",\n \"outDir\",\n \"srcDir\",\n \"testsDir\",\n \"rulesDir\",\n \"promptsDir\",\n ] as const;\n\n for (const key of pathKeys) {\n const resolved = resolvePath(root, config, key);\n const ok = await exists(resolved);\n addCheck(checks, {\n id: `paths.${key}`,\n severity: ok ? \"ok\" : \"warning\",\n title: `Path exists: ${key}`,\n message: ok\n ? `${key} exists`\n : `${key} is missing (did you run 'qfai init'?)`,\n details: { path: toRelativePath(root, resolved) },\n });\n\n if (key === \"promptsDir\") {\n const promptsLocalDir = path.join(\n path.dirname(resolved),\n `${path.basename(resolved)}.local`,\n );\n const found = await exists(promptsLocalDir);\n addCheck(checks, {\n id: \"paths.promptsLocalDir\",\n severity: \"info\",\n title: \"Prompts overlay (prompts.local)\",\n message: found\n ? \"prompts.local exists (overlay can be used)\"\n : \"prompts.local is optional (create it to override prompts)\",\n details: { path: toRelativePath(root, promptsLocalDir) },\n });\n }\n }\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n let missingFiles = 0;\n\n for (const entry of entries) {\n const requiredFiles = [entry.specPath, entry.deltaPath, entry.scenarioPath];\n for (const filePath of requiredFiles) {\n if (!(await exists(filePath))) {\n missingFiles += 1;\n }\n }\n }\n\n addCheck(checks, {\n id: \"spec.layout\",\n severity: missingFiles === 0 ? \"ok\" : \"warning\",\n title: \"Spec pack shape\",\n message:\n missingFiles === 0\n ? `All spec packs have required files (count=${entries.length})`\n : `Missing required files in spec packs (missingFiles=${missingFiles})`,\n details: { specPacks: entries.length, missingFiles },\n });\n\n const validateJsonAbs = path.isAbsolute(config.output.validateJsonPath)\n ? config.output.validateJsonPath\n : path.resolve(root, config.output.validateJsonPath);\n const validateJsonExists = await exists(validateJsonAbs);\n addCheck(checks, {\n id: \"output.validateJson\",\n severity: validateJsonExists ? \"ok\" : \"warning\",\n title: \"validate.json\",\n message: validateJsonExists\n ? \"validate.json exists (report can run)\"\n : \"validate.json is missing (run 'qfai validate' before 'qfai report')\",\n details: { path: toRelativePath(root, validateJsonAbs) },\n });\n\n const outDirAbs = resolvePath(root, config, \"outDir\");\n const rel = path.relative(outDirAbs, validateJsonAbs);\n const inside = rel !== \"\" && !rel.startsWith(\"..\") && !path.isAbsolute(rel);\n addCheck(checks, {\n id: \"output.pathAlignment\",\n severity: inside ? \"ok\" : \"warning\",\n title: \"Output path alignment\",\n message: inside\n ? \"validateJsonPath is under outDir\"\n : \"validateJsonPath is not under outDir (may be intended, but check configuration)\",\n details: {\n outDir: toRelativePath(root, outDirAbs),\n validateJsonPath: toRelativePath(root, validateJsonAbs),\n },\n });\n\n if (options.rootExplicit) {\n addCheck(checks, await buildOutDirCollisionCheck(root));\n }\n\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const globs = normalizeGlobs(config.validation.traceability.testFileGlobs);\n const exclude = normalizeGlobs([\n ...DEFAULT_TEST_FILE_EXCLUDE_GLOBS,\n ...config.validation.traceability.testFileExcludeGlobs,\n ]);\n\n try {\n const matched =\n globs.length === 0\n ? []\n : await collectFilesByGlobs(root, { globs, ignore: exclude });\n const matchedCount = matched.length;\n\n const severity: DoctorSeverity =\n globs.length === 0\n ? \"warning\"\n : scenarioFiles.length > 0 &&\n config.validation.traceability.scMustHaveTest &&\n matchedCount === 0\n ? \"warning\"\n : \"ok\";\n\n addCheck(checks, {\n id: \"traceability.testGlobs\",\n severity,\n title: \"Test file globs\",\n message:\n globs.length === 0\n ? \"testFileGlobs is empty (SC→Test cannot be verified)\"\n : `matchedFileCount=${matchedCount}`,\n details: {\n globs,\n excludeGlobs: exclude,\n scenarioFiles: scenarioFiles.length,\n scMustHaveTest: config.validation.traceability.scMustHaveTest,\n },\n });\n } catch (error) {\n addCheck(checks, {\n id: \"traceability.testGlobs\",\n severity: \"error\",\n title: \"Test file globs\",\n message: \"Glob scan failed (invalid pattern or filesystem error)\",\n details: { globs, excludeGlobs: exclude, error: String(error) },\n });\n }\n\n return {\n tool: \"qfai\",\n version,\n generatedAt,\n root: toRelativePath(process.cwd(), root),\n config: {\n startDir: toRelativePath(process.cwd(), startDir),\n found: search.found,\n configPath: toRelativePath(root, search.configPath) || \"qfai.config.yaml\",\n },\n summary: summarize(checks),\n checks,\n };\n}\n\nconst DEFAULT_CONFIG_SEARCH_IGNORE_GLOBS = [\n ...DEFAULT_TEST_FILE_EXCLUDE_GLOBS,\n \"**/.pnpm/**\",\n \"**/tmp/**\",\n \"**/.mcp-tools/**\",\n];\n\ntype OutDirCollision = {\n outDir: string;\n roots: string[];\n};\n\ntype OutDirCollisionResult = {\n monorepoRoot: string;\n configRoots: string[];\n collisions: OutDirCollision[];\n};\n\nasync function buildOutDirCollisionCheck(root: string): Promise<DoctorCheck> {\n try {\n const result = await detectOutDirCollisions(root);\n const relativeRoot = toRelativePath(process.cwd(), result.monorepoRoot);\n const configRoots = result.configRoots\n .map((configRoot) => toRelativePath(result.monorepoRoot, configRoot))\n .sort((a, b) => a.localeCompare(b));\n const collisions = result.collisions\n .map((item) => ({\n outDir: toRelativePath(result.monorepoRoot, item.outDir),\n roots: item.roots\n .map((collisionRoot) =>\n toRelativePath(result.monorepoRoot, collisionRoot),\n )\n .sort((a, b) => a.localeCompare(b)),\n }))\n .sort((a, b) => a.outDir.localeCompare(b.outDir));\n const severity: DoctorSeverity = collisions.length > 0 ? \"warning\" : \"ok\";\n const message =\n collisions.length > 0\n ? `outDir collision detected (count=${collisions.length})`\n : `outDir collision not detected (configs=${configRoots.length})`;\n\n return {\n id: \"output.outDirCollision\",\n severity,\n title: \"OutDir collision\",\n message,\n details: {\n monorepoRoot: relativeRoot,\n configRoots,\n collisions,\n },\n };\n } catch (error) {\n return {\n id: \"output.outDirCollision\",\n severity: \"error\",\n title: \"OutDir collision\",\n message: \"OutDir collision scan failed\",\n details: { error: String(error) },\n };\n }\n}\n\nasync function detectOutDirCollisions(\n root: string,\n): Promise<OutDirCollisionResult> {\n const monorepoRoot = await findMonorepoRoot(root);\n const configPaths = await collectFilesByGlobs(monorepoRoot, {\n globs: [\"**/qfai.config.yaml\"],\n ignore: DEFAULT_CONFIG_SEARCH_IGNORE_GLOBS,\n });\n const configRoots = Array.from(\n new Set(configPaths.map((configPath) => path.dirname(configPath))),\n ).sort((a, b) => a.localeCompare(b));\n const outDirToRoots = new Map<string, Set<string>>();\n\n for (const configRoot of configRoots) {\n const { config } = await loadConfig(configRoot);\n const outDir = path.normalize(resolvePath(configRoot, config, \"outDir\"));\n const roots = outDirToRoots.get(outDir) ?? new Set<string>();\n roots.add(configRoot);\n outDirToRoots.set(outDir, roots);\n }\n\n const collisions: OutDirCollision[] = [];\n for (const [outDir, roots] of outDirToRoots.entries()) {\n if (roots.size > 1) {\n collisions.push({\n outDir,\n roots: Array.from(roots).sort((a, b) => a.localeCompare(b)),\n });\n }\n }\n\n return { monorepoRoot, configRoots, collisions };\n}\n\nasync function findMonorepoRoot(startDir: string): Promise<string> {\n let current = path.resolve(startDir);\n while (true) {\n const gitPath = path.join(current, \".git\");\n const workspacePath = path.join(current, \"pnpm-workspace.yaml\");\n if ((await exists(gitPath)) || (await exists(workspacePath))) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return path.resolve(startDir);\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { Issue } from \"./types.js\";\n\nexport type FailOn = \"never\" | \"warning\" | \"error\";\nexport type OutputFormat = \"text\" | \"github\";\nexport type TraceabilitySeverity = \"warning\" | \"error\";\nexport type OrphanContractsPolicy = \"error\" | \"warning\" | \"allow\";\n\nexport type QfaiPaths = {\n contractsDir: string;\n specsDir: string;\n rulesDir: string;\n outDir: string;\n promptsDir: string;\n srcDir: string;\n testsDir: string;\n};\n\nexport type QfaiValidationConfig = {\n failOn: FailOn;\n require: {\n specSections: string[];\n };\n traceability: {\n brMustHaveSc: boolean;\n scMustHaveTest: boolean;\n testFileGlobs: string[];\n testFileExcludeGlobs: string[];\n scNoTestSeverity: TraceabilitySeverity;\n orphanContractsPolicy: OrphanContractsPolicy;\n unknownContractIdSeverity: TraceabilitySeverity;\n };\n};\n\nexport type QfaiOutputConfig = {\n validateJsonPath: string;\n};\n\nexport type QfaiConfig = {\n paths: QfaiPaths;\n validation: QfaiValidationConfig;\n output: QfaiOutputConfig;\n};\n\nexport type ConfigPathKey = keyof QfaiPaths;\n\nexport type ConfigLoadResult = {\n config: QfaiConfig;\n issues: Issue[];\n configPath: string;\n};\n\nexport type ConfigSearchResult = {\n root: string;\n configPath: string;\n found: boolean;\n};\n\nexport const defaultConfig: QfaiConfig = {\n paths: {\n contractsDir: \".qfai/contracts\",\n specsDir: \".qfai/specs\",\n rulesDir: \".qfai/rules\",\n outDir: \".qfai/out\",\n promptsDir: \".qfai/prompts\",\n srcDir: \"src\",\n testsDir: \"tests\",\n },\n validation: {\n failOn: \"error\",\n require: {\n specSections: [\n \"背景\",\n \"スコープ\",\n \"非ゴール\",\n \"用語\",\n \"前提\",\n \"決定事項\",\n \"業務ルール\",\n ],\n },\n traceability: {\n brMustHaveSc: true,\n scMustHaveTest: true,\n testFileGlobs: [],\n testFileExcludeGlobs: [],\n scNoTestSeverity: \"error\",\n orphanContractsPolicy: \"error\",\n unknownContractIdSeverity: \"error\",\n },\n },\n output: {\n validateJsonPath: \".qfai/out/validate.json\",\n },\n};\n\nexport function getConfigPath(root: string): string {\n return path.join(root, \"qfai.config.yaml\");\n}\n\nexport async function findConfigRoot(\n startDir: string,\n): Promise<ConfigSearchResult> {\n const resolvedStart = path.resolve(startDir);\n let current = resolvedStart;\n\n while (true) {\n const configPath = getConfigPath(current);\n if (await exists(configPath)) {\n return { root: current, configPath, found: true };\n }\n const parent = path.dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n return {\n root: resolvedStart,\n configPath: getConfigPath(resolvedStart),\n found: false,\n };\n}\n\nexport async function loadConfig(root: string): Promise<ConfigLoadResult> {\n const configPath = getConfigPath(root);\n const issues: Issue[] = [];\n\n let parsed: unknown;\n try {\n const raw = await readFile(configPath, \"utf-8\");\n parsed = parseYaml(raw);\n } catch (error) {\n if (isMissingFile(error)) {\n return { config: defaultConfig, issues, configPath };\n }\n issues.push(configIssue(configPath, formatError(error)));\n return { config: defaultConfig, issues, configPath };\n }\n\n const normalized = normalizeConfig(parsed, configPath, issues);\n return { config: normalized, issues, configPath };\n}\n\nexport function resolvePath(\n root: string,\n config: QfaiConfig,\n key: ConfigPathKey,\n): string {\n return path.resolve(root, config.paths[key]);\n}\n\nfunction normalizeConfig(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiConfig {\n if (!isRecord(raw)) {\n issues.push(configIssue(configPath, \"設定ファイルの形式が不正です。\"));\n return defaultConfig;\n }\n\n return {\n paths: normalizePaths(raw.paths, configPath, issues),\n validation: normalizeValidation(raw.validation, configPath, issues),\n output: normalizeOutput(raw.output, configPath, issues),\n };\n}\n\nfunction normalizePaths(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiPaths {\n const base = defaultConfig.paths;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"paths はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n contractsDir: readString(\n raw.contractsDir,\n base.contractsDir,\n \"paths.contractsDir\",\n configPath,\n issues,\n ),\n specsDir: readString(\n raw.specsDir,\n base.specsDir,\n \"paths.specsDir\",\n configPath,\n issues,\n ),\n rulesDir: readString(\n raw.rulesDir,\n base.rulesDir,\n \"paths.rulesDir\",\n configPath,\n issues,\n ),\n outDir: readString(\n raw.outDir,\n base.outDir,\n \"paths.outDir\",\n configPath,\n issues,\n ),\n promptsDir: readString(\n raw.promptsDir,\n base.promptsDir,\n \"paths.promptsDir\",\n configPath,\n issues,\n ),\n srcDir: readString(\n raw.srcDir,\n base.srcDir,\n \"paths.srcDir\",\n configPath,\n issues,\n ),\n testsDir: readString(\n raw.testsDir,\n base.testsDir,\n \"paths.testsDir\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction normalizeValidation(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiValidationConfig {\n const base = defaultConfig.validation;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(\n configPath,\n \"validation はオブジェクトである必要があります。\",\n ),\n );\n return base;\n }\n\n let requireRaw: Record<string, unknown> | undefined;\n if (raw.require === undefined) {\n requireRaw = undefined;\n } else if (isRecord(raw.require)) {\n requireRaw = raw.require;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.require はオブジェクトである必要があります。\",\n ),\n );\n requireRaw = undefined;\n }\n\n let traceabilityRaw: Record<string, unknown> | undefined;\n if (raw.traceability === undefined) {\n traceabilityRaw = undefined;\n } else if (isRecord(raw.traceability)) {\n traceabilityRaw = raw.traceability;\n } else {\n issues.push(\n configIssue(\n configPath,\n \"validation.traceability はオブジェクトである必要があります。\",\n ),\n );\n traceabilityRaw = undefined;\n }\n\n return {\n failOn: readFailOn(\n raw.failOn,\n base.failOn,\n \"validation.failOn\",\n configPath,\n issues,\n ),\n require: {\n specSections: readStringArray(\n requireRaw?.specSections,\n base.require.specSections,\n \"validation.require.specSections\",\n configPath,\n issues,\n ),\n },\n traceability: {\n brMustHaveSc: readBoolean(\n traceabilityRaw?.brMustHaveSc,\n base.traceability.brMustHaveSc,\n \"validation.traceability.brMustHaveSc\",\n configPath,\n issues,\n ),\n scMustHaveTest: readBoolean(\n traceabilityRaw?.scMustHaveTest,\n base.traceability.scMustHaveTest,\n \"validation.traceability.scMustHaveTest\",\n configPath,\n issues,\n ),\n testFileGlobs: readStringArray(\n traceabilityRaw?.testFileGlobs,\n base.traceability.testFileGlobs,\n \"validation.traceability.testFileGlobs\",\n configPath,\n issues,\n ),\n testFileExcludeGlobs: readStringArray(\n traceabilityRaw?.testFileExcludeGlobs,\n base.traceability.testFileExcludeGlobs,\n \"validation.traceability.testFileExcludeGlobs\",\n configPath,\n issues,\n ),\n scNoTestSeverity: readTraceabilitySeverity(\n traceabilityRaw?.scNoTestSeverity,\n base.traceability.scNoTestSeverity,\n \"validation.traceability.scNoTestSeverity\",\n configPath,\n issues,\n ),\n orphanContractsPolicy: readOrphanContractsPolicy(\n traceabilityRaw?.orphanContractsPolicy,\n base.traceability.orphanContractsPolicy,\n \"validation.traceability.orphanContractsPolicy\",\n configPath,\n issues,\n ),\n unknownContractIdSeverity: readTraceabilitySeverity(\n traceabilityRaw?.unknownContractIdSeverity,\n base.traceability.unknownContractIdSeverity,\n \"validation.traceability.unknownContractIdSeverity\",\n configPath,\n issues,\n ),\n },\n };\n}\n\nfunction normalizeOutput(\n raw: unknown,\n configPath: string,\n issues: Issue[],\n): QfaiOutputConfig {\n const base = defaultConfig.output;\n if (!raw) {\n return base;\n }\n if (!isRecord(raw)) {\n issues.push(\n configIssue(configPath, \"output はオブジェクトである必要があります。\"),\n );\n return base;\n }\n\n return {\n validateJsonPath: readString(\n raw.validateJsonPath,\n base.validateJsonPath,\n \"output.validateJsonPath\",\n configPath,\n issues,\n ),\n };\n}\n\nfunction readString(\n value: unknown,\n fallback: string,\n label: string,\n configPath: string,\n issues: Issue[],\n): string {\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readStringArray(\n value: unknown,\n fallback: string[],\n label: string,\n configPath: string,\n issues: Issue[],\n): string[] {\n if (Array.isArray(value) && value.every((item) => typeof item === \"string\")) {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は文字列配列である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readBoolean(\n value: unknown,\n fallback: boolean,\n label: string,\n configPath: string,\n issues: Issue[],\n): boolean {\n if (typeof value === \"boolean\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(configPath, `${label} は真偽値である必要があります。`),\n );\n }\n return fallback;\n}\n\nfunction readFailOn(\n value: unknown,\n fallback: FailOn,\n label: string,\n configPath: string,\n issues: Issue[],\n): FailOn {\n if (value === \"never\" || value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は never|warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction readTraceabilitySeverity(\n value: unknown,\n fallback: TraceabilitySeverity,\n label: string,\n configPath: string,\n issues: Issue[],\n): TraceabilitySeverity {\n if (value === \"warning\" || value === \"error\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は warning|error のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction readOrphanContractsPolicy(\n value: unknown,\n fallback: OrphanContractsPolicy,\n label: string,\n configPath: string,\n issues: Issue[],\n): OrphanContractsPolicy {\n if (value === \"error\" || value === \"warning\" || value === \"allow\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は error|warning|allow のいずれかである必要があります。`,\n ),\n );\n }\n return fallback;\n}\n\nfunction configIssue(file: string, message: string): Issue {\n return {\n code: \"QFAI_CONFIG_INVALID\",\n severity: \"error\",\n message,\n file,\n rule: \"config.invalid\",\n };\n}\n\nfunction isMissingFile(error: unknown): boolean {\n if (error && typeof error === \"object\" && \"code\" in error) {\n return (error as { code?: string }).code === \"ENOENT\";\n }\n return false;\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n","import { access } from \"node:fs/promises\";\n\nimport { collectFiles } from \"./fs.js\";\nimport { collectSpecEntries } from \"./specLayout.js\";\n\nexport type ContractFiles = {\n api: string[];\n ui: string[];\n db: string[];\n};\n\nexport async function collectSpecPackDirs(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return entries.map((entry) => entry.dir);\n}\n\nexport async function collectSpecFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.specPath));\n}\n\nexport async function collectDeltaFiles(specsRoot: string): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.deltaPath));\n}\n\nexport async function collectScenarioFiles(\n specsRoot: string,\n): Promise<string[]> {\n const entries = await collectSpecEntries(specsRoot);\n return filterExisting(entries.map((entry) => entry.scenarioPath));\n}\n\nexport async function collectUiContractFiles(\n uiRoot: string,\n): Promise<string[]> {\n return collectFiles(uiRoot, { extensions: [\".yaml\", \".yml\"] });\n}\n\nexport async function collectApiContractFiles(\n apiRoot: string,\n): Promise<string[]> {\n return collectFiles(apiRoot, { extensions: [\".yaml\", \".yml\", \".json\"] });\n}\n\nexport async function collectDbContractFiles(\n dbRoot: string,\n): Promise<string[]> {\n return collectFiles(dbRoot, { extensions: [\".sql\"] });\n}\n\nexport async function collectContractFiles(\n uiRoot: string,\n apiRoot: string,\n dbRoot: string,\n): Promise<ContractFiles> {\n const [ui, api, db] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDbContractFiles(dbRoot),\n ]);\n return { ui, api, db };\n}\n\nasync function filterExisting(files: string[]): Promise<string[]> {\n const existing: string[] = [];\n for (const file of files) {\n if (await exists(file)) {\n existing.push(file);\n }\n }\n return existing;\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { access, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport fg from \"fast-glob\";\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \".pnpm\",\n \"tmp\",\n \".mcp-tools\",\n]);\n\nexport type CollectFilesOptions = {\n extensions?: string[];\n ignoreDirs?: string[];\n};\n\nexport type CollectFilesByGlobOptions = {\n globs: string[];\n ignore?: string[];\n};\n\nexport async function collectFiles(\n root: string,\n options: CollectFilesOptions = {},\n): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const ignoreDirs = new Set([\n ...DEFAULT_IGNORE_DIRS,\n ...(options.ignoreDirs ?? []),\n ]);\n const extensions = options.extensions?.map((ext) => ext.toLowerCase()) ?? [];\n\n await walk(root, root, ignoreDirs, extensions, entries);\n return entries;\n}\n\nexport async function collectFilesByGlobs(\n root: string,\n options: CollectFilesByGlobOptions,\n): Promise<string[]> {\n if (options.globs.length === 0) {\n return [];\n }\n return fg(options.globs, {\n cwd: root,\n ignore: options.ignore ?? [],\n onlyFiles: true,\n absolute: true,\n unique: true,\n });\n}\n\nasync function walk(\n base: string,\n current: string,\n ignoreDirs: Set<string>,\n extensions: string[],\n out: string[],\n): Promise<void> {\n const items = await readdir(current, { withFileTypes: true });\n\n for (const item of items) {\n const fullPath = path.join(current, item.name);\n\n if (item.isDirectory()) {\n if (ignoreDirs.has(item.name)) {\n continue;\n }\n await walk(base, fullPath, ignoreDirs, extensions, out);\n continue;\n }\n\n if (item.isFile()) {\n if (extensions.length > 0) {\n const ext = path.extname(item.name).toLowerCase();\n if (!extensions.includes(ext)) {\n continue;\n }\n }\n out.push(fullPath);\n }\n }\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst SPEC_DIR_RE = /^spec-\\d{4}$/;\n\nexport type SpecEntry = {\n dir: string;\n specPath: string;\n deltaPath: string;\n scenarioPath: string;\n};\n\nexport async function collectSpecEntries(\n specsRoot: string,\n): Promise<SpecEntry[]> {\n const dirs = await listSpecDirs(specsRoot);\n const entries = dirs.map((dir) => ({\n dir,\n specPath: path.join(dir, \"spec.md\"),\n deltaPath: path.join(dir, \"delta.md\"),\n scenarioPath: path.join(dir, \"scenario.md\"),\n }));\n return entries.sort((a, b) => a.dir.localeCompare(b.dir));\n}\n\nasync function listSpecDirs(specsRoot: string): Promise<string[]> {\n try {\n const items = await readdir(specsRoot, { withFileTypes: true });\n return items\n .filter((item) => item.isDirectory())\n .map((item) => item.name)\n .filter((name) => SPEC_DIR_RE.test(name.toLowerCase()))\n .map((name) => path.join(specsRoot, name));\n } catch (error) {\n if (isMissingFileError(error)) {\n return [];\n }\n throw error;\n }\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import path from \"node:path\";\n\nexport function toRelativePath(root: string, target: string): string {\n if (!target) {\n return target;\n }\n if (!path.isAbsolute(target)) {\n return toPosixPath(target);\n }\n const relative = path.relative(root, target);\n if (!relative) {\n return \".\";\n }\n return toPosixPath(relative);\n}\n\nfunction toPosixPath(value: string): string {\n return value.replace(/\\\\/g, \"/\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { collectFilesByGlobs } from \"./fs.js\";\nimport { parseScenarioDocument } from \"./scenarioModel.js\";\n\nexport const SC_TAG_RE = /^SC-\\d{4}$/;\nexport const SC_TEST_ANNOTATION_RE = /\\bQFAI:SC-(\\d{4})\\b/g;\nexport const DEFAULT_TEST_FILE_EXCLUDE_GLOBS = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/.qfai/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/coverage/**\",\n \"**/.next/**\",\n \"**/out/**\",\n];\n\nexport type ScCoverage = {\n total: number;\n covered: number;\n missing: number;\n missingIds: string[];\n refs: Record<string, string[]>;\n};\n\nexport type TestFileScan = {\n globs: string[];\n excludeGlobs: string[];\n matchedFileCount: number;\n};\n\nexport type ScTestReferenceResult = {\n refs: Map<string, Set<string>>;\n scan: TestFileScan;\n error?: string;\n};\n\nexport function extractAnnotatedScIds(text: string): string[] {\n const ids = new Set<string>();\n for (const match of text.matchAll(SC_TEST_ANNOTATION_RE)) {\n const suffix = match[1];\n if (suffix) {\n ids.add(`SC-${suffix}`);\n }\n }\n return Array.from(ids);\n}\n\nexport async function collectScIdsFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Set<string>> {\n const scIds = new Set<string>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n scIds.add(tag);\n }\n }\n }\n }\n return scIds;\n}\n\nexport async function collectScIdSourcesFromScenarioFiles(\n scenarioFiles: string[],\n): Promise<Map<string, Set<string>>> {\n const sources = new Map<string, Set<string>>();\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (!SC_TAG_RE.test(tag)) {\n continue;\n }\n const current = sources.get(tag) ?? new Set<string>();\n current.add(file);\n sources.set(tag, current);\n }\n }\n }\n return sources;\n}\n\nexport async function collectScTestReferences(\n root: string,\n globs: string[],\n excludeGlobs: string[],\n): Promise<ScTestReferenceResult> {\n const refs = new Map<string, Set<string>>();\n const normalizedGlobs = normalizeGlobs(globs);\n const normalizedExcludeGlobs = normalizeGlobs(excludeGlobs);\n const mergedExcludeGlobs = Array.from(\n new Set([...DEFAULT_TEST_FILE_EXCLUDE_GLOBS, ...normalizedExcludeGlobs]),\n );\n if (normalizedGlobs.length === 0) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n };\n }\n\n let files: string[] = [];\n try {\n files = await collectFilesByGlobs(root, {\n globs: normalizedGlobs,\n ignore: mergedExcludeGlobs,\n });\n } catch (error) {\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: 0,\n },\n error: formatError(error),\n };\n }\n\n const normalizedFiles = Array.from(\n new Set(files.map((file) => path.normalize(file))),\n );\n for (const file of normalizedFiles) {\n const text = await readFile(file, \"utf-8\");\n const scIds = extractAnnotatedScIds(text);\n if (scIds.length === 0) {\n continue;\n }\n for (const scId of scIds) {\n const current = refs.get(scId) ?? new Set<string>();\n current.add(file);\n refs.set(scId, current);\n }\n }\n\n return {\n refs,\n scan: {\n globs: normalizedGlobs,\n excludeGlobs: mergedExcludeGlobs,\n matchedFileCount: normalizedFiles.length,\n },\n };\n}\n\nexport function buildScCoverage(\n scIds: Iterable<string>,\n refs: Map<string, Set<string>>,\n): ScCoverage {\n const sortedScIds = toSortedArray(scIds);\n const refsRecord: Record<string, string[]> = {};\n const missingIds: string[] = [];\n let covered = 0;\n\n for (const scId of sortedScIds) {\n const files = refs.get(scId);\n const sortedFiles = files ? toSortedArray(files) : [];\n refsRecord[scId] = sortedFiles;\n if (sortedFiles.length === 0) {\n missingIds.push(scId);\n } else {\n covered += 1;\n }\n }\n\n return {\n total: sortedScIds.length,\n covered,\n missing: missingIds.length,\n missingIds,\n refs: refsRecord,\n };\n}\n\nfunction toSortedArray(values: Iterable<string>): string[] {\n return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));\n}\n\nfunction normalizeGlobs(globs: string[]): string[] {\n return globs.map((glob) => glob.trim()).filter((glob) => glob.length > 0);\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import {\n AstBuilder,\n GherkinClassicTokenMatcher,\n Parser,\n} from \"@cucumber/gherkin\";\nimport type { GherkinDocument } from \"@cucumber/messages\";\nimport { randomUUID } from \"node:crypto\";\n\nexport type ParsedGherkin = {\n gherkinDocument: GherkinDocument | null;\n errors: string[];\n};\n\nexport function parseGherkin(source: string, uri: string): ParsedGherkin {\n const errors: string[] = [];\n const uuidFn = () => randomUUID();\n const builder = new AstBuilder(uuidFn);\n const matcher = new GherkinClassicTokenMatcher();\n const parser = new Parser(builder, matcher);\n\n try {\n const gherkinDocument = parser.parse(source);\n gherkinDocument.uri = uri;\n return { gherkinDocument, errors };\n } catch (error) {\n errors.push(formatError(error));\n return { gherkinDocument: null, errors };\n }\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n","import type * as Messages from \"@cucumber/messages\";\n\nimport { parseGherkin } from \"./gherkin/parse.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\nexport type ScenarioKind = \"Scenario\" | \"ScenarioOutline\";\n\nexport type ScenarioNode = {\n name: string;\n kind: ScenarioKind;\n line?: number;\n tags: string[];\n steps: readonly Messages.Step[];\n};\n\nexport type ScenarioDocument = {\n uri: string;\n featureName?: string;\n featureTags: string[];\n scenarios: ScenarioNode[];\n};\n\nexport type ScenarioParseResult = {\n document: ScenarioDocument | null;\n errors: string[];\n};\n\nexport type ScenarioAtom = {\n uri: string;\n featureName: string;\n scenarioName: string;\n kind: ScenarioKind;\n specId?: string;\n scId?: string;\n brIds: string[];\n contractIds: string[];\n line?: number;\n};\n\nexport function parseScenarioDocument(\n text: string,\n uri: string,\n): ScenarioParseResult {\n const { gherkinDocument, errors } = parseGherkin(text, uri);\n if (!gherkinDocument) {\n return { document: null, errors };\n }\n\n const feature = gherkinDocument.feature;\n if (!feature) {\n return {\n document: { uri, featureTags: [], scenarios: [] },\n errors,\n };\n }\n\n const featureTags = collectTagNames(feature.tags);\n const scenarios = collectScenarioNodes(feature, featureTags);\n return {\n document: {\n uri,\n featureName: feature.name,\n featureTags,\n scenarios,\n },\n errors,\n };\n}\n\nexport function buildScenarioAtoms(\n document: ScenarioDocument,\n contractIds: string[] = [],\n): ScenarioAtom[] {\n const uniqueContractIds = unique(contractIds).sort((a, b) =>\n a.localeCompare(b),\n );\n return document.scenarios.map((scenario) => {\n const specIds = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const scIds = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n const brIds = unique(scenario.tags.filter((tag) => BR_TAG_RE.test(tag)));\n\n const atom: ScenarioAtom = {\n uri: document.uri,\n featureName: document.featureName ?? \"\",\n scenarioName: scenario.name,\n kind: scenario.kind,\n brIds,\n contractIds: uniqueContractIds,\n };\n\n if (scenario.line !== undefined) {\n atom.line = scenario.line;\n }\n if (specIds.length === 1) {\n const specId = specIds[0];\n if (specId) {\n atom.specId = specId;\n }\n }\n if (scIds.length === 1) {\n const scId = scIds[0];\n if (scId) {\n atom.scId = scId;\n }\n }\n\n return atom;\n });\n}\n\nfunction collectScenarioNodes(\n feature: Messages.Feature,\n featureTags: string[],\n): ScenarioNode[] {\n const scenarios: ScenarioNode[] = [];\n\n for (const child of feature.children) {\n if (child.scenario) {\n scenarios.push(buildScenarioNode(child.scenario, featureTags, []));\n }\n if (child.rule) {\n const ruleTags = collectTagNames(child.rule.tags);\n for (const ruleChild of child.rule.children) {\n if (ruleChild.scenario) {\n scenarios.push(\n buildScenarioNode(ruleChild.scenario, featureTags, ruleTags),\n );\n }\n }\n }\n }\n\n return scenarios;\n}\n\nfunction buildScenarioNode(\n scenario: Messages.Scenario,\n featureTags: string[],\n ruleTags: string[],\n): ScenarioNode {\n const tags = [...featureTags, ...ruleTags, ...collectTagNames(scenario.tags)];\n const kind: ScenarioKind =\n scenario.examples.length > 0 ? \"ScenarioOutline\" : \"Scenario\";\n return {\n name: scenario.name,\n kind,\n line: scenario.location?.line,\n tags,\n steps: scenario.steps,\n };\n}\n\nfunction collectTagNames(tags: readonly Messages.Tag[]): string[] {\n return tags.map((tag) => tag.name.replace(/^@/, \"\"));\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\ndeclare const __QFAI_TOOL_VERSION__: string | undefined;\n\nexport async function resolveToolVersion(): Promise<string> {\n if (\n typeof __QFAI_TOOL_VERSION__ === \"string\" &&\n __QFAI_TOOL_VERSION__.length > 0\n ) {\n return __QFAI_TOOL_VERSION__;\n }\n\n try {\n const packagePath = resolvePackageJsonPath();\n const raw = await readFile(packagePath, \"utf-8\");\n const parsed = JSON.parse(raw) as { version?: unknown };\n const version = typeof parsed.version === \"string\" ? parsed.version : \"\";\n return version.length > 0 ? version : \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction resolvePackageJsonPath(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n return path.resolve(path.dirname(basePath), \"../../package.json\");\n}\n","export function info(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function warn(message: string): void {\n process.stdout.write(`${message}\\n`);\n}\n\nexport function error(message: string): void {\n process.stderr.write(`${message}\\n`);\n}\n","import path from \"node:path\";\n\nimport { copyTemplateTree } from \"../lib/fs.js\";\nimport { getInitAssetsDir } from \"../lib/assets.js\";\nimport { info } from \"../lib/logger.js\";\n\nexport type InitOptions = {\n dir: string;\n force: boolean;\n dryRun: boolean;\n yes: boolean;\n};\n\nexport async function runInit(options: InitOptions): Promise<void> {\n const assetsRoot = getInitAssetsDir();\n const rootAssets = path.join(assetsRoot, \"root\");\n const qfaiAssets = path.join(assetsRoot, \".qfai\");\n\n const destRoot = path.resolve(options.dir);\n const destQfai = path.join(destRoot, \".qfai\");\n\n const rootResult = await copyTemplateTree(rootAssets, destRoot, {\n force: options.force,\n dryRun: options.dryRun,\n });\n const qfaiResult = await copyTemplateTree(qfaiAssets, destQfai, {\n force: options.force,\n dryRun: options.dryRun,\n protect: [\"prompts.local\"],\n });\n\n report(\n [...rootResult.copied, ...qfaiResult.copied],\n [...rootResult.skipped, ...qfaiResult.skipped],\n options.dryRun,\n \"init\",\n );\n}\n\nfunction report(\n copied: string[],\n skipped: string[],\n dryRun: boolean,\n label: string,\n): void {\n info(`qfai ${label}: ${dryRun ? \"dry-run\" : \"done\"}`);\n if (copied.length > 0) {\n info(` created: ${copied.length}`);\n }\n if (skipped.length > 0) {\n info(` skipped: ${skipped.length}`);\n }\n}\n","import { access, copyFile, mkdir, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type CopyOptions = {\n force: boolean;\n dryRun: boolean;\n /**\n * Protect specific relative paths from overwriting.\n * - Even when force=true, existing files under these paths are never overwritten.\n * - When force=false, existing files under these paths do not block the copy.\n */\n protect?: string[];\n};\n\nexport type CopyResult = {\n copied: string[];\n skipped: string[];\n};\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const files = await collectTemplateFiles(sourceRoot);\n return copyFiles(files, sourceRoot, destRoot, options);\n}\n\nexport async function copyTemplatePaths(\n sourceRoot: string,\n destRoot: string,\n relativePaths: string[],\n options: CopyOptions,\n): Promise<CopyResult> {\n const allFiles: string[] = [];\n for (const relPath of relativePaths) {\n const fullPath = path.join(sourceRoot, relPath);\n const files = await collectTemplateFiles(fullPath);\n allFiles.push(...files);\n }\n\n return copyFiles(allFiles, sourceRoot, destRoot, options);\n}\n\nasync function copyFiles(\n files: string[],\n sourceRoot: string,\n destRoot: string,\n options: CopyOptions,\n): Promise<CopyResult> {\n const copied: string[] = [];\n const skipped: string[] = [];\n const conflicts: string[] = [];\n\n const protectPrefixes = (options.protect ?? [])\n .map((p) => p.replace(/^[\\\\/]+/, \"\").replace(/[\\\\/]+$/, \"\"))\n .filter((p) => p.length > 0)\n .map((p) => p + path.sep);\n\n const isProtectedRelative = (relative: string): boolean => {\n if (protectPrefixes.length === 0) {\n return false;\n }\n const normalized = relative.replace(/[\\\\/]+/g, path.sep);\n return protectPrefixes.some(\n (prefix) =>\n normalized === prefix.slice(0, -1) || normalized.startsWith(prefix),\n );\n };\n\n if (!options.force) {\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n if (isProtectedRelative(relative)) {\n continue;\n }\n const dest = path.join(destRoot, relative);\n if (!(await shouldWrite(dest, options.force))) {\n conflicts.push(dest);\n }\n }\n\n if (conflicts.length > 0) {\n throw new Error(formatConflictMessage(conflicts));\n }\n }\n\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\n const dest = path.join(destRoot, relative);\n\n const forceForThisFile = isProtectedRelative(relative)\n ? false\n : options.force;\n\n if (!(await shouldWrite(dest, forceForThisFile))) {\n skipped.push(dest);\n continue;\n }\n\n if (!options.dryRun) {\n await mkdir(path.dirname(dest), { recursive: true });\n await copyFile(file, dest);\n }\n copied.push(dest);\n }\n\n return { copied, skipped };\n}\n\nfunction formatConflictMessage(conflicts: string[]): string {\n return [\n \"既存ファイルと衝突しました。安全のため停止します。\",\n \"\",\n \"衝突ファイル:\",\n ...conflicts.map((conflict) => `- ${conflict}`),\n \"\",\n \"上書きして続行する場合は --force を付けて再実行してください。\",\n ].join(\"\\n\");\n}\n\nasync function collectTemplateFiles(root: string): Promise<string[]> {\n const entries: string[] = [];\n if (!(await exists(root))) {\n return entries;\n }\n\n const items = await readdir(root, { withFileTypes: true });\n for (const item of items) {\n const fullPath = path.join(root, item.name);\n if (item.isDirectory()) {\n const nested = await collectTemplateFiles(fullPath);\n entries.push(...nested);\n continue;\n }\n if (item.isFile()) {\n entries.push(fullPath);\n }\n }\n\n return entries;\n}\n\nasync function shouldWrite(target: string, force: boolean): Promise<boolean> {\n if (force) {\n return true;\n }\n return !(await exists(target));\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await access(target);\n return true;\n } catch {\n return false;\n }\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport function getInitAssetsDir(): string {\n const base = import.meta.url;\n const basePath = base.startsWith(\"file:\") ? fileURLToPath(base) : base;\n const baseDir = path.dirname(basePath);\n // src/cli/lib と dist/cli/lib からの解決を想定する。\n const candidates = [\n path.resolve(baseDir, \"../../../assets/init\"),\n path.resolve(baseDir, \"../../assets/init\"),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(\n [\n \"init 用テンプレートが見つかりません。Template assets not found.\",\n \"確認したパス / Checked paths:\",\n ...candidates.map((candidate) => `- ${candidate}`),\n ].join(\"\\n\"),\n );\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { loadConfig, resolvePath } from \"../../core/config.js\";\nimport { normalizeValidationResult } from \"../../core/normalize.js\";\nimport {\n createReportData,\n formatReportJson,\n formatReportMarkdown,\n} from \"../../core/report.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\nimport { validateProject } from \"../../core/validate.js\";\nimport { error, info, warn } from \"../lib/logger.js\";\n\nexport type ReportOptions = {\n root: string;\n format: \"md\" | \"json\";\n outPath?: string;\n inputPath?: string;\n runValidate?: boolean;\n};\n\nexport async function runReport(options: ReportOptions): Promise<void> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n let validation: ValidationResult;\n if (options.runValidate) {\n if (options.inputPath) {\n warn(\"report: --run-validate が指定されたため --in は無視します。\");\n }\n const result = await validateProject(root, configResult);\n const normalized = normalizeValidationResult(root, result);\n await writeValidationResult(\n root,\n configResult.config.output.validateJsonPath,\n normalized,\n );\n validation = normalized;\n } else {\n const input =\n options.inputPath ?? configResult.config.output.validateJsonPath;\n const inputPath = path.isAbsolute(input)\n ? input\n : path.resolve(root, input);\n try {\n validation = await readValidationResult(inputPath);\n } catch (err) {\n if (isMissingFileError(err)) {\n error(\n [\n `qfai report: 入力ファイルが見つかりません: ${inputPath}`,\n \"\",\n \"まず qfai validate を実行してください。例:\",\n \" qfai validate\",\n \"(デフォルトの出力先: .qfai/out/validate.json)\",\n \"\",\n \"または report に --run-validate を指定してください。\",\n \"GitHub Actions テンプレを使っている場合は、workflow の validate ジョブを先に実行してください。\",\n ].join(\"\\n\"),\n );\n process.exitCode = 2;\n return;\n }\n throw err;\n }\n }\n\n const data = await createReportData(root, validation, configResult);\n const output =\n options.format === \"json\"\n ? formatReportJson(data)\n : formatReportMarkdown(data);\n\n const outRoot = resolvePath(root, configResult.config, \"outDir\");\n const defaultOut =\n options.format === \"json\"\n ? path.join(outRoot, \"report.json\")\n : path.join(outRoot, \"report.md\");\n const out = options.outPath ?? defaultOut;\n const outPath = path.isAbsolute(out) ? out : path.resolve(root, out);\n\n await mkdir(path.dirname(outPath), { recursive: true });\n await writeFile(outPath, `${output}\\n`, \"utf-8\");\n\n info(\n `report: info=${validation.counts.info} warning=${validation.counts.warning} error=${validation.counts.error}`,\n );\n info(`wrote report: ${outPath}`);\n}\n\nasync function readValidationResult(\n inputPath: string,\n): Promise<ValidationResult> {\n const raw = await readFile(inputPath, \"utf-8\");\n const parsed = JSON.parse(raw) as unknown;\n if (!isValidationResult(parsed)) {\n throw new Error(`validate.json の形式が不正です: ${inputPath}`);\n }\n return parsed;\n}\n\nfunction isValidationResult(value: unknown): value is ValidationResult {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.toolVersion !== \"string\") {\n return false;\n }\n if (!Array.isArray(record.issues)) {\n return false;\n }\n const counts = record.counts as Record<string, unknown> | undefined;\n if (!counts) {\n return false;\n }\n if (\n typeof counts.info !== \"number\" ||\n typeof counts.warning !== \"number\" ||\n typeof counts.error !== \"number\"\n ) {\n return false;\n }\n\n const traceability = record.traceability as\n | Record<string, unknown>\n | undefined;\n if (!traceability || typeof traceability !== \"object\") {\n return false;\n }\n\n const sc = traceability.sc as Record<string, unknown> | undefined;\n const testFiles = traceability.testFiles as\n | Record<string, unknown>\n | undefined;\n if (!sc || !testFiles) {\n return false;\n }\n if (\n typeof sc.total !== \"number\" ||\n typeof sc.covered !== \"number\" ||\n typeof sc.missing !== \"number\"\n ) {\n return false;\n }\n if (!Array.isArray(sc.missingIds)) {\n return false;\n }\n if (!sc.refs || typeof sc.refs !== \"object\") {\n return false;\n }\n if (\n !Array.isArray(testFiles.globs) ||\n !Array.isArray(testFiles.excludeGlobs) ||\n typeof testFiles.matchedFileCount !== \"number\"\n ) {\n return false;\n }\n\n return true;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n const record = error as { code?: string };\n return record.code === \"ENOENT\";\n}\n\nasync function writeValidationResult(\n root: string,\n outputPath: string,\n result: ValidationResult,\n): Promise<void> {\n const abs = path.isAbsolute(outputPath)\n ? outputPath\n : path.resolve(root, outputPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\n","import type { ScCoverage } from \"./traceability.js\";\nimport type { Issue, ValidationResult } from \"./types.js\";\nimport { toRelativePath } from \"./paths.js\";\n\nexport function normalizeIssuePaths(root: string, issues: Issue[]): Issue[] {\n return issues.map((issue) => {\n if (!issue.file) {\n return issue;\n }\n const normalized = toRelativePath(root, issue.file);\n if (normalized === issue.file) {\n return issue;\n }\n return {\n ...issue,\n file: normalized,\n };\n });\n}\n\nexport function normalizeScCoverage(root: string, sc: ScCoverage): ScCoverage {\n const refs: Record<string, string[]> = {};\n for (const [scId, files] of Object.entries(sc.refs)) {\n refs[scId] = files.map((file) => toRelativePath(root, file));\n }\n return {\n ...sc,\n refs,\n };\n}\n\nexport function normalizeValidationResult(\n root: string,\n result: ValidationResult,\n): ValidationResult {\n return {\n ...result,\n issues: normalizeIssuePaths(root, result.issues),\n traceability: {\n ...result.traceability,\n sc: normalizeScCoverage(root, result.traceability.sc),\n },\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { buildContractIndex } from \"./contractIndex.js\";\nimport { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport {\n collectContractFiles,\n collectScenarioFiles,\n collectSpecFiles,\n} from \"./discovery.js\";\nimport { collectFiles } from \"./fs.js\";\nimport { extractAllIds, extractIds, type IdPrefix } from \"./ids.js\";\nimport { normalizeValidationResult } from \"./normalize.js\";\nimport { parseSpec } from \"./parse/spec.js\";\nimport { toRelativePath } from \"./paths.js\";\nimport {\n collectScIdSourcesFromScenarioFiles,\n type ScCoverage,\n type TestFileScan,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { validateProject } from \"./validate.js\";\nimport { resolveToolVersion } from \"./version.js\";\n\nexport type ReportSummary = {\n specs: number;\n scenarios: number;\n contracts: {\n api: number;\n ui: number;\n db: number;\n };\n counts: ValidationCounts;\n};\n\nexport type ReportIds = {\n spec: string[];\n br: string[];\n sc: string[];\n ui: string[];\n api: string[];\n db: string[];\n};\n\nexport type ReportContractCoverage = {\n total: number;\n referenced: number;\n orphan: number;\n idToSpecs: Record<string, string[]>;\n};\n\nexport type ReportSpecCoverage = {\n contractRefMissing: number;\n missingRefSpecs: string[];\n specToContracts: Record<string, ReportSpecContractRefs>;\n};\n\nexport type ReportSpecContractRefs = {\n status: \"missing\" | \"declared\";\n ids: string[];\n};\n\nexport type ReportTraceability = {\n upstreamIdsFound: number;\n referencedInCodeOrTests: boolean;\n sc: ScCoverage;\n scSources: Record<string, string[]>;\n testFiles: TestFileScan;\n contracts: ReportContractCoverage;\n specs: ReportSpecCoverage;\n};\n\nexport type ReportData = {\n tool: \"qfai\";\n version: string;\n generatedAt: string;\n root: string;\n configPath: string;\n summary: ReportSummary;\n ids: ReportIds;\n traceability: ReportTraceability;\n issues: Issue[];\n};\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DB\"];\n\nexport async function createReportData(\n root: string,\n validation?: ValidationResult,\n configResult?: ConfigLoadResult,\n): Promise<ReportData> {\n const resolvedRoot = path.resolve(root);\n const resolved = configResult ?? (await loadConfig(resolvedRoot));\n const config = resolved.config;\n const configPath = resolved.configPath;\n\n const specsRoot = resolvePath(resolvedRoot, config, \"specsDir\");\n const contractsRoot = resolvePath(resolvedRoot, config, \"contractsDir\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const dbRoot = path.join(contractsRoot, \"db\");\n const srcRoot = resolvePath(resolvedRoot, config, \"srcDir\");\n const testsRoot = resolvePath(resolvedRoot, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const {\n api: apiFiles,\n ui: uiFiles,\n db: dbFiles,\n } = await collectContractFiles(uiRoot, apiRoot, dbRoot);\n const contractIndex = await buildContractIndex(resolvedRoot, config);\n const contractIdList = Array.from(contractIndex.ids);\n const specContractRefs = await collectSpecContractRefs(\n specFiles,\n contractIdList,\n );\n const referencedContracts = new Set<string>();\n for (const entry of specContractRefs.specToContracts.values()) {\n entry.ids.forEach((id) => referencedContracts.add(id));\n }\n const referencedContractCount = contractIdList.filter((id) =>\n referencedContracts.has(id),\n ).length;\n const orphanContractCount = contractIdList.filter(\n (id) => !referencedContracts.has(id),\n ).length;\n const contractIdToSpecsRecord = mapToSortedRecord(specContractRefs.idToSpecs);\n const specToContractsRecord = mapToSpecContractRecord(\n specContractRefs.specToContracts,\n );\n\n const idsByPrefix = await collectIds([\n ...specFiles,\n ...scenarioFiles,\n ...apiFiles,\n ...uiFiles,\n ...dbFiles,\n ]);\n\n const upstreamIds = await collectUpstreamIds([\n ...specFiles,\n ...scenarioFiles,\n ]);\n const traceability = await evaluateTraceability(\n upstreamIds,\n srcRoot,\n testsRoot,\n );\n const resolvedValidationRaw =\n validation ?? (await validateProject(resolvedRoot, resolved));\n const normalizedValidation = normalizeValidationResult(\n resolvedRoot,\n resolvedValidationRaw,\n );\n const scCoverage = normalizedValidation.traceability.sc;\n const testFiles = normalizedValidation.traceability.testFiles;\n const scSources = await collectScIdSourcesFromScenarioFiles(scenarioFiles);\n const scSourceRecord = mapToSortedRecord(\n normalizeScSources(resolvedRoot, scSources),\n );\n\n const version = await resolveToolVersion();\n const displayRoot = toRelativePath(resolvedRoot, resolvedRoot);\n const displayConfigPath = toRelativePath(resolvedRoot, configPath);\n\n return {\n tool: \"qfai\",\n version,\n generatedAt: new Date().toISOString(),\n root: displayRoot,\n configPath: displayConfigPath,\n summary: {\n specs: specFiles.length,\n scenarios: scenarioFiles.length,\n contracts: {\n api: apiFiles.length,\n ui: uiFiles.length,\n db: dbFiles.length,\n },\n counts: normalizedValidation.counts,\n },\n ids: {\n spec: idsByPrefix.SPEC,\n br: idsByPrefix.BR,\n sc: idsByPrefix.SC,\n ui: idsByPrefix.UI,\n api: idsByPrefix.API,\n db: idsByPrefix.DB,\n },\n traceability: {\n upstreamIdsFound: upstreamIds.size,\n referencedInCodeOrTests: traceability,\n sc: scCoverage,\n scSources: scSourceRecord,\n testFiles,\n contracts: {\n total: contractIdList.length,\n referenced: referencedContractCount,\n orphan: orphanContractCount,\n idToSpecs: contractIdToSpecsRecord,\n },\n specs: {\n contractRefMissing: specContractRefs.missingRefSpecs.size,\n missingRefSpecs: toSortedArray(specContractRefs.missingRefSpecs),\n specToContracts: specToContractsRecord,\n },\n },\n issues: normalizedValidation.issues,\n };\n}\n\nexport function formatReportMarkdown(data: ReportData): string {\n const lines: string[] = [];\n\n lines.push(\"# QFAI Report\");\n lines.push(\"\");\n lines.push(`- 生成日時: ${data.generatedAt}`);\n lines.push(`- ルート: ${data.root}`);\n lines.push(`- 設定: ${data.configPath}`);\n lines.push(`- 版: ${data.version}`);\n lines.push(\"\");\n\n lines.push(\"## Summary\");\n lines.push(\"\");\n lines.push(`- specs: ${data.summary.specs}`);\n lines.push(`- scenarios: ${data.summary.scenarios}`);\n lines.push(\n `- contracts: api ${data.summary.contracts.api} / ui ${data.summary.contracts.ui} / db ${data.summary.contracts.db}`,\n );\n lines.push(\n `- issues: info ${data.summary.counts.info} / warning ${data.summary.counts.warning} / error ${data.summary.counts.error}`,\n );\n lines.push(\n `- fail-on=error: ${data.summary.counts.error > 0 ? \"FAIL\" : \"PASS\"}`,\n );\n lines.push(\n `- fail-on=warning: ${data.summary.counts.error + data.summary.counts.warning > 0 ? \"FAIL\" : \"PASS\"}`,\n );\n lines.push(\"\");\n\n lines.push(\"## Findings\");\n lines.push(\"\");\n\n lines.push(\"### Issues (by code)\");\n lines.push(\"\");\n const severityOrder: Record<string, number> = {\n error: 0,\n warning: 1,\n info: 2,\n };\n const issueKeyToCount = new Map<\n string,\n { severity: string; code: string; count: number }\n >();\n for (const issue of data.issues) {\n const key = `${issue.severity}|${issue.code}`;\n const current = issueKeyToCount.get(key);\n if (current) {\n current.count += 1;\n continue;\n }\n issueKeyToCount.set(key, {\n severity: issue.severity,\n code: issue.code,\n count: 1,\n });\n }\n const issueSummaryRows = Array.from(issueKeyToCount.values())\n .sort((a, b) => {\n const sa = severityOrder[a.severity] ?? 999;\n const sb = severityOrder[b.severity] ?? 999;\n if (sa !== sb) return sa - sb;\n return a.code.localeCompare(b.code);\n })\n .map((x) => [x.severity, x.code, String(x.count)]);\n if (issueSummaryRows.length === 0) {\n lines.push(\"- (none)\");\n } else {\n lines.push(\n ...formatMarkdownTable([\"Severity\", \"Code\", \"Count\"], issueSummaryRows),\n );\n }\n lines.push(\"\");\n\n lines.push(\"### Issues (list)\");\n lines.push(\"\");\n if (data.issues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n const sortedIssues = [...data.issues].sort((a, b) => {\n const sa = severityOrder[a.severity] ?? 999;\n const sb = severityOrder[b.severity] ?? 999;\n if (sa !== sb) return sa - sb;\n const code = a.code.localeCompare(b.code);\n if (code !== 0) return code;\n const fileA = a.file ?? \"\";\n const fileB = b.file ?? \"\";\n const file = fileA.localeCompare(fileB);\n if (file !== 0) return file;\n const lineA = a.loc?.line ?? 0;\n const lineB = b.loc?.line ?? 0;\n return lineA - lineB;\n });\n\n for (const item of sortedIssues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n lines.push(\n `- ${item.severity.toUpperCase()} [${item.code}] ${item.message}${location}${refs}`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"### IDs\");\n lines.push(\"\");\n lines.push(formatIdLine(\"SPEC\", data.ids.spec));\n lines.push(formatIdLine(\"BR\", data.ids.br));\n lines.push(formatIdLine(\"SC\", data.ids.sc));\n lines.push(formatIdLine(\"UI\", data.ids.ui));\n lines.push(formatIdLine(\"API\", data.ids.api));\n lines.push(formatIdLine(\"DB\", data.ids.db));\n lines.push(\"\");\n\n lines.push(\"### Traceability\");\n lines.push(\"\");\n lines.push(`- 上流ID検出数: ${data.traceability.upstreamIdsFound}`);\n lines.push(\n `- コード/テスト参照: ${data.traceability.referencedInCodeOrTests ? \"あり\" : \"なし\"}`,\n );\n lines.push(\"\");\n\n lines.push(\"### Contract Coverage\");\n lines.push(\"\");\n lines.push(`- total: ${data.traceability.contracts.total}`);\n lines.push(`- referenced: ${data.traceability.contracts.referenced}`);\n lines.push(`- orphan: ${data.traceability.contracts.orphan}`);\n lines.push(\n `- specContractRefMissing: ${data.traceability.specs.contractRefMissing}`,\n );\n lines.push(\"\");\n\n lines.push(\"### Contract → Spec\");\n lines.push(\"\");\n const contractToSpecs = data.traceability.contracts.idToSpecs;\n const contractIds = Object.keys(contractToSpecs).sort((a, b) =>\n a.localeCompare(b),\n );\n if (contractIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const contractId of contractIds) {\n const specs = contractToSpecs[contractId] ?? [];\n if (specs.length === 0) {\n lines.push(`- ${contractId}: (none)`);\n } else {\n lines.push(`- ${contractId}: ${specs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"### Spec → Contracts\");\n lines.push(\"\");\n const specToContracts = data.traceability.specs.specToContracts;\n const specIds = Object.keys(specToContracts).sort((a, b) =>\n a.localeCompare(b),\n );\n if (specIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n const rows = specIds.map((specId) => {\n const entry = specToContracts[specId];\n const contracts =\n entry?.status === \"missing\"\n ? \"(missing)\"\n : entry && entry.ids.length > 0\n ? entry.ids.join(\", \")\n : \"(none)\";\n const status = entry?.status ?? \"missing\";\n return [specId, status, contracts];\n });\n lines.push(...formatMarkdownTable([\"Spec\", \"Status\", \"Contracts\"], rows));\n }\n lines.push(\"\");\n\n lines.push(\"### Specs missing contract-ref\");\n lines.push(\"\");\n const missingRefSpecs = data.traceability.specs.missingRefSpecs;\n if (missingRefSpecs.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const specId of missingRefSpecs) {\n lines.push(`- ${specId}`);\n }\n }\n lines.push(\"\");\n\n lines.push(\"### SC coverage\");\n lines.push(\"\");\n lines.push(`- total: ${data.traceability.sc.total}`);\n lines.push(`- covered: ${data.traceability.sc.covered}`);\n lines.push(`- missing: ${data.traceability.sc.missing}`);\n lines.push(\n `- testFileGlobs: ${formatList(data.traceability.testFiles.globs)}`,\n );\n lines.push(\n `- testFileExcludeGlobs: ${formatList(\n data.traceability.testFiles.excludeGlobs,\n )}`,\n );\n lines.push(\n `- testFileCount: ${data.traceability.testFiles.matchedFileCount}`,\n );\n if (data.traceability.sc.missingIds.length === 0) {\n lines.push(\"- missingIds: (none)\");\n } else {\n const sources = data.traceability.scSources;\n const missingWithSources = data.traceability.sc.missingIds.map((id) => {\n const files = sources[id] ?? [];\n if (files.length === 0) {\n return id;\n }\n return `${id} (${files.join(\", \")})`;\n });\n lines.push(`- missingIds: ${missingWithSources.join(\", \")}`);\n }\n lines.push(\"\");\n\n lines.push(\"### SC → referenced tests\");\n lines.push(\"\");\n const scRefs = data.traceability.sc.refs;\n const scIds = Object.keys(scRefs).sort((a, b) => a.localeCompare(b));\n if (scIds.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const scId of scIds) {\n const refs = scRefs[scId] ?? [];\n if (refs.length === 0) {\n lines.push(`- ${scId}: (none)`);\n } else {\n lines.push(`- ${scId}: ${refs.join(\", \")}`);\n }\n }\n }\n lines.push(\"\");\n\n lines.push(\"### Spec:SC=1:1 violations\");\n lines.push(\"\");\n const specScIssues = data.issues.filter(\n (item) => item.code === \"QFAI-TRACE-012\",\n );\n if (specScIssues.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const item of specScIssues) {\n const location = item.file ?? \"(unknown)\";\n const refs =\n item.refs && item.refs.length > 0 ? item.refs.join(\", \") : item.message;\n lines.push(`- ${location}: ${refs}`);\n }\n }\n lines.push(\"\");\n\n lines.push(\"### Hotspots\");\n lines.push(\"\");\n const hotspots = buildHotspots(data.issues);\n if (hotspots.length === 0) {\n lines.push(\"- (none)\");\n } else {\n for (const spot of hotspots) {\n lines.push(\n `- ${spot.file}: total ${spot.total} (error ${spot.error} / warning ${spot.warning} / info ${spot.info})`,\n );\n }\n }\n lines.push(\"\");\n\n lines.push(\"## Guidance\");\n lines.push(\"\");\n\n lines.push(\n \"- 次の手順: `qfai doctor --fail-on error` → `qfai validate --fail-on error` → `qfai report`\",\n );\n if (data.summary.counts.error > 0) {\n lines.push(\"- error があるため、まず error から修正してください。\");\n } else if (data.summary.counts.warning > 0) {\n lines.push(\n \"- warning の扱い(Hard Gate にするか)は運用で決めてください。\",\n );\n } else {\n lines.push(\n \"- issue は検出されませんでした。運用テンプレに沿って継続してください。\",\n );\n }\n lines.push(\n \"- 変更区分(Compatibility / Change/Improvement)は `.qfai/specs/*/delta.md` に記録します。\",\n );\n lines.push(\n \"- 参照ルールの正本: `.qfai/promptpack/steering/traceability.md` / `.qfai/promptpack/steering/compatibility-vs-change.md`\",\n );\n\n return lines.join(\"\\n\");\n}\n\nexport function formatReportJson(data: ReportData): string {\n return JSON.stringify(data, null, 2);\n}\n\ntype SpecContractRefsResult = {\n specToContracts: Map<string, SpecContractRefEntry>;\n idToSpecs: Map<string, Set<string>>;\n missingRefSpecs: Set<string>;\n};\n\ntype SpecContractRefEntry = {\n status: \"missing\" | \"declared\";\n ids: Set<string>;\n};\n\nasync function collectSpecContractRefs(\n specFiles: string[],\n contractIdList: string[],\n): Promise<SpecContractRefsResult> {\n const specToContracts = new Map<string, SpecContractRefEntry>();\n const idToSpecs = new Map<string, Set<string>>();\n const missingRefSpecs = new Set<string>();\n\n for (const contractId of contractIdList) {\n idToSpecs.set(contractId, new Set<string>());\n }\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n const specKey = parsed.specId;\n if (!specKey) {\n continue;\n }\n const refs = parsed.contractRefs;\n\n if (refs.lines.length === 0) {\n missingRefSpecs.add(specKey);\n specToContracts.set(specKey, { status: \"missing\", ids: new Set() });\n continue;\n }\n\n const current =\n specToContracts.get(specKey) ??\n ({\n status: \"declared\",\n ids: new Set<string>(),\n } satisfies SpecContractRefEntry);\n for (const id of refs.ids) {\n current.ids.add(id);\n const specs = idToSpecs.get(id);\n if (specs) {\n specs.add(specKey);\n }\n }\n specToContracts.set(specKey, current);\n }\n\n return {\n specToContracts,\n idToSpecs,\n missingRefSpecs,\n };\n}\n\nasync function collectIds(\n files: string[],\n): Promise<Record<IdPrefix, string[]>> {\n const result: Record<IdPrefix, Set<string>> = {\n SPEC: new Set(),\n BR: new Set(),\n SC: new Set(),\n UI: new Set(),\n API: new Set(),\n DB: new Set(),\n };\n\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n for (const prefix of ID_PREFIXES) {\n const ids = extractIds(text, prefix);\n ids.forEach((id) => result[prefix].add(id));\n }\n }\n\n return {\n SPEC: toSortedArray(result.SPEC),\n BR: toSortedArray(result.BR),\n SC: toSortedArray(result.SC),\n UI: toSortedArray(result.UI),\n API: toSortedArray(result.API),\n DB: toSortedArray(result.DB),\n };\n}\n\nasync function collectUpstreamIds(files: string[]): Promise<Set<string>> {\n const ids = new Set<string>();\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => ids.add(id));\n }\n return ids;\n}\n\nasync function evaluateTraceability(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<boolean> {\n if (upstreamIds.size === 0) {\n return false;\n }\n\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n return false;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction formatIdLine(label: string, values: string[]): string {\n if (values.length === 0) {\n return `- ${label}: (none)`;\n }\n return `- ${label}: ${values.join(\", \")}`;\n}\n\nfunction formatList(values: string[]): string {\n if (values.length === 0) {\n return \"(none)\";\n }\n return values.join(\", \");\n}\n\nfunction formatMarkdownTable(headers: string[], rows: string[][]): string[] {\n const widths = headers.map((header, index) => {\n const candidates = rows.map((row) => row[index] ?? \"\");\n return Math.max(header.length, ...candidates.map((item) => item.length));\n });\n\n const formatRow = (cells: string[]): string => {\n const padded = cells.map((cell, index) =>\n (cell ?? \"\").padEnd(widths[index] ?? 0),\n );\n return `| ${padded.join(\" | \")} |`;\n };\n\n const separator = `| ${widths.map((width) => \"-\".repeat(width)).join(\" | \")} |`;\n\n return [formatRow(headers), separator, ...rows.map(formatRow)];\n}\n\nfunction toSortedArray(values: Set<string>): string[] {\n return Array.from(values).sort((a, b) => a.localeCompare(b));\n}\n\nfunction mapToSortedRecord(\n values: Map<string, Set<string>>,\n): Record<string, string[]> {\n const record: Record<string, string[]> = {};\n for (const [key, files] of values.entries()) {\n record[key] = Array.from(files).sort((a, b) => a.localeCompare(b));\n }\n return record;\n}\n\nfunction mapToSpecContractRecord(\n values: Map<string, SpecContractRefEntry>,\n): Record<string, ReportSpecContractRefs> {\n const record: Record<string, ReportSpecContractRefs> = {};\n for (const [key, entry] of values.entries()) {\n record[key] = {\n status: entry.status,\n ids: toSortedArray(entry.ids),\n };\n }\n return record;\n}\n\nfunction normalizeScSources(\n root: string,\n sources: Map<string, Set<string>>,\n): Map<string, Set<string>> {\n const normalized = new Map<string, Set<string>>();\n for (const [id, files] of sources.entries()) {\n const mapped = new Set<string>();\n for (const file of files) {\n mapped.add(toRelativePath(root, file));\n }\n normalized.set(id, mapped);\n }\n return normalized;\n}\n\ntype Hotspot = {\n file: string;\n total: number;\n error: number;\n warning: number;\n info: number;\n};\n\nfunction buildHotspots(issues: Issue[]): Hotspot[] {\n const map = new Map<string, Hotspot>();\n for (const issue of issues) {\n if (!issue.file) {\n continue;\n }\n const current =\n map.get(issue.file) ??\n ({\n file: issue.file,\n total: 0,\n error: 0,\n warning: 0,\n info: 0,\n } satisfies Hotspot);\n current.total += 1;\n current[issue.severity] += 1;\n map.set(issue.file, current);\n }\n\n return Array.from(map.values()).sort((a, b) =>\n b.total !== a.total ? b.total - a.total : a.file.localeCompare(b.file),\n );\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"./config.js\";\nimport { resolvePath } from \"./config.js\";\nimport {\n collectApiContractFiles,\n collectDbContractFiles,\n collectUiContractFiles,\n} from \"./discovery.js\";\nimport { extractDeclaredContractIds } from \"./contractsDecl.js\";\n\nexport type ContractIndex = {\n ids: Set<string>;\n idToFiles: Map<string, Set<string>>;\n files: { ui: string[]; api: string[]; db: string[] };\n};\n\nexport async function buildContractIndex(\n root: string,\n config: QfaiConfig,\n): Promise<ContractIndex> {\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n const uiRoot = path.join(contractsRoot, \"ui\");\n const apiRoot = path.join(contractsRoot, \"api\");\n const dbRoot = path.join(contractsRoot, \"db\");\n\n const [uiFiles, apiFiles, dbFiles] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDbContractFiles(dbRoot),\n ]);\n\n const index: ContractIndex = {\n ids: new Set<string>(),\n idToFiles: new Map<string, Set<string>>(),\n files: { ui: uiFiles, api: apiFiles, db: dbFiles },\n };\n\n await indexContractFiles(uiFiles, index);\n await indexContractFiles(apiFiles, index);\n await indexContractFiles(dbFiles, index);\n\n return index;\n}\n\nasync function indexContractFiles(\n files: string[],\n index: ContractIndex,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n extractDeclaredContractIds(text).forEach((id) => record(index, id, file));\n }\n}\n\nfunction record(index: ContractIndex, id: string, file: string): void {\n index.ids.add(id);\n const current = index.idToFiles.get(id) ?? new Set<string>();\n current.add(file);\n index.idToFiles.set(id, current);\n}\n","const CONTRACT_DECLARATION_RE =\n /^\\s*(?:#|\\/\\/|--|\\/\\*+|\\*+)?\\s*QFAI-CONTRACT-ID:\\s*((?:API|UI|DB)-\\d{4})\\s*(?:\\*\\/)?\\s*$/gm;\nconst CONTRACT_DECLARATION_LINE_RE =\n /^\\s*(?:#|\\/\\/|--|\\/\\*+|\\*+)?\\s*QFAI-CONTRACT-ID:\\s*(?:API|UI|DB)-\\d{4}\\s*(?:\\*\\/)?\\s*$/;\n\nexport function extractDeclaredContractIds(text: string): string[] {\n const ids: string[] = [];\n for (const match of text.matchAll(CONTRACT_DECLARATION_RE)) {\n const id = match[1];\n if (id) {\n ids.push(id);\n }\n }\n return ids;\n}\n\nexport function stripContractDeclarationLines(text: string): string {\n return text\n .split(/\\r?\\n/)\n .filter((line) => !CONTRACT_DECLARATION_LINE_RE.test(line))\n .join(\"\\n\");\n}\n","export type IdPrefix = \"SPEC\" | \"BR\" | \"SC\" | \"UI\" | \"API\" | \"DB\";\nexport type IdFormatPrefix = IdPrefix | \"ADR\";\n\nconst ID_PREFIXES: IdPrefix[] = [\"SPEC\", \"BR\", \"SC\", \"UI\", \"API\", \"DB\"];\n\nconst STRICT_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-\\d{4}\\b/g,\n BR: /\\bBR-\\d{4}\\b/g,\n SC: /\\bSC-\\d{4}\\b/g,\n UI: /\\bUI-\\d{4}\\b/g,\n API: /\\bAPI-\\d{4}\\b/g,\n DB: /\\bDB-\\d{4}\\b/g,\n ADR: /\\bADR-\\d{4}\\b/g,\n};\n\nconst LOOSE_ID_PATTERNS: Record<IdFormatPrefix, RegExp> = {\n SPEC: /\\bSPEC-[A-Za-z0-9_-]+\\b/gi,\n BR: /\\bBR-[A-Za-z0-9_-]+\\b/gi,\n SC: /\\bSC-[A-Za-z0-9_-]+\\b/gi,\n UI: /\\bUI-[A-Za-z0-9_-]+\\b/gi,\n API: /\\bAPI-[A-Za-z0-9_-]+\\b/gi,\n DB: /\\bDB-[A-Za-z0-9_-]+\\b/gi,\n ADR: /\\bADR-[A-Za-z0-9_-]+\\b/gi,\n};\n\nexport function extractIds(text: string, prefix: IdPrefix): string[] {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const matches = text.match(pattern);\n return unique(matches ?? []);\n}\n\nexport function extractAllIds(text: string): string[] {\n const all: string[] = [];\n ID_PREFIXES.forEach((prefix) => {\n all.push(...extractIds(text, prefix));\n });\n return unique(all);\n}\n\nexport function extractInvalidIds(\n text: string,\n prefixes: IdFormatPrefix[],\n): string[] {\n const invalid: string[] = [];\n for (const prefix of prefixes) {\n const candidates = text.match(LOOSE_ID_PATTERNS[prefix]) ?? [];\n for (const candidate of candidates) {\n if (!isValidId(candidate, prefix)) {\n invalid.push(candidate);\n }\n }\n }\n return unique(invalid);\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction isValidId(value: string, prefix: IdFormatPrefix): boolean {\n const pattern = STRICT_ID_PATTERNS[prefix];\n const strict = new RegExp(pattern.source);\n return strict.test(value);\n}\n","export type ParsedContractRefs = {\n lines: string[];\n ids: string[];\n invalidTokens: string[];\n hasNone: boolean;\n};\n\nexport type ContractRefParseOptions = {\n allowCommentPrefix?: boolean;\n};\n\nconst CONTRACT_REF_ID_RE = /^(?:API|UI|DB)-\\d{4}$/;\n\nexport function parseContractRefs(\n text: string,\n options: ContractRefParseOptions = {},\n): ParsedContractRefs {\n const linePattern = buildLinePattern(options);\n const lines: string[] = [];\n for (const match of text.matchAll(linePattern)) {\n lines.push((match[1] ?? \"\").trim());\n }\n\n const ids: string[] = [];\n const invalidTokens: string[] = [];\n let hasNone = false;\n\n for (const line of lines) {\n if (line.length === 0) {\n invalidTokens.push(\"(empty)\");\n continue;\n }\n const tokens = line.split(\",\").map((token) => token.trim());\n for (const token of tokens) {\n if (token.length === 0) {\n invalidTokens.push(\"(empty)\");\n continue;\n }\n if (token === \"none\") {\n hasNone = true;\n continue;\n }\n if (CONTRACT_REF_ID_RE.test(token)) {\n ids.push(token);\n continue;\n }\n invalidTokens.push(token);\n }\n }\n\n return {\n lines,\n ids: unique(ids),\n invalidTokens: unique(invalidTokens),\n hasNone,\n };\n}\n\nfunction buildLinePattern(options: ContractRefParseOptions): RegExp {\n // Scenario uses a comment line, so require \"#\" when the comment prefix is enabled.\n const prefix = options.allowCommentPrefix ? \"#\" : \"\";\n return new RegExp(\n `^[ \\\\t]*${prefix}[ \\\\t]*QFAI-CONTRACT-REF:[ \\\\t]*([^\\\\r\\\\n]*)[ \\\\t]*$`,\n \"gm\",\n );\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n","export type Heading = { level: number; title: string; line: number };\n\nexport type H2Section = {\n title: string;\n startLine: number;\n endLine: number;\n body: string;\n};\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\nexport function parseHeadings(md: string): Heading[] {\n const lines = md.split(/\\r?\\n/);\n const headings: Heading[] = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const match = line.match(HEADING_RE);\n if (!match) continue;\n const levelToken = match[1];\n const title = match[2];\n if (!levelToken || !title) continue;\n headings.push({\n level: levelToken.length,\n title: title.trim(),\n line: i + 1,\n });\n }\n return headings;\n}\n\nexport function extractH2Sections(md: string): Map<string, H2Section> {\n const lines = md.split(/\\r?\\n/);\n const headings = parseHeadings(md).filter((heading) => heading.level === 2);\n const sections = new Map<string, H2Section>();\n\n for (let i = 0; i < headings.length; i++) {\n const current = headings[i];\n if (!current) continue;\n const next = headings[i + 1];\n const startLine = current.line + 1;\n const endLine = (next?.line ?? lines.length + 1) - 1;\n const body =\n startLine <= endLine\n ? lines.slice(startLine - 1, endLine).join(\"\\n\")\n : \"\";\n\n sections.set(current.title.trim(), {\n title: current.title.trim(),\n startLine,\n endLine,\n body,\n });\n }\n\n return sections;\n}\n","import { parseContractRefs, type ParsedContractRefs } from \"./contractRefs.js\";\nimport { extractH2Sections, parseHeadings } from \"./markdown.js\";\n\nexport type BrPriority = \"P0\" | \"P1\" | \"P2\" | \"P3\";\n\nexport type ParsedBr = {\n id: string;\n priority: BrPriority;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithoutPriority = {\n id: string;\n text: string;\n line: number;\n};\n\nexport type ParsedBrWithInvalidPriority = {\n id: string;\n priority: string;\n text: string;\n line: number;\n};\n\nexport type ParsedSpec = {\n file: string;\n specId?: string;\n sections: Set<string>;\n brs: ParsedBr[];\n brsWithoutPriority: ParsedBrWithoutPriority[];\n brsWithInvalidPriority: ParsedBrWithInvalidPriority[];\n contractRefs: ParsedContractRefs;\n};\n\nconst SPEC_ID_RE = /\\bSPEC-\\d{4}\\b/;\nconst BR_LINE_RE = /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[0-3])\\]\\s*(.+)$/;\nconst BR_LINE_ANY_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\]\\[(P[^\\]]+)\\]\\s*(.+)$/;\nconst BR_LINE_NO_PRIORITY_RE =\n /^\\s*(?:[-*]\\s*)?\\[(BR-\\d{4})\\](?!\\s*\\[P)\\s*(.*\\S.*)$/;\nconst BR_SECTION_TITLE = \"業務ルール\";\nconst VALID_PRIORITIES = new Set<BrPriority>([\"P0\", \"P1\", \"P2\", \"P3\"]);\n\nexport function parseSpec(md: string, file: string): ParsedSpec {\n const headings = parseHeadings(md);\n const h1 = headings.find((heading) => heading.level === 1);\n const specId = h1?.title.match(SPEC_ID_RE)?.[0];\n\n const sections = extractH2Sections(md);\n const sectionNames = new Set(Array.from(sections.keys()));\n const brSection = sections.get(BR_SECTION_TITLE);\n const brLines = brSection ? brSection.body.split(/\\r?\\n/) : [];\n const startLine = brSection?.startLine ?? 1;\n\n const brs: ParsedBr[] = [];\n const brsWithoutPriority: ParsedBrWithoutPriority[] = [];\n const brsWithInvalidPriority: ParsedBrWithInvalidPriority[] = [];\n\n for (let i = 0; i < brLines.length; i++) {\n const lineText = brLines[i] ?? \"\";\n const lineNumber = startLine + i;\n\n const validMatch = lineText.match(BR_LINE_RE);\n if (validMatch) {\n const id = validMatch[1];\n const priority = validMatch[2];\n const text = validMatch[3];\n if (!id || !priority || !text) continue;\n brs.push({\n id,\n priority: priority as BrPriority,\n text: text.trim(),\n line: lineNumber,\n });\n continue;\n }\n\n const anyPriorityMatch = lineText.match(BR_LINE_ANY_PRIORITY_RE);\n if (anyPriorityMatch) {\n const id = anyPriorityMatch[1];\n const priority = anyPriorityMatch[2];\n const text = anyPriorityMatch[3];\n if (!id || !priority || !text) continue;\n if (!VALID_PRIORITIES.has(priority as BrPriority)) {\n brsWithInvalidPriority.push({\n id,\n priority,\n text: text.trim(),\n line: lineNumber,\n });\n }\n continue;\n }\n\n const noPriorityMatch = lineText.match(BR_LINE_NO_PRIORITY_RE);\n if (noPriorityMatch) {\n const id = noPriorityMatch[1];\n const text = noPriorityMatch[2];\n if (!id || !text) continue;\n brsWithoutPriority.push({\n id,\n text: text.trim(),\n line: lineNumber,\n });\n }\n }\n\n const parsed: ParsedSpec = {\n file,\n sections: sectionNames,\n brs,\n brsWithoutPriority,\n brsWithInvalidPriority,\n contractRefs: parseContractRefs(md),\n };\n if (specId) {\n parsed.specId = specId;\n }\n return parsed;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { parseStructuredContract } from \"../contracts.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport {\n extractDeclaredContractIds,\n stripContractDeclarationLines,\n} from \"../contractsDecl.js\";\nimport {\n collectApiContractFiles,\n collectDbContractFiles,\n collectUiContractFiles,\n} from \"../discovery.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SQL_DANGEROUS_PATTERNS: Array<{ pattern: RegExp; label: string }> = [\n { pattern: /\\bDROP\\s+TABLE\\b/i, label: \"DROP TABLE\" },\n { pattern: /\\bDROP\\s+DATABASE\\b/i, label: \"DROP DATABASE\" },\n { pattern: /\\bTRUNCATE\\b/i, label: \"TRUNCATE\" },\n {\n pattern: /\\bALTER\\s+TABLE\\b[\\s\\S]*\\bDROP\\b/i,\n label: \"ALTER TABLE ... DROP\",\n },\n];\n\nexport async function validateContracts(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const contractsRoot = resolvePath(root, config, \"contractsDir\");\n\n issues.push(...(await validateUiContracts(path.join(contractsRoot, \"ui\"))));\n issues.push(...(await validateApiContracts(path.join(contractsRoot, \"api\"))));\n issues.push(...(await validateDbContracts(path.join(contractsRoot, \"db\"))));\n const contractIndex = await buildContractIndex(root, config);\n issues.push(...validateDuplicateContractIds(contractIndex));\n\n return issues;\n}\n\nasync function validateUiContracts(uiRoot: string): Promise<Issue[]> {\n const files = await collectUiContractFiles(uiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-UI-000\",\n \"UI 契約ファイルが見つかりません。\",\n \"info\",\n uiRoot,\n \"contracts.ui.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"UI\"));\n try {\n parseStructuredContract(file, stripContractDeclarationLines(text));\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `UI 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.ui.parse\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateApiContracts(apiRoot: string): Promise<Issue[]> {\n const files = await collectApiContractFiles(apiRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-API-000\",\n \"API 契約ファイルが見つかりません。\",\n \"info\",\n apiRoot,\n \"contracts.api.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"API\"));\n let doc: Record<string, unknown>;\n try {\n doc = parseStructuredContract(file, stripContractDeclarationLines(text));\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-001\",\n `API 契約ファイルの解析に失敗しました: ${file} (${formatError(error)})`,\n \"error\",\n file,\n \"contracts.api.parse\",\n ),\n );\n continue;\n }\n\n if (!hasOpenApi(doc)) {\n issues.push(\n issue(\n \"QFAI-API-001\",\n \"OpenAPI 定義が見つかりません。\",\n \"error\",\n file,\n \"contracts.api.openapi\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateDbContracts(dbRoot: string): Promise<Issue[]> {\n const files = await collectDbContractFiles(dbRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-DB-000\",\n \"DB 契約ファイルが見つかりません。\",\n \"info\",\n dbRoot,\n \"contracts.db.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n const declaredIds = extractDeclaredContractIds(text);\n issues.push(...validateDeclaredContractIds(declaredIds, file, \"DB\"));\n issues.push(...lintSql(text, file));\n }\n\n return issues;\n}\n\nexport function lintSql(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n for (const { pattern, label } of SQL_DANGEROUS_PATTERNS) {\n if (pattern.test(text)) {\n issues.push(\n issue(\n \"QFAI-DB-001\",\n `危険な SQL 操作が含まれています: ${label}`,\n \"warning\",\n file,\n \"contracts.db.sql\",\n ),\n );\n }\n }\n return issues;\n}\n\ntype ContractKind = \"UI\" | \"API\" | \"DB\";\n\nfunction validateDeclaredContractIds(\n ids: string[],\n file: string,\n kind: ContractKind,\n): Issue[] {\n const issues: Issue[] = [];\n if (ids.length === 0) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-010\",\n `契約ファイルに QFAI-CONTRACT-ID がありません: ${file}`,\n \"error\",\n file,\n \"contracts.declaration\",\n ),\n );\n return issues;\n }\n if (ids.length > 1) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-011\",\n `契約ファイルに複数の QFAI-CONTRACT-ID が宣言されています: ${ids.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"contracts.declaration\",\n ids,\n ),\n );\n return issues;\n }\n\n const [id] = ids;\n if (id && !id.startsWith(`${kind}-`)) {\n issues.push(\n issue(\n \"QFAI-CONTRACT-013\",\n `契約ファイルの QFAI-CONTRACT-ID が ${kind}- ではありません: ${id}`,\n \"error\",\n file,\n \"contracts.declarationPrefix\",\n [id],\n ),\n );\n }\n\n return issues;\n}\n\nfunction validateDuplicateContractIds(contractIndex: {\n idToFiles: Map<string, Set<string>>;\n}): Issue[] {\n const issues: Issue[] = [];\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sortedFiles = Array.from(files).sort((a, b) => a.localeCompare(b));\n issues.push(\n issue(\n \"QFAI-CONTRACT-012\",\n `契約 ID が複数ファイルで宣言されています: ${id} (${sortedFiles.join(\n \", \",\n )})`,\n \"error\",\n sortedFiles[0],\n \"contracts.idDuplicate\",\n [id],\n ),\n );\n }\n return issues;\n}\n\nfunction hasOpenApi(doc: Record<string, unknown>): boolean {\n return typeof doc.openapi === \"string\" && doc.openapi.length > 0;\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport { extractIds } from \"./ids.js\";\n\nexport function parseStructuredContract(\n file: string,\n text: string,\n): Record<string, unknown> {\n const ext = path.extname(file).toLowerCase();\n if (ext === \".json\") {\n return JSON.parse(text) as Record<string, unknown>;\n }\n return parseYaml(text) as Record<string, unknown>;\n}\n\nexport function extractUiContractIds(doc: Record<string, unknown>): string[] {\n const id = typeof doc.id === \"string\" ? doc.id : \"\";\n return extractIds(id, \"UI\");\n}\n\nexport function extractApiContractIds(doc: Record<string, unknown>): string[] {\n const operationIds = new Set<string>();\n collectOperationIds(doc, operationIds);\n\n const ids = new Set<string>();\n for (const operationId of operationIds) {\n extractIds(operationId, \"API\").forEach((id) => ids.add(id));\n }\n return Array.from(ids);\n}\n\nexport function collectOperationIds(value: unknown, out: Set<string>): void {\n if (!value || typeof value !== \"object\") {\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n collectOperationIds(item, out);\n }\n return;\n }\n\n for (const [key, entry] of Object.entries(value)) {\n if (key === \"operationId\" && typeof entry === \"string\") {\n out.add(entry);\n continue;\n }\n collectOperationIds(entry, out);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { collectSpecPackDirs } from \"../discovery.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SECTION_RE = /^##\\s+変更区分/m;\nconst COMPAT_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_LINE_RE = /^\\s*-\\s*\\[[ xX]\\]\\s*Change\\/Improvement\\b/m;\nconst COMPAT_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Compatibility\\b/m;\nconst CHANGE_CHECKED_RE = /^\\s*-\\s*\\[[xX]\\]\\s*Change\\/Improvement\\b/m;\n\nexport async function validateDeltas(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const packs = await collectSpecPackDirs(specsRoot);\n if (packs.length === 0) {\n return [];\n }\n\n const issues: Issue[] = [];\n for (const pack of packs) {\n const deltaPath = path.join(pack, \"delta.md\");\n let text: string;\n try {\n text = await readFile(deltaPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-DELTA-001\",\n \"delta.md が見つかりません。\",\n \"error\",\n deltaPath,\n \"delta.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n\n const hasSection = SECTION_RE.test(text);\n const hasCompatibility = COMPAT_LINE_RE.test(text);\n const hasChange = CHANGE_LINE_RE.test(text);\n if (!hasSection || !hasCompatibility || !hasChange) {\n issues.push(\n issue(\n \"QFAI-DELTA-002\",\n \"delta.md の変更区分が不足しています。`## 変更区分` とチェックボックス(Compatibility / Change/Improvement)を追加してください。\",\n \"error\",\n deltaPath,\n \"delta.section\",\n ),\n );\n continue;\n }\n\n const compatibilityChecked = COMPAT_CHECKED_RE.test(text);\n const changeChecked = CHANGE_CHECKED_RE.test(text);\n if (compatibilityChecked === changeChecked) {\n issues.push(\n issue(\n \"QFAI-DELTA-003\",\n \"delta.md の変更区分はどちらか1つだけ選択してください(両方ON/両方OFFは無効です)。\",\n \"error\",\n deltaPath,\n \"delta.classification\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SC_TAG_RE = /^SC-\\d{4}$/;\n\nexport async function validateDefinedIds(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const defined = new Map<string, Set<string>>();\n\n await collectSpecDefinitionIds(specFiles, defined);\n await collectScenarioDefinitionIds(scenarioFiles, defined);\n const contractIndex = await buildContractIndex(root, config);\n for (const [id, files] of contractIndex.idToFiles.entries()) {\n for (const file of files) {\n recordId(defined, id, file);\n }\n }\n\n for (const [id, files] of defined.entries()) {\n if (files.size <= 1) {\n continue;\n }\n const sorted = Array.from(files).sort();\n issues.push(\n issue(\n \"QFAI-ID-001\",\n `ID が重複しています: ${id} (${formatFileList(sorted, root)})`,\n \"error\",\n sorted[0],\n \"id.duplicate\",\n ),\n );\n }\n\n return issues;\n}\n\nasync function collectSpecDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n recordId(out, parsed.specId, file);\n }\n parsed.brs.forEach((br) => recordId(out, br.id, file));\n }\n}\n\nasync function collectScenarioDefinitionIds(\n files: string[],\n out: Map<string, Set<string>>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n for (const scenario of document.scenarios) {\n for (const tag of scenario.tags) {\n if (SC_TAG_RE.test(tag)) {\n recordId(out, tag, file);\n }\n }\n }\n }\n}\n\nfunction recordId(\n out: Map<string, Set<string>>,\n id: string,\n file: string,\n): void {\n const current = out.get(id) ?? new Set<string>();\n current.add(file);\n out.set(id, current);\n}\n\nfunction formatFileList(files: string[], root: string): string {\n return files\n .map((file) => {\n const relative = path.relative(root, file);\n return relative.length > 0 ? relative : file;\n })\n .join(\", \");\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractInvalidIds } from \"../ids.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport { parseScenarioDocument } from \"../scenarioModel.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst GIVEN_PATTERN = /\\bGiven\\b/;\nconst WHEN_PATTERN = /\\bWhen\\b/;\nconst THEN_PATTERN = /\\bThen\\b/;\nconst SC_TAG_RE = /^SC-\\d{4}$/;\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\n\nexport async function validateScenarios(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/scenario.md\";\n const legacy = \"spec-001/scenario.md\";\n return [\n issue(\n \"QFAI-SC-000\",\n `Scenario ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"scenario.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.scenarioPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SC-001\",\n \"scenario.md が見つかりません。\",\n \"error\",\n entry.scenarioPath,\n \"scenario.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(...validateScenarioContent(text, entry.scenarioPath));\n }\n\n return issues;\n}\n\nexport function validateScenarioContent(text: string, file: string): Issue[] {\n const issues: Issue[] = [];\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-010\",\n `Gherkin の解析に失敗しました: ${errors.join(\", \") || \"unknown\"}`,\n \"error\",\n file,\n \"scenario.parse\",\n ),\n );\n return issues;\n }\n\n const featureSpecTags = document.featureTags.filter((tag) =>\n SPEC_TAG_RE.test(tag),\n );\n if (featureSpecTags.length > 1) {\n issues.push(\n issue(\n \"QFAI-SC-009\",\n `Feature の SPEC タグが複数あります: ${featureSpecTags.join(\", \")}`,\n \"error\",\n file,\n \"scenario.featureSpec\",\n featureSpecTags,\n ),\n );\n }\n\n const missingStructure: string[] = [];\n if (!document.featureName) missingStructure.push(\"Feature\");\n if (document.scenarios.length === 0) missingStructure.push(\"Scenario\");\n if (missingStructure.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-006\",\n `Scenario ファイルに必要な構造がありません: ${missingStructure.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"scenario.structure\",\n ),\n );\n }\n\n for (const scenario of document.scenarios) {\n if (scenario.tags.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-007\",\n `Scenario タグが見つかりません: ${scenario.name}`,\n \"error\",\n file,\n \"scenario.tags\",\n ),\n );\n continue;\n }\n\n const missingTags: string[] = [];\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n if (scTags.length === 0) {\n missingTags.push(\"SC(0件)\");\n } else if (scTags.length > 1) {\n missingTags.push(`SC(${scTags.length}件/1件必須)`);\n }\n if (missingTags.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-008\",\n `Scenario タグに不足があります: ${missingTags.join(\", \")} (${\n scenario.name\n })`,\n \"error\",\n file,\n \"scenario.tagIds\",\n ),\n );\n }\n }\n\n for (const scenario of document.scenarios) {\n const missingSteps: string[] = [];\n const keywords = scenario.steps.map((step) => step.keyword.trim());\n if (!keywords.some((keyword) => GIVEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Given\");\n }\n if (!keywords.some((keyword) => WHEN_PATTERN.test(keyword))) {\n missingSteps.push(\"When\");\n }\n if (!keywords.some((keyword) => THEN_PATTERN.test(keyword))) {\n missingSteps.push(\"Then\");\n }\n if (missingSteps.length > 0) {\n issues.push(\n issue(\n \"QFAI-SC-005\",\n `Given/When/Then が不足しています: ${missingSteps.join(\", \")} (${\n scenario.name\n })`,\n \"warning\",\n file,\n \"scenario.steps\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { extractIds, extractInvalidIds } from \"../ids.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { collectSpecEntries } from \"../specLayout.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nexport async function validateSpecs(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const entries = await collectSpecEntries(specsRoot);\n\n if (entries.length === 0) {\n const expected = \"spec-0001/spec.md\";\n const legacy = \"spec-001/spec.md\";\n return [\n issue(\n \"QFAI-SPEC-000\",\n `Spec ファイルが見つかりません。配置場所: ${config.paths.specsDir} / 期待パターン: ${expected} (${legacy} は非対応)`,\n \"info\",\n specsRoot,\n \"spec.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const entry of entries) {\n let text: string;\n try {\n text = await readFile(entry.specPath, \"utf-8\");\n } catch (error) {\n if (isMissingFileError(error)) {\n issues.push(\n issue(\n \"QFAI-SPEC-005\",\n \"spec.md が見つかりません。\",\n \"error\",\n entry.specPath,\n \"spec.exists\",\n ),\n );\n continue;\n }\n throw error;\n }\n issues.push(\n ...validateSpecContent(\n text,\n entry.specPath,\n config.validation.require.specSections,\n ),\n );\n }\n\n return issues;\n}\n\nexport function validateSpecContent(\n text: string,\n file: string,\n requiredSections: string[],\n): Issue[] {\n const issues: Issue[] = [];\n\n const parsed = parseSpec(text, file);\n\n const invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DB\",\n \"ADR\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-ID-002\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n if (!parsed.specId) {\n issues.push(\n issue(\n \"QFAI-SPEC-001\",\n \"SPEC ID が見つかりません。\",\n \"error\",\n file,\n \"spec.id\",\n ),\n );\n }\n\n if (parsed.brs.length === 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-002\",\n \"BR ID が見つかりません。\",\n \"error\",\n file,\n \"spec.br\",\n ),\n );\n }\n\n for (const br of parsed.brsWithoutPriority) {\n issues.push(\n issue(\n \"QFAI-BR-001\",\n `BR 行に Priority がありません: ${br.id}`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n for (const br of parsed.brsWithInvalidPriority) {\n issues.push(\n issue(\n \"QFAI-BR-002\",\n `BR Priority が不正です: ${br.id} (${br.priority})`,\n \"error\",\n file,\n \"spec.brPriority\",\n [br.id],\n ),\n );\n }\n\n const scIds = extractIds(text, \"SC\");\n if (scIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-003\",\n \"Spec は SC を参照しないルールです。\",\n \"warning\",\n file,\n \"spec.noSc\",\n scIds,\n ),\n );\n }\n\n for (const section of requiredSections) {\n if (!parsed.sections.has(section)) {\n issues.push(\n issue(\n \"QFAI-SPEC-004\",\n `必須セクションが不足しています: ${section}`,\n \"error\",\n file,\n \"spec.requiredSection\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n if (!error || typeof error !== \"object\") {\n return false;\n }\n return (error as { code?: string }).code === \"ENOENT\";\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { buildContractIndex } from \"../contractIndex.js\";\nimport { collectScenarioFiles, collectSpecFiles } from \"../discovery.js\";\nimport { collectFiles } from \"../fs.js\";\nimport { extractAllIds } from \"../ids.js\";\nimport { parseContractRefs } from \"../parse/contractRefs.js\";\nimport { parseSpec } from \"../parse/spec.js\";\nimport { buildScenarioAtoms, parseScenarioDocument } from \"../scenarioModel.js\";\nimport { SC_TAG_RE, collectScTestReferences } from \"../traceability.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst SPEC_TAG_RE = /^SPEC-\\d{4}$/;\nconst BR_TAG_RE = /^BR-\\d{4}$/;\n\nexport async function validateTraceability(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n\n const upstreamIds = new Set<string>();\n const specIds = new Set<string>();\n const brIdsInSpecs = new Set<string>();\n const brIdsInScenarios = new Set<string>();\n const scIdsInScenarios = new Set<string>();\n const specContractIds = new Set<string>();\n const specToBrIds = new Map<string, Set<string>>();\n const contractIndex = await buildContractIndex(root, config);\n const contractIds = contractIndex.ids;\n\n for (const file of specFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const parsed = parseSpec(text, file);\n if (parsed.specId) {\n specIds.add(parsed.specId);\n }\n\n const brIds = parsed.brs.map((br) => br.id);\n brIds.forEach((id) => brIdsInSpecs.add(id));\n\n if (parsed.specId) {\n const current = specToBrIds.get(parsed.specId) ?? new Set<string>();\n brIds.forEach((id) => current.add(id));\n specToBrIds.set(parsed.specId, current);\n }\n\n const contractRefs = parsed.contractRefs;\n if (contractRefs.lines.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-020\",\n \"Spec に QFAI-CONTRACT-REF がありません。例: `QFAI-CONTRACT-REF: none` または `QFAI-CONTRACT-REF: UI-0001`\",\n \"error\",\n file,\n \"traceability.specContractRefRequired\",\n ),\n );\n } else {\n if (contractRefs.hasNone && contractRefs.ids.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-023\",\n \"Spec の QFAI-CONTRACT-REF に none と契約 ID が混在しています。none か 契約ID のどちらか一方だけにしてください。\",\n \"error\",\n file,\n \"traceability.specContractRefFormat\",\n ),\n );\n }\n if (contractRefs.invalidTokens.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-021\",\n `Spec の契約 ID が不正です: ${contractRefs.invalidTokens.join(\n \", \",\n )} (例: UI-0001 / API-0001 / DB-0001)`,\n \"error\",\n file,\n \"traceability.specContractRefFormat\",\n contractRefs.invalidTokens,\n ),\n );\n }\n }\n\n contractRefs.ids.forEach((id) => {\n specContractIds.add(id);\n });\n\n const unknownContractIds = contractRefs.ids.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-024\",\n `Spec が未知の契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )}`,\n \"error\",\n file,\n \"traceability.specContractExists\",\n unknownContractIds,\n ),\n );\n }\n }\n\n for (const file of scenarioFiles) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n\n const scenarioContractRefs = parseContractRefs(text, {\n allowCommentPrefix: true,\n });\n if (scenarioContractRefs.lines.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-031\",\n \"Scenario に QFAI-CONTRACT-REF がありません。例: `# QFAI-CONTRACT-REF: none` または `# QFAI-CONTRACT-REF: UI-0001`\",\n \"error\",\n file,\n \"traceability.scenarioContractRefRequired\",\n ),\n );\n } else {\n if (scenarioContractRefs.hasNone && scenarioContractRefs.ids.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-033\",\n \"Scenario の QFAI-CONTRACT-REF に none と契約 ID が混在しています。none か 契約ID のどちらか一方だけにしてください。\",\n \"error\",\n file,\n \"traceability.scenarioContractRefFormat\",\n ),\n );\n }\n if (scenarioContractRefs.invalidTokens.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-032\",\n `Scenario の契約 ID が不正です: ${scenarioContractRefs.invalidTokens.join(\n \", \",\n )} (例: UI-0001 / API-0001 / DB-0001)`,\n \"error\",\n file,\n \"traceability.scenarioContractRefFormat\",\n scenarioContractRefs.invalidTokens,\n ),\n );\n }\n }\n\n const { document, errors } = parseScenarioDocument(text, file);\n if (!document || errors.length > 0) {\n continue;\n }\n\n if (document.scenarios.length !== 1) {\n issues.push(\n issue(\n \"QFAI-TRACE-030\",\n `Scenario ファイルは 1ファイル=1シナリオです。現在: ${document.scenarios.length}件 (file=${file})`,\n \"error\",\n file,\n \"traceability.scenarioOnePerFile\",\n ),\n );\n }\n\n const atoms = buildScenarioAtoms(document, scenarioContractRefs.ids);\n const scIdsInFile = new Set<string>();\n\n for (const [index, scenario] of document.scenarios.entries()) {\n const atom = atoms[index];\n if (!atom) {\n continue;\n }\n\n const specTags = scenario.tags.filter((tag) => SPEC_TAG_RE.test(tag));\n const brTags = scenario.tags.filter((tag) => BR_TAG_RE.test(tag));\n const scTags = scenario.tags.filter((tag) => SC_TAG_RE.test(tag));\n\n if (specTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-014\",\n `Scenario が SPEC タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioSpecRequired\",\n ),\n );\n }\n if (brTags.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-015\",\n `Scenario が BR タグを持っていません: ${scenario.name}`,\n \"error\",\n file,\n \"traceability.scenarioBrRequired\",\n ),\n );\n }\n\n brTags.forEach((id) => brIdsInScenarios.add(id));\n scTags.forEach((id) => {\n scIdsInScenarios.add(id);\n scIdsInFile.add(id);\n });\n const unknownSpecIds = specTags.filter((id) => !specIds.has(id));\n if (unknownSpecIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-005\",\n `Scenario が存在しない SPEC を参照しています: ${unknownSpecIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioSpecExists\",\n unknownSpecIds,\n ),\n );\n }\n\n const unknownBrIds = brTags.filter((id) => !brIdsInSpecs.has(id));\n if (unknownBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-006\",\n `Scenario が存在しない BR を参照しています: ${unknownBrIds.join(\n \", \",\n )} (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrExists\",\n unknownBrIds,\n ),\n );\n }\n\n const unknownContractIds = atom.contractIds.filter(\n (id) => !contractIds.has(id),\n );\n if (unknownContractIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-008\",\n `Scenario が存在しない契約 ID を参照しています: ${unknownContractIds.join(\n \", \",\n )} (${scenario.name})`,\n config.validation.traceability.unknownContractIdSeverity,\n file,\n \"traceability.scenarioContractExists\",\n unknownContractIds,\n ),\n );\n }\n\n if (specTags.length > 0 && brTags.length > 0) {\n const allowedBrIds = new Set<string>();\n for (const specId of specTags) {\n const brIdsForSpec = specToBrIds.get(specId);\n if (!brIdsForSpec) {\n continue;\n }\n brIdsForSpec.forEach((id) => allowedBrIds.add(id));\n }\n const invalidBrIds = brTags.filter((id) => !allowedBrIds.has(id));\n if (invalidBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-007\",\n `Scenario の BR が参照 SPEC に属していません: ${invalidBrIds.join(\n \", \",\n )} (SPEC: ${specTags.join(\", \")}) (${scenario.name})`,\n \"error\",\n file,\n \"traceability.scenarioBrUnderSpec\",\n invalidBrIds,\n ),\n );\n }\n }\n }\n\n if (scIdsInFile.size !== 1) {\n const invalidScIds = Array.from(scIdsInFile).sort((a, b) =>\n a.localeCompare(b),\n );\n const detail =\n invalidScIds.length === 0\n ? \"SC が見つかりません\"\n : `複数の SC が存在します: ${invalidScIds.join(\", \")}`;\n issues.push(\n issue(\n \"QFAI-TRACE-012\",\n `Spec entry が Spec:SC=1:1 を満たしていません: ${detail}`,\n \"error\",\n file,\n \"traceability.specScOneToOne\",\n invalidScIds,\n ),\n );\n }\n }\n\n if (upstreamIds.size === 0) {\n return [\n issue(\n \"QFAI-TRACE-000\",\n \"上流 ID が見つかりません。\",\n \"info\",\n specsRoot,\n \"traceability.upstream\",\n ),\n ];\n }\n\n if (config.validation.traceability.brMustHaveSc && brIdsInSpecs.size > 0) {\n const orphanBrIds = Array.from(brIdsInSpecs).filter(\n (id) => !brIdsInScenarios.has(id),\n );\n if (orphanBrIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-009\",\n `BR が SC に紐づいていません: ${orphanBrIds.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.brMustHaveSc\",\n orphanBrIds,\n ),\n );\n }\n }\n\n const scRefsResult = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scTestRefs = scRefsResult.refs;\n const testFileScan = scRefsResult.scan;\n const hasScenarios = scIdsInScenarios.size > 0;\n const hasGlobConfig = testFileScan.globs.length > 0;\n const hasMatchedTests = testFileScan.matchedFileCount > 0;\n\n if (\n hasScenarios &&\n (!hasGlobConfig || !hasMatchedTests || scRefsResult.error)\n ) {\n const detail = scRefsResult.error ? `(詳細: ${scRefsResult.error})` : \"\";\n issues.push(\n issue(\n \"QFAI-TRACE-013\",\n `テスト探索 glob が未設定/不正/一致ファイル0のため SC→Test を判定できません。${detail}`,\n \"error\",\n testsRoot,\n \"traceability.testFileGlobs\",\n ),\n );\n } else {\n if (\n config.validation.traceability.scMustHaveTest &&\n scIdsInScenarios.size\n ) {\n const scWithoutTests = Array.from(scIdsInScenarios).filter((id) => {\n const refs = scTestRefs.get(id);\n return !refs || refs.size === 0;\n });\n if (scWithoutTests.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-010\",\n `SC がテストで参照されていません: ${scWithoutTests.join(\n \", \",\n )}。testFileGlobs に一致するテストファイルへ QFAI:SC-xxxx を記載してください。`,\n config.validation.traceability.scNoTestSeverity,\n testsRoot,\n \"traceability.scMustHaveTest\",\n scWithoutTests,\n ),\n );\n }\n }\n\n const unknownScIds = Array.from(scTestRefs.keys()).filter(\n (id) => !scIdsInScenarios.has(id),\n );\n if (unknownScIds.length > 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-011\",\n `テストが未知の SC をアノテーション参照しています: ${unknownScIds.join(\n \", \",\n )}`,\n \"error\",\n testsRoot,\n \"traceability.scUnknownInTests\",\n unknownScIds,\n ),\n );\n }\n }\n\n const orphanPolicy = config.validation.traceability.orphanContractsPolicy;\n if (orphanPolicy !== \"allow\") {\n if (contractIds.size > 0) {\n const orphanContracts = Array.from(contractIds).filter(\n (id) => !specContractIds.has(id),\n );\n if (orphanContracts.length > 0) {\n const severity: IssueSeverity =\n orphanPolicy === \"warning\" ? \"warning\" : \"error\";\n issues.push(\n issue(\n \"QFAI-TRACE-022\",\n `契約が Spec から参照されていません: ${orphanContracts.join(\", \")}`,\n severity,\n specsRoot,\n \"traceability.contractCoverage\",\n orphanContracts,\n ),\n );\n }\n }\n }\n\n issues.push(\n ...(await validateCodeReferences(upstreamIds, srcRoot, testsRoot)),\n );\n return issues;\n}\n\nasync function validateCodeReferences(\n upstreamIds: Set<string>,\n srcRoot: string,\n testsRoot: string,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const codeFiles = await collectFiles(srcRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const testFiles = await collectFiles(testsRoot, {\n extensions: [\".ts\", \".tsx\", \".js\", \".jsx\"],\n });\n const targetFiles = [...codeFiles, ...testFiles];\n\n if (targetFiles.length === 0) {\n issues.push(\n issue(\n \"QFAI-TRACE-001\",\n \"参照対象のコード/テストが見つかりません。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n return issues;\n }\n\n const pattern = buildIdPattern(Array.from(upstreamIds));\n let found = false;\n\n for (const file of targetFiles) {\n const text = await readFile(file, \"utf-8\");\n if (pattern.test(text)) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n issues.push(\n issue(\n \"QFAI-TRACE-002\",\n \"上流 ID がコード/テストに参照されていません(参考情報)。\",\n \"info\",\n srcRoot,\n \"traceability.codeReferences\",\n ),\n );\n }\n\n return issues;\n}\n\nfunction buildIdPattern(ids: string[]): RegExp {\n const escaped = ids.map((id) => id.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n return new RegExp(`\\\\b(${escaped.join(\"|\")})\\\\b`);\n}\n\nfunction issue(\n code: string,\n message: string,\n severity: IssueSeverity,\n file?: string,\n rule?: string,\n refs?: string[],\n): Issue {\n const issue: Issue = {\n code,\n severity,\n message,\n };\n if (file) {\n issue.file = file;\n }\n if (rule) {\n issue.rule = rule;\n }\n if (refs && refs.length > 0) {\n issue.refs = refs;\n }\n return issue;\n}\n","import { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport { collectScenarioFiles } from \"./discovery.js\";\nimport {\n buildScCoverage,\n collectScIdsFromScenarioFiles,\n collectScTestReferences,\n} from \"./traceability.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { resolveToolVersion } from \"./version.js\";\nimport { validateContracts } from \"./validators/contracts.js\";\nimport { validateDeltas } from \"./validators/delta.js\";\nimport { validateDefinedIds } from \"./validators/ids.js\";\nimport { validateScenarios } from \"./validators/scenario.js\";\nimport { validateSpecs } from \"./validators/spec.js\";\nimport { validateTraceability } from \"./validators/traceability.js\";\n\nexport async function validateProject(\n root: string,\n configResult?: ConfigLoadResult,\n): Promise<ValidationResult> {\n const resolved = configResult ?? (await loadConfig(root));\n const { config, issues: configIssues } = resolved;\n const issues = [\n ...configIssues,\n ...(await validateSpecs(root, config)),\n ...(await validateDeltas(root, config)),\n ...(await validateScenarios(root, config)),\n ...(await validateContracts(root, config)),\n ...(await validateDefinedIds(root, config)),\n ...(await validateTraceability(root, config)),\n ];\n\n const specsRoot = resolvePath(root, config, \"specsDir\");\n const scenarioFiles = await collectScenarioFiles(specsRoot);\n const scIds = await collectScIdsFromScenarioFiles(scenarioFiles);\n const { refs: scTestRefs, scan: testFiles } = await collectScTestReferences(\n root,\n config.validation.traceability.testFileGlobs,\n config.validation.traceability.testFileExcludeGlobs,\n );\n const scCoverage = buildScCoverage(scIds, scTestRefs);\n\n const toolVersion = await resolveToolVersion();\n return {\n toolVersion,\n issues,\n counts: countIssues(issues),\n traceability: {\n sc: scCoverage,\n testFiles,\n },\n };\n}\n\nfunction countIssues(issues: Issue[]): ValidationCounts {\n return issues.reduce<ValidationCounts>(\n (acc, issue) => {\n acc[issue.severity] += 1;\n return acc;\n },\n { info: 0, warning: 0, error: 0 },\n );\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { FailOn, OutputFormat } from \"../../core/config.js\";\nimport { loadConfig } from \"../../core/config.js\";\nimport { normalizeValidationResult } from \"../../core/normalize.js\";\nimport { toRelativePath } from \"../../core/paths.js\";\nimport type { Issue, ValidationResult } from \"../../core/types.js\";\nimport { validateProject } from \"../../core/validate.js\";\nimport { shouldFail } from \"../lib/failOn.js\";\n\nexport type ValidateOptions = {\n root: string;\n strict: boolean;\n failOn?: FailOn;\n format?: OutputFormat;\n};\n\nexport async function runValidate(options: ValidateOptions): Promise<number> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const result = await validateProject(root, configResult);\n const normalized = normalizeValidationResult(root, result);\n\n const failOn = resolveFailOn(options, configResult.config.validation.failOn);\n const willFail = shouldFail(normalized, failOn);\n\n const format = options.format ?? \"text\";\n if (format === \"text\") {\n emitText(normalized);\n }\n if (format === \"github\") {\n const jsonPath = resolveJsonPath(\n root,\n configResult.config.output.validateJsonPath,\n );\n emitGitHubOutput(normalized, root, jsonPath, { failOn, willFail });\n }\n await emitJson(normalized, root, configResult.config.output.validateJsonPath);\n\n return willFail ? 1 : 0;\n}\n\nfunction resolveFailOn(options: ValidateOptions, fallback: FailOn): FailOn {\n if (options.failOn) {\n return options.failOn;\n }\n if (options.strict) {\n return \"warning\";\n }\n return fallback;\n}\n\nfunction emitText(result: ValidationResult): void {\n for (const item of result.issues) {\n const location = item.file ? ` (${item.file})` : \"\";\n const refs =\n item.refs && item.refs.length > 0 ? ` refs=${item.refs.join(\",\")}` : \"\";\n process.stdout.write(\n `[${item.severity}] ${item.code} ${item.message}${location}${refs}\\n`,\n );\n }\n process.stdout.write(\n `counts: info=${result.counts.info} warning=${result.counts.warning} error=${result.counts.error}\\n`,\n );\n}\n\nfunction emitGitHubOutput(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n status: { failOn: FailOn; willFail: boolean },\n): void {\n const deduped = dedupeIssues(result.issues);\n const omitted = Math.max(deduped.length - GITHUB_ANNOTATION_LIMIT, 0);\n const dropped = Math.max(result.issues.length - deduped.length, 0);\n\n emitGitHubSummary(result, {\n total: deduped.length,\n omitted,\n dropped,\n jsonPath,\n root,\n ...status,\n });\n\n const issues = deduped.slice(0, GITHUB_ANNOTATION_LIMIT);\n for (const issue of issues) {\n emitGitHub(issue);\n }\n}\n\nfunction emitGitHub(issue: Issue): void {\n const level =\n issue.severity === \"error\"\n ? \"error\"\n : issue.severity === \"warning\"\n ? \"warning\"\n : \"notice\";\n const file = issue.file ? `file=${issue.file}` : \"\";\n const line = issue.loc?.line ? `,line=${issue.loc.line}` : \"\";\n const column = issue.loc?.column ? `,col=${issue.loc.column}` : \"\";\n const location = file ? ` ${file}${line}${column}` : \"\";\n process.stdout.write(\n `::${level}${location}::${issue.code}: ${issue.message}\\n`,\n );\n}\n\nfunction emitGitHubSummary(\n result: ValidationResult,\n options: {\n total: number;\n omitted: number;\n dropped: number;\n jsonPath: string;\n root: string;\n failOn: FailOn;\n willFail: boolean;\n },\n): void {\n const summary = [\n \"qfai validate summary:\",\n `error=${result.counts.error}`,\n `warning=${result.counts.warning}`,\n `info=${result.counts.info}`,\n `annotations=${Math.min(options.total, GITHUB_ANNOTATION_LIMIT)}/${options.total}`,\n `failOn=${options.failOn}`,\n `result=${options.willFail ? \"FAIL\" : \"PASS\"}`,\n ].join(\" \");\n process.stdout.write(`${summary}\\n`);\n\n if (options.dropped > 0 || options.omitted > 0) {\n const details = [\n \"qfai validate note:\",\n options.dropped > 0 ? `重複除外=${options.dropped}` : null,\n options.omitted > 0 ? `上限省略=${options.omitted}` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n process.stdout.write(`${details}\\n`);\n }\n\n const relative = toRelativePath(options.root, options.jsonPath);\n process.stdout.write(\n `qfai validate note: 詳細は ${relative} または --format text を参照してください。\\n`,\n );\n\n process.stdout.write(\n \"qfai validate note: 次は qfai report で report.md を生成できます(例: qfai report)。\\n\",\n );\n}\n\nfunction dedupeIssues(issues: Issue[]): Issue[] {\n const seen = new Set<string>();\n const deduped: Issue[] = [];\n for (const issue of issues) {\n const key = issueKey(issue);\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n deduped.push(issue);\n }\n return deduped;\n}\n\nfunction issueKey(issue: Issue): string {\n const file = issue.file ?? \"\";\n const line = issue.loc?.line ?? \"\";\n const column = issue.loc?.column ?? \"\";\n return [issue.code, issue.severity, issue.message, file, line, column].join(\n \"|\",\n );\n}\n\nasync function emitJson(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n): Promise<void> {\n const abs = resolveJsonPath(root, jsonPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction resolveJsonPath(root: string, jsonPath: string): string {\n return path.isAbsolute(jsonPath) ? jsonPath : path.resolve(root, jsonPath);\n}\n\nconst GITHUB_ANNOTATION_LIMIT = 100;\n","import type { FailOn } from \"../../core/config.js\";\nimport type { ValidationResult } from \"../../core/types.js\";\n\nexport type { FailOn };\n\nexport function shouldFail(result: ValidationResult, failOn: FailOn): boolean {\n if (failOn === \"never\") {\n return false;\n }\n if (failOn === \"error\") {\n return result.counts.error > 0;\n }\n return result.counts.error + result.counts.warning > 0;\n}\n","export type ParsedArgs = {\n command: string | null;\n options: {\n root: string;\n rootExplicit: boolean;\n dir: string;\n force: boolean;\n yes: boolean;\n dryRun: boolean;\n reportFormat: \"md\" | \"json\";\n reportOut?: string;\n reportIn?: string;\n reportRunValidate: boolean;\n doctorFormat: \"text\" | \"json\";\n doctorOut?: string;\n validateFormat: \"text\" | \"github\";\n strict: boolean;\n failOn?: \"never\" | \"warning\" | \"error\";\n help: boolean;\n };\n};\n\nexport function parseArgs(argv: string[], cwd: string): ParsedArgs {\n const options: ParsedArgs[\"options\"] = {\n root: cwd,\n rootExplicit: false,\n dir: cwd,\n force: false,\n yes: false,\n dryRun: false,\n reportFormat: \"md\",\n reportRunValidate: false,\n doctorFormat: \"text\",\n validateFormat: \"text\",\n strict: false,\n help: false,\n };\n\n const args = [...argv];\n let command = args.shift() ?? null;\n\n if (command === \"--help\" || command === \"-h\") {\n options.help = true;\n command = null;\n }\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n switch (arg) {\n case \"--root\":\n options.root = args[i + 1] ?? options.root;\n options.rootExplicit = true;\n i += 1;\n break;\n case \"--dir\":\n options.dir = args[i + 1] ?? options.dir;\n i += 1;\n break;\n case \"--force\":\n options.force = true;\n break;\n case \"--yes\":\n options.yes = true;\n break;\n case \"--dry-run\":\n options.dryRun = true;\n break;\n case \"--format\": {\n const next = args[i + 1];\n applyFormatOption(command, next, options);\n i += 1;\n break;\n }\n case \"--strict\":\n options.strict = true;\n break;\n case \"--fail-on\": {\n const next = args[i + 1];\n if (next === \"never\" || next === \"warning\" || next === \"error\") {\n options.failOn = next;\n }\n i += 1;\n break;\n }\n case \"--out\":\n {\n const next = args[i + 1];\n if (next) {\n if (command === \"doctor\") {\n options.doctorOut = next;\n } else {\n options.reportOut = next;\n }\n }\n }\n i += 1;\n break;\n case \"--in\":\n {\n const next = args[i + 1];\n if (next) {\n options.reportIn = next;\n }\n }\n i += 1;\n break;\n case \"--run-validate\":\n options.reportRunValidate = true;\n break;\n case \"--help\":\n case \"-h\":\n options.help = true;\n break;\n default:\n break;\n }\n }\n\n return { command, options };\n}\n\nfunction applyFormatOption(\n command: string | null,\n value: string | undefined,\n options: ParsedArgs[\"options\"],\n): void {\n if (!value) {\n return;\n }\n if (command === \"report\") {\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n return;\n }\n if (command === \"validate\") {\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n return;\n }\n if (command === \"doctor\") {\n if (value === \"text\" || value === \"json\") {\n options.doctorFormat = value;\n }\n return;\n }\n\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n if (value === \"text\" || value === \"github\") {\n options.validateFormat = value;\n }\n}\n","import { runDoctor } from \"./commands/doctor.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runReport } from \"./commands/report.js\";\nimport { runValidate } from \"./commands/validate.js\";\nimport { parseArgs } from \"./lib/args.js\";\nimport { error, info, warn } from \"./lib/logger.js\";\nimport { findConfigRoot } from \"../core/config.js\";\n\nexport async function run(argv: string[], cwd: string): Promise<void> {\n const { command, options } = parseArgs(argv, cwd);\n\n if (!command || options.help) {\n info(usage());\n return;\n }\n\n switch (command) {\n case \"init\":\n await runInit({\n dir: options.dir,\n force: options.force,\n dryRun: options.dryRun,\n yes: options.yes,\n });\n return;\n case \"validate\":\n {\n const resolvedRoot = await resolveRoot(options);\n process.exitCode = await runValidate({\n root: resolvedRoot,\n strict: options.strict,\n format: options.validateFormat,\n ...(options.failOn !== undefined ? { failOn: options.failOn } : {}),\n });\n }\n return;\n case \"report\":\n {\n const resolvedRoot = await resolveRoot(options);\n await runReport({\n root: resolvedRoot,\n format: options.reportFormat,\n ...(options.reportOut !== undefined\n ? { outPath: options.reportOut }\n : {}),\n ...(options.reportIn !== undefined\n ? { inputPath: options.reportIn }\n : {}),\n ...(options.reportRunValidate ? { runValidate: true } : {}),\n });\n }\n return;\n case \"doctor\":\n {\n const exitCode = await runDoctor({\n root: options.root,\n rootExplicit: options.rootExplicit,\n format: options.doctorFormat,\n ...(options.doctorOut !== undefined\n ? { outPath: options.doctorOut }\n : {}),\n ...(options.failOn && options.failOn !== \"never\"\n ? { failOn: options.failOn }\n : {}),\n });\n process.exitCode = exitCode;\n }\n return;\n default:\n error(`Unknown command: ${command}`);\n info(usage());\n return;\n }\n}\n\nfunction usage(): string {\n return `qfai <command> [options]\n\nCommands:\n init テンプレを生成\n validate 仕様/契約/参照の検査\n report 検証結果と集計を出力\n doctor 設定/パス/出力前提の診断\n\nOptions:\n --root <path> 対象ディレクトリ\n --dir <path> init の出力先\n --force 既存ファイルを上書き\n --yes init: 予約フラグ(現状は非対話のため挙動差なし。将来の対話導入時に自動Yes)\n --dry-run 変更を行わず表示のみ\n --format <text|github> validate の出力形式\n --format <md|json> report の出力形式\n --format <text|json> doctor の出力形式\n --strict validate: warning 以上で exit 1\n --fail-on <error|warning|never> validate: 失敗条件\n --fail-on <error|warning> doctor: 失敗条件\n --out <path> report/doctor: 出力先\n --in <path> report: validate.json の入力先(configより優先)\n --run-validate report: validate を実行してから report を生成\n -h, --help ヘルプ表示\n`;\n}\n\nasync function resolveRoot(options: {\n root: string;\n rootExplicit: boolean;\n}): Promise<string> {\n if (options.rootExplicit) {\n return options.root;\n }\n\n const search = await findConfigRoot(options.root);\n if (!search.found) {\n warn(\n `qfai: qfai.config.yaml が見つからないため defaultConfig を使用します (root=${search.root})`,\n );\n }\n return search.root;\n}\n","#!/usr/bin/env node\nimport { run } from \"./main.js\";\n\nrun(process.argv.slice(2), process.cwd()).catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["import_promises","import_node_path","import_promises","import_node_path","path","parseYaml","error","import_promises","import_promises","import_node_path","exists","fg","path","import_promises","import_node_path","path","error","exists","import_node_path","path","import_promises","import_node_path","error","formatError","SC_TAG_RE","error","formatError","path","import_promises","import_node_path","path","exists","normalizeGlobs","path","error","path","import_node_path","import_promises","import_node_path","path","exists","import_node_path","import_node_url","path","path","import_promises","import_node_path","issue","import_promises","import_node_path","import_promises","import_node_path","path","unique","unique","import_promises","import_node_path","import_node_path","import_yaml","path","parseYaml","path","error","formatError","issue","import_promises","import_node_path","path","error","isMissingFileError","issue","import_promises","import_node_path","SC_TAG_RE","issue","path","import_promises","SC_TAG_RE","SPEC_TAG_RE","issue","error","isMissingFileError","import_promises","issue","error","isMissingFileError","import_promises","SPEC_TAG_RE","BR_TAG_RE","issue","SC_TAG_RE","issue","ID_PREFIXES","path","toSortedArray","issue","buildIdPattern","record","path","isMissingFileError","record","error","import_promises","import_node_path","path","issue"]}
|