qfai 0.2.5
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/README.md +28 -0
- package/assets/init/qfai/README.md +6 -0
- package/assets/init/qfai/contracts/api/api-0001-sample.yaml +14 -0
- package/assets/init/qfai/contracts/db/db-0001-sample.sql +5 -0
- package/assets/init/qfai/contracts/ui/ui-0001-sample.yaml +4 -0
- package/assets/init/qfai/prompts/makeBusinessFlow.md +34 -0
- package/assets/init/qfai/prompts/makeOverview.md +27 -0
- package/assets/init/qfai/spec/decisions/ADR-0001.md +7 -0
- package/assets/init/qfai/spec/scenarios.feature +6 -0
- package/assets/init/qfai/spec/spec-0001-sample.md +29 -0
- package/assets/init/root/.github/workflows/qfai.yml +22 -0
- package/assets/init/root/qfai.config.yaml +29 -0
- package/dist/cli/commands/init.d.ts +8 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +30 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/report.d.ts +8 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +83 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +10 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +66 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.cjs +2003 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +1980 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/cli/lib/args.d.ts +19 -0
- package/dist/cli/lib/args.d.ts.map +1 -0
- package/dist/cli/lib/args.js +107 -0
- package/dist/cli/lib/args.js.map +1 -0
- package/dist/cli/lib/assets.d.ts +2 -0
- package/dist/cli/lib/assets.d.ts.map +1 -0
- package/dist/cli/lib/assets.js +8 -0
- package/dist/cli/lib/assets.js.map +1 -0
- package/dist/cli/lib/failOn.d.ts +5 -0
- package/dist/cli/lib/failOn.d.ts.map +1 -0
- package/dist/cli/lib/failOn.js +10 -0
- package/dist/cli/lib/failOn.js.map +1 -0
- package/dist/cli/lib/fs.d.ts +11 -0
- package/dist/cli/lib/fs.d.ts.map +1 -0
- package/dist/cli/lib/fs.js +91 -0
- package/dist/cli/lib/fs.js.map +1 -0
- package/dist/cli/lib/logger.d.ts +4 -0
- package/dist/cli/lib/logger.d.ts.map +1 -0
- package/dist/cli/lib/logger.js +10 -0
- package/dist/cli/lib/logger.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +73 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/core/config.d.ts +46 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +224 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/discovery.d.ts +11 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +31 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/fs.d.ts +6 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +55 -0
- package/dist/core/fs.js.map +1 -0
- package/dist/core/ids.d.ts +5 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +49 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +11 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/report.d.ts +41 -0
- package/dist/core/report.d.ts.map +1 -0
- package/dist/core/report.js +238 -0
- package/dist/core/report.js.map +1 -0
- package/dist/core/types.d.ts +27 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/validate.d.ts +4 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +32 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/core/validators/contracts.d.ts +5 -0
- package/dist/core/validators/contracts.d.ts.map +1 -0
- package/dist/core/validators/contracts.js +157 -0
- package/dist/core/validators/contracts.js.map +1 -0
- package/dist/core/validators/scenario.d.ts +5 -0
- package/dist/core/validators/scenario.d.ts.map +1 -0
- package/dist/core/validators/scenario.js +82 -0
- package/dist/core/validators/scenario.js.map +1 -0
- package/dist/core/validators/spec.d.ts +5 -0
- package/dist/core/validators/spec.d.ts.map +1 -0
- package/dist/core/validators/spec.js +69 -0
- package/dist/core/validators/spec.js.map +1 -0
- package/dist/core/validators/traceability.d.ts +4 -0
- package/dist/core/validators/traceability.d.ts.map +1 -0
- package/dist/core/validators/traceability.js +148 -0
- package/dist/core/validators/traceability.js.map +1 -0
- package/dist/core/version.d.ts +2 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +25 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.cjs +1579 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +132 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1523 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/init.ts","../../src/cli/lib/fs.ts","../../src/cli/lib/assets.ts","../../src/cli/lib/logger.ts","../../src/cli/commands/report.ts","../../src/core/config.ts","../../src/core/report.ts","../../src/core/discovery.ts","../../src/core/fs.ts","../../src/core/ids.ts","../../src/core/types.ts","../../src/core/version.ts","../../src/core/validators/contracts.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 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 });\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\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 if (!options.force) {\n for (const file of files) {\n const relative = path.relative(sourceRoot, file);\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 if (!(await shouldWrite(dest, options.force))) {\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 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 return path.resolve(path.dirname(basePath), \"../../assets/init\");\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 { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { loadConfig } from \"../../core/config.js\";\nimport {\n createReportData,\n formatReportJson,\n formatReportMarkdown,\n} from \"../../core/report.js\";\nimport {\n VALIDATION_SCHEMA_VERSION,\n type ValidationResult,\n} from \"../../core/types.js\";\nimport { error, info } from \"../lib/logger.js\";\n\nexport type ReportOptions = {\n root: string;\n format: \"md\" | \"json\";\n jsonPath?: string;\n outPath?: string;\n};\n\nexport async function runReport(options: ReportOptions): Promise<void> {\n const root = path.resolve(options.root);\n const configResult = await loadConfig(root);\n const input = options.jsonPath ?? configResult.config.output.jsonPath;\n const inputPath = path.isAbsolute(input) ? input : path.resolve(root, input);\n let validation: ValidationResult;\n try {\n validation = await readValidationResult(inputPath);\n } catch (err) {\n if (isMissingFileError(err)) {\n error(\n [\n `qfai report: 入力ファイルが見つかりません: ${inputPath}`,\n \"\",\n \"まず validate.json を生成してください。例:\",\n ` qfai validate --json-path ${input}`,\n \"\",\n \"GitHub Actions テンプレを使っている場合は、workflow の validate ジョブを先に実行してください。\",\n ].join(\"\\n\"),\n );\n process.exitCode = 2;\n return;\n }\n throw err;\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 defaultOut =\n options.format === \"json\" ? \".qfai/out/report.json\" : \".qfai/out/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 if (parsed.schemaVersion !== VALIDATION_SCHEMA_VERSION) {\n throw new Error(\n `validate.json の schemaVersion が不一致です: expected ${VALIDATION_SCHEMA_VERSION}, actual ${parsed.schemaVersion}`,\n );\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.schemaVersion !== \"string\") {\n return false;\n }\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 return (\n typeof counts.info === \"number\" &&\n typeof counts.warning === \"number\" &&\n typeof counts.error === \"number\"\n );\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","import { 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\" | \"json\" | \"github\";\n\nexport type QfaiPaths = {\n specDir: string;\n decisionsDir: string;\n scenariosDir: string;\n rulesDir: string;\n contractsDir: string;\n uiContractsDir: string;\n apiContractsDir: string;\n dataContractsDir: 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 scMustTouchContracts: boolean;\n allowOrphanContracts: boolean;\n };\n};\n\nexport type QfaiOutputConfig = {\n format: OutputFormat;\n jsonPath: 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 const defaultConfig: QfaiConfig = {\n paths: {\n specDir: \"qfai/spec\",\n decisionsDir: \"qfai/spec/decisions\",\n scenariosDir: \"qfai/spec\",\n rulesDir: \"qfai/rules\",\n contractsDir: \"qfai/contracts\",\n uiContractsDir: \"qfai/contracts/ui\",\n apiContractsDir: \"qfai/contracts/api\",\n dataContractsDir: \"qfai/contracts/db\",\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 scMustTouchContracts: true,\n allowOrphanContracts: false,\n },\n },\n output: {\n format: \"text\",\n jsonPath: \".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 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 specDir: readString(\n raw.specDir,\n base.specDir,\n \"paths.specDir\",\n configPath,\n issues,\n ),\n decisionsDir: readString(\n raw.decisionsDir,\n base.decisionsDir,\n \"paths.decisionsDir\",\n configPath,\n issues,\n ),\n scenariosDir: readString(\n raw.scenariosDir,\n base.scenariosDir,\n \"paths.scenariosDir\",\n configPath,\n issues,\n ),\n rulesDir: readString(\n raw.rulesDir,\n base.rulesDir,\n \"paths.rulesDir\",\n configPath,\n issues,\n ),\n contractsDir: readString(\n raw.contractsDir,\n base.contractsDir,\n \"paths.contractsDir\",\n configPath,\n issues,\n ),\n uiContractsDir: readString(\n raw.uiContractsDir,\n base.uiContractsDir,\n \"paths.uiContractsDir\",\n configPath,\n issues,\n ),\n apiContractsDir: readString(\n raw.apiContractsDir,\n base.apiContractsDir,\n \"paths.apiContractsDir\",\n configPath,\n issues,\n ),\n dataContractsDir: readString(\n raw.dataContractsDir,\n base.dataContractsDir,\n \"paths.dataContractsDir\",\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 scMustTouchContracts: readBoolean(\n traceabilityRaw?.scMustTouchContracts,\n base.traceability.scMustTouchContracts,\n \"validation.traceability.scMustTouchContracts\",\n configPath,\n issues,\n ),\n allowOrphanContracts: readBoolean(\n traceabilityRaw?.allowOrphanContracts,\n base.traceability.allowOrphanContracts,\n \"validation.traceability.allowOrphanContracts\",\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 format: readOutputFormat(\n raw.format,\n base.format,\n \"output.format\",\n configPath,\n issues,\n ),\n jsonPath: readString(\n raw.jsonPath,\n base.jsonPath,\n \"output.jsonPath\",\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 readOutputFormat(\n value: unknown,\n fallback: OutputFormat,\n label: string,\n configPath: string,\n issues: Issue[],\n): OutputFormat {\n if (value === \"text\" || value === \"json\" || value === \"github\") {\n return value;\n }\n if (value !== undefined) {\n issues.push(\n configIssue(\n configPath,\n `${label} は text|json|github のいずれかである必要があります。`,\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\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 { readFile } from \"node:fs/promises\";\nimport { loadConfig, resolvePath, type ConfigLoadResult } from \"./config.js\";\nimport { collectContractFiles, collectSpecFiles } from \"./discovery.js\";\nimport { collectFiles } from \"./fs.js\";\nimport { extractAllIds, extractIds, type IdPrefix } from \"./ids.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 decisions: number;\n rules: 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 data: string[];\n};\n\nexport type ReportTraceability = {\n upstreamIdsFound: number;\n referencedInCodeOrTests: boolean;\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\", \"DATA\"];\n\nexport async function createReportData(\n root: string,\n validation?: ValidationResult,\n configResult?: ConfigLoadResult,\n): Promise<ReportData> {\n const resolved = configResult ?? (await loadConfig(root));\n const config = resolved.config;\n const configPath = resolved.configPath;\n\n const specRoot = resolvePath(root, config, \"specDir\");\n const decisionsRoot = resolvePath(root, config, \"decisionsDir\");\n const scenariosRoot = resolvePath(root, config, \"scenariosDir\");\n const rulesRoot = resolvePath(root, config, \"rulesDir\");\n const apiRoot = resolvePath(root, config, \"apiContractsDir\");\n const uiRoot = resolvePath(root, config, \"uiContractsDir\");\n const dbRoot = resolvePath(root, config, \"dataContractsDir\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specRoot);\n const scenarioFiles = await collectFiles(scenariosRoot, {\n extensions: [\".feature\"],\n });\n const decisionFiles = await collectFiles(decisionsRoot, {\n extensions: [\".md\"],\n });\n const ruleFiles = await collectFiles(rulesRoot, { extensions: [\".md\"] });\n const {\n api: apiFiles,\n ui: uiFiles,\n db: dbFiles,\n } = await collectContractFiles(uiRoot, apiRoot, dbRoot);\n\n const idsByPrefix = await collectIds([\n ...specFiles,\n ...scenarioFiles,\n ...decisionFiles,\n ...ruleFiles,\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\n const resolvedValidation =\n validation ?? (await validateProject(root, resolved));\n const version = await resolveToolVersion();\n\n return {\n tool: \"qfai\",\n version,\n generatedAt: new Date().toISOString(),\n root,\n configPath,\n summary: {\n specs: specFiles.length,\n scenarios: scenarioFiles.length,\n decisions: decisionFiles.length,\n rules: ruleFiles.length,\n contracts: {\n api: apiFiles.length,\n ui: uiFiles.length,\n db: dbFiles.length,\n },\n counts: resolvedValidation.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 data: idsByPrefix.DATA,\n },\n traceability: {\n upstreamIdsFound: upstreamIds.size,\n referencedInCodeOrTests: traceability,\n },\n issues: resolvedValidation.issues,\n };\n}\n\nexport function formatReportMarkdown(data: ReportData): string {\n const lines: string[] = [];\n\n lines.push(\"# QFAI Report\");\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(`- specs: ${data.summary.specs}`);\n lines.push(`- scenarios: ${data.summary.scenarios}`);\n lines.push(`- decisions: ${data.summary.decisions}`);\n lines.push(`- rules: ${data.summary.rules}`);\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(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(\"DATA\", data.ids.data));\n lines.push(\"\");\n\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(\"## Hotspots\");\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 const traceIssues = data.issues.filter(\n (item) =>\n item.rule?.startsWith(\"traceability.\") ||\n item.code.startsWith(\"QFAI_TRACE\") ||\n item.code === \"QFAI_CONTRACT_ORPHAN\",\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 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\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 DATA: 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 DATA: toSortedArray(result.DATA),\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 toSortedArray(values: Set<string>): string[] {\n return Array.from(values).sort((a, b) => a.localeCompare(b));\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 path from \"node:path\";\n\nimport { collectFiles } from \"./fs.js\";\n\nconst LEGACY_SPEC_NAME = \"spec.md\";\nconst SPEC_NAMED_PATTERN = /^spec-\\d{4}-[^/\\\\]+\\.md$/i;\n\nexport type ContractFiles = {\n api: string[];\n ui: string[];\n db: string[];\n};\n\nexport async function collectSpecFiles(specRoot: string): Promise<string[]> {\n const files = await collectFiles(specRoot, { extensions: [\".md\"] });\n return files.filter((file) => isSpecFile(file));\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 collectDataContractFiles(\n dataRoot: string,\n): Promise<string[]> {\n return collectFiles(dataRoot, { extensions: [\".sql\"] });\n}\n\nexport async function collectContractFiles(\n uiRoot: string,\n apiRoot: string,\n dataRoot: string,\n): Promise<ContractFiles> {\n const [ui, api, db] = await Promise.all([\n collectUiContractFiles(uiRoot),\n collectApiContractFiles(apiRoot),\n collectDataContractFiles(dataRoot),\n ]);\n return { ui, api, db };\n}\n\nfunction isSpecFile(filePath: string): boolean {\n const name = path.basename(filePath).toLowerCase();\n return name === LEGACY_SPEC_NAME || SPEC_NAMED_PATTERN.test(name);\n}\n","import { access, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\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 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\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","export type IdPrefix = \"SPEC\" | \"BR\" | \"SC\" | \"UI\" | \"API\" | \"DATA\";\n\nconst ID_PATTERNS: Record<IdPrefix, RegExp> = {\n SPEC: /\\bSPEC-[A-Z0-9-]+\\b/g,\n BR: /\\bBR-[A-Z0-9-]+\\b/g,\n SC: /\\bSC-[A-Z0-9-]+\\b/g,\n UI: /\\bUI-[A-Z0-9-]+\\b/g,\n API: /\\bAPI-[A-Z0-9-]+\\b/g,\n DATA: /\\bDATA-[A-Z0-9-]+\\b/g,\n};\n\nconst LOOSE_ID_PATTERNS: Record<IdPrefix, 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 DATA: /\\bDATA-[A-Za-z0-9_-]+\\b/gi,\n};\n\nexport function extractIds(text: string, prefix: IdPrefix): string[] {\n const pattern = 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 (Object.keys(ID_PATTERNS) as IdPrefix[]).forEach((prefix) => {\n all.push(...extractIds(text, prefix));\n });\n return unique(all);\n}\n\nexport function extractInvalidIds(\n text: string,\n prefixes: IdPrefix[],\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: IdPrefix): boolean {\n const pattern = ID_PATTERNS[prefix];\n const strict = new RegExp(pattern.source);\n return strict.test(value);\n}\n","export type IssueSeverity = \"info\" | \"warning\" | \"error\";\n\nexport const VALIDATION_SCHEMA_VERSION = \"0.2\" as const;\n\nexport type IssueLocation = {\n line: number;\n column?: number;\n};\n\nexport type Issue = {\n code: string;\n severity: IssueSeverity;\n message: string;\n file?: string;\n refs?: string[];\n rule?: string;\n loc?: IssueLocation;\n};\n\nexport type ValidationCounts = {\n info: number;\n warning: number;\n error: number;\n};\n\nexport type ValidationResult = {\n schemaVersion: typeof VALIDATION_SCHEMA_VERSION;\n toolVersion: string;\n issues: Issue[];\n counts: ValidationCounts;\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","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport {\n collectApiContractFiles,\n collectDataContractFiles,\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\n issues.push(\n ...(await validateUiContracts(resolvePath(root, config, \"uiContractsDir\"))),\n );\n issues.push(\n ...(await validateApiContracts(\n resolvePath(root, config, \"apiContractsDir\"),\n )),\n );\n issues.push(\n ...(await validateDataContracts(\n resolvePath(root, config, \"dataContractsDir\"),\n )),\n );\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 \"DATA\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_ID_INVALID_FORMAT\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n try {\n const doc = parseYaml(text) as Record<string, unknown>;\n const id = typeof doc.id === \"string\" ? doc.id : \"\";\n if (!id.startsWith(\"UI-\")) {\n issues.push(\n issue(\n \"QFAI-UI-001\",\n \"UI 契約の id は UI- で始まる必要があります。\",\n \"error\",\n file,\n \"contracts.ui.id\",\n ),\n );\n }\n } catch (error) {\n issues.push(\n issue(\n \"QFAI-UI-002\",\n `UI YAML の解析に失敗しました: ${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 \"DATA\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_ID_INVALID_FORMAT\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n try {\n const doc = parseStructured(file, text);\n if (!doc || !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 } catch (error) {\n issues.push(\n issue(\n \"QFAI-API-002\",\n `API 定義の解析に失敗しました: ${formatError(error)}`,\n \"error\",\n file,\n \"contracts.api.parse\",\n ),\n );\n }\n }\n\n return issues;\n}\n\nasync function validateDataContracts(dataRoot: string): Promise<Issue[]> {\n const files = await collectDataContractFiles(dataRoot);\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-DATA-000\",\n \"DATA 契約ファイルが見つかりません。\",\n \"info\",\n dataRoot,\n \"contracts.data.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 \"DATA\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_ID_INVALID_FORMAT\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\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-DATA-001\",\n `危険な SQL 操作が含まれています: ${label}`,\n \"warning\",\n file,\n \"contracts.data.sql\",\n ),\n );\n }\n }\n return issues;\n}\n\nfunction parseStructured(\n file: string,\n text: string,\n): Record<string, unknown> | null {\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\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 { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { collectFiles } from \"../fs.js\";\nimport { extractIds, extractInvalidIds } from \"../ids.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nconst GIVEN_PATTERN = /\\bGiven\\b/;\nconst WHEN_PATTERN = /\\bWhen\\b/;\nconst THEN_PATTERN = /\\bThen\\b/;\n\nexport async function validateScenarios(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const scenariosRoot = resolvePath(root, config, \"scenariosDir\");\n const files = await collectFiles(scenariosRoot, {\n extensions: [\".feature\"],\n });\n\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-SC-000\",\n \"Scenario ファイルが見つかりません。\",\n \"info\",\n scenariosRoot,\n \"scenario.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n issues.push(...validateScenarioContent(text, file));\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 \"DATA\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_ID_INVALID_FORMAT\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n const scIds = extractIds(text, \"SC\");\n if (scIds.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-001\",\n \"SC ID が見つかりません。\",\n \"error\",\n file,\n \"scenario.id\",\n ),\n );\n }\n\n const specIds = extractIds(text, \"SPEC\");\n if (specIds.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-002\",\n \"SC は SPEC を参照する必要があります。\",\n \"error\",\n file,\n \"scenario.spec\",\n ),\n );\n }\n\n const brIds = extractIds(text, \"BR\");\n if (brIds.length === 0) {\n issues.push(\n issue(\n \"QFAI-SC-003\",\n \"SC は BR を参照する必要があります。\",\n \"error\",\n file,\n \"scenario.br\",\n ),\n );\n }\n\n const missingSteps: string[] = [];\n if (!GIVEN_PATTERN.test(text)) {\n missingSteps.push(\"Given\");\n }\n if (!WHEN_PATTERN.test(text)) {\n missingSteps.push(\"When\");\n }\n if (!THEN_PATTERN.test(text)) {\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 \"warning\",\n file,\n \"scenario.steps\",\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","import { readFile } from \"node:fs/promises\";\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport { collectSpecFiles } from \"../discovery.js\";\nimport { extractIds, extractInvalidIds } from \"../ids.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, \"specDir\");\n const files = await collectSpecFiles(specsRoot);\n\n if (files.length === 0) {\n return [\n issue(\n \"QFAI-SPEC-000\",\n \"Spec ファイルが見つかりません。\",\n \"info\",\n specsRoot,\n \"spec.files\",\n ),\n ];\n }\n\n const issues: Issue[] = [];\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n issues.push(\n ...validateSpecContent(\n text,\n file,\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 invalidIds = extractInvalidIds(text, [\n \"SPEC\",\n \"BR\",\n \"SC\",\n \"UI\",\n \"API\",\n \"DATA\",\n ]);\n if (invalidIds.length > 0) {\n issues.push(\n issue(\n \"QFAI_ID_INVALID_FORMAT\",\n `ID フォーマットが不正です: ${invalidIds.join(\", \")}`,\n \"error\",\n file,\n \"id.format\",\n invalidIds,\n ),\n );\n }\n\n const specIds = extractIds(text, \"SPEC\");\n if (specIds.length === 0) {\n issues.push(\n issue(\n \"QFAI-SPEC-001\",\n \"SPEC ID が見つかりません。\",\n \"error\",\n file,\n \"spec.id\",\n ),\n );\n }\n\n const brIds = extractIds(text, \"BR\");\n if (brIds.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 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 (!text.includes(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","import { readFile } from \"node:fs/promises\";\n\nimport type { QfaiConfig } from \"../config.js\";\nimport { resolvePath } from \"../config.js\";\nimport {\n collectApiContractFiles,\n collectDataContractFiles,\n collectSpecFiles,\n collectUiContractFiles,\n} from \"../discovery.js\";\nimport { collectFiles } from \"../fs.js\";\nimport { extractAllIds, extractIds, type IdPrefix } from \"../ids.js\";\nimport type { Issue, IssueSeverity } from \"../types.js\";\n\nexport async function validateTraceability(\n root: string,\n config: QfaiConfig,\n): Promise<Issue[]> {\n const issues: Issue[] = [];\n const specsRoot = resolvePath(root, config, \"specDir\");\n const decisionsRoot = resolvePath(root, config, \"decisionsDir\");\n const scenariosRoot = resolvePath(root, config, \"scenariosDir\");\n const srcRoot = resolvePath(root, config, \"srcDir\");\n const testsRoot = resolvePath(root, config, \"testsDir\");\n\n const specFiles = await collectSpecFiles(specsRoot);\n const decisionFiles = await collectFiles(decisionsRoot, {\n extensions: [\".md\"],\n });\n const scenarioFiles = await collectFiles(scenariosRoot, {\n extensions: [\".feature\"],\n });\n\n const upstreamIds = new Set<string>();\n const brIdsInSpecs = new Set<string>();\n const brIdsInScenarios = new Set<string>();\n const scIdsInScenarios = new Set<string>();\n const scenarioContractIds = new Set<string>();\n const scWithContracts = new Set<string>();\n\n for (const file of [...specFiles, ...decisionFiles]) {\n const text = await readFile(file, \"utf-8\");\n extractAllIds(text).forEach((id) => upstreamIds.add(id));\n extractIds(text, \"BR\").forEach((id) => brIdsInSpecs.add(id));\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 brIds = extractIds(text, \"BR\");\n brIds.forEach((id) => brIdsInScenarios.add(id));\n\n const scIds = extractIds(text, \"SC\");\n scIds.forEach((id) => scIdsInScenarios.add(id));\n\n const contractIds = [\n ...extractIds(text, \"UI\"),\n ...extractIds(text, \"API\"),\n ...extractIds(text, \"DATA\"),\n ];\n contractIds.forEach((id) => scenarioContractIds.add(id));\n\n if (contractIds.length > 0) {\n scIds.forEach((id) => scWithContracts.add(id));\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_BR_ORPHAN\",\n `BR が SC に紐づいていません: ${orphanBrIds.join(\", \")}`,\n \"error\",\n specsRoot,\n \"traceability.brMustHaveSc\",\n orphanBrIds,\n ),\n );\n }\n }\n\n if (\n config.validation.traceability.scMustTouchContracts &&\n scIdsInScenarios.size > 0\n ) {\n const scWithoutContracts = Array.from(scIdsInScenarios).filter(\n (id) => !scWithContracts.has(id),\n );\n if (scWithoutContracts.length > 0) {\n issues.push(\n issue(\n \"QFAI_TRACE_SC_NO_CONTRACT\",\n `SC が契約(UI/API/DATA)に接続していません: ${scWithoutContracts.join(\n \", \",\n )}`,\n \"error\",\n scenariosRoot,\n \"traceability.scMustTouchContracts\",\n scWithoutContracts,\n ),\n );\n }\n }\n\n if (!config.validation.traceability.allowOrphanContracts) {\n const contractIds = await collectContractIds(root, config);\n if (contractIds.size > 0) {\n const orphanContracts = Array.from(contractIds).filter(\n (id) => !scenarioContractIds.has(id),\n );\n if (orphanContracts.length > 0) {\n issues.push(\n issue(\n \"QFAI_CONTRACT_ORPHAN\",\n `契約が SC から参照されていません: ${orphanContracts.join(\", \")}`,\n \"error\",\n scenariosRoot,\n \"traceability.allowOrphanContracts\",\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 collectContractIds(\n root: string,\n config: QfaiConfig,\n): Promise<Set<string>> {\n const contractIds = new Set<string>();\n const uiRoot = resolvePath(root, config, \"uiContractsDir\");\n const apiRoot = resolvePath(root, config, \"apiContractsDir\");\n const dataRoot = resolvePath(root, config, \"dataContractsDir\");\n\n const uiFiles = await collectUiContractFiles(uiRoot);\n const apiFiles = await collectApiContractFiles(apiRoot);\n const dataFiles = await collectDataContractFiles(dataRoot);\n\n await collectIdsFromFiles(uiFiles, [\"UI\"], contractIds);\n await collectIdsFromFiles(apiFiles, [\"API\"], contractIds);\n await collectIdsFromFiles(dataFiles, [\"DATA\"], contractIds);\n\n return contractIds;\n}\n\nasync function collectIdsFromFiles(\n files: string[],\n prefixes: IdPrefix[],\n out: Set<string>,\n): Promise<void> {\n for (const file of files) {\n const text = await readFile(file, \"utf-8\");\n for (const prefix of prefixes) {\n extractIds(text, prefix).forEach((id) => out.add(id));\n }\n }\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 \"warning\",\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, type ConfigLoadResult } from \"./config.js\";\nimport type { Issue, ValidationCounts, ValidationResult } from \"./types.js\";\nimport { VALIDATION_SCHEMA_VERSION } from \"./types.js\";\nimport { resolveToolVersion } from \"./version.js\";\nimport { validateContracts } from \"./validators/contracts.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 validateScenarios(root, config)),\n ...(await validateContracts(root, config)),\n ...(await validateTraceability(root, config)),\n ];\n\n const toolVersion = await resolveToolVersion();\n return {\n schemaVersion: VALIDATION_SCHEMA_VERSION,\n toolVersion,\n issues,\n counts: countIssues(issues),\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 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 jsonPath?: string;\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\n const format = options.format ?? configResult.config.output.format;\n const explicitJsonPath = options.jsonPath;\n if (format === \"text\") {\n emitText(result);\n }\n if (format === \"github\") {\n result.issues.forEach(emitGitHub);\n }\n const shouldWriteJson = format === \"json\" || explicitJsonPath !== undefined;\n if (shouldWriteJson) {\n const jsonPath =\n format === \"json\"\n ? (options.jsonPath ?? configResult.config.output.jsonPath)\n : explicitJsonPath;\n if (jsonPath) {\n await emitJson(result, root, jsonPath);\n }\n }\n\n const failOn = resolveFailOn(options, configResult.config.validation.failOn);\n return shouldFail(result, 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 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\nasync function emitJson(\n result: ValidationResult,\n root: string,\n jsonPath: string,\n): Promise<void> {\n const abs = path.isAbsolute(jsonPath)\n ? jsonPath\n : path.resolve(root, jsonPath);\n await mkdir(path.dirname(abs), { recursive: true });\n await writeFile(abs, `${JSON.stringify(result, null, 2)}\\n`, \"utf-8\");\n}\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 dir: string;\n force: boolean;\n yes: boolean;\n dryRun: boolean;\n reportFormat: \"md\" | \"json\";\n reportOut?: string;\n validateFormat: \"text\" | \"json\" | \"github\";\n strict: boolean;\n failOn?: \"never\" | \"warning\" | \"error\";\n jsonPath?: string;\n help: boolean;\n };\n};\n\nexport function parseArgs(argv: string[], cwd: string): ParsedArgs {\n const options: ParsedArgs[\"options\"] = {\n root: cwd,\n dir: cwd,\n force: false,\n yes: false,\n dryRun: false,\n reportFormat: \"md\",\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 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 \"--json-path\":\n {\n const next = args[i + 1];\n if (next) {\n options.jsonPath = next;\n }\n }\n i += 1;\n break;\n case \"--out\":\n {\n const next = args[i + 1];\n if (next) {\n options.reportOut = next;\n }\n }\n i += 1;\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 === \"json\" || value === \"github\") {\n options.validateFormat = value;\n }\n return;\n }\n\n if (value === \"md\" || value === \"json\") {\n options.reportFormat = value;\n }\n if (value === \"text\" || value === \"json\" || value === \"github\") {\n options.validateFormat = value;\n }\n}\n","import { 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 } from \"./lib/logger.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 process.exitCode = await runValidate({\n root: options.root,\n strict: options.strict,\n format: options.validateFormat,\n ...(options.failOn !== undefined ? { failOn: options.failOn } : {}),\n ...(options.jsonPath !== undefined\n ? { jsonPath: options.jsonPath }\n : {}),\n });\n return;\n case \"report\":\n await runReport({\n root: options.root,\n format: options.reportFormat,\n ...(options.jsonPath !== undefined\n ? { jsonPath: options.jsonPath }\n : {}),\n ...(options.reportOut !== undefined\n ? { outPath: options.reportOut }\n : {}),\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\nOptions:\n --root <path> 対象ディレクトリ\n --dir <path> init の出力先\n --force 既存ファイルを上書き\n --yes init: 非対話でデフォルトを採用(現在は非対話が既定、将来の対話導入時も自動Yes)\n --dry-run 変更を行わず表示のみ\n --format <text|json|github> validate の出力形式\n --format <md|json> report の出力形式\n --strict validate: warning 以上で exit 1\n --fail-on <error|warning|never> validate: 失敗条件\n --json-path <path> validate: JSON 出力先 / report: validate JSON 入力\n --out <path> report: 出力先\n -h, --help ヘルプ表示\n`;\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_node_path","path","import_node_path","path","path","import_promises","import_node_path","import_promises","import_node_path","path","parseYaml","error","import_promises","import_node_path","import_promises","import_node_path","exists","path","path","import_promises","import_node_path","import_node_url","path","import_promises","import_node_path","import_yaml","parseYaml","error","formatError","path","issue","import_promises","issue","import_promises","issue","import_promises","issue","issue","buildIdPattern","issue","path","error","import_promises","import_node_path","path","issue"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|