#!/usr/bin/env bun import { runQualityGate } from './runner' import type { BaselineTarget, QualityGateMode } from './types' function parseArgs(argv: string[]) { const args = new Map>() for (let index = 0; index < argv.length; index += 1) { const arg = argv[index] if (!arg.startsWith('--')) { continue } const next = argv[index + 1] if (next && !next.startsWith('--')) { args.set(arg, [...(args.get(arg) ?? []), next]) index += 1 } else { args.set(arg, [...(args.get(arg) ?? []), true]) } } return args } function firstArg(args: Map>, name: string) { return args.get(name)?.[0] } function hasFlag(args: Map>, name: string) { return args.has(name) } function readMode(value: string | boolean | undefined): QualityGateMode { if (value === 'pr' || value === 'baseline' || value === 'release') { return value } throw new Error('Usage: bun run quality:gate --mode [--dry-run] [--allow-live]') } function readBaselineTargets(args: Map>): BaselineTarget[] { const values = (args.get('--provider-model') ?? []) .filter((value): value is string => typeof value === 'string') .flatMap((value) => value.split(',')) .map((value) => value.trim()) .filter(Boolean) return values.map((value) => { const [providerId, modelId, rawLabel] = value.split(':') if (!providerId || !modelId) { throw new Error(`Invalid --provider-model value "${value}". Expected providerId:modelId[:label].`) } return { providerId, modelId, label: rawLabel || `${providerId.slice(0, 8)}-${modelId}`, } }) } const args = parseArgs(process.argv.slice(2)) const mode = readMode(firstArg(args, '--mode')) const dryRun = hasFlag(args, '--dry-run') const allowLive = hasFlag(args, '--allow-live') const artifactsDir = typeof firstArg(args, '--artifacts-dir') === 'string' ? String(firstArg(args, '--artifacts-dir')) : undefined const baselineTargets = readBaselineTargets(args) const { report, outputDir } = await runQualityGate({ mode, dryRun, allowLive, baselineTargets, rootDir: process.cwd(), artifactsDir, }) console.log(`Quality gate report: ${outputDir}/report.md`) console.log(`Summary: passed=${report.summary.passed} failed=${report.summary.failed} skipped=${report.summary.skipped}`) if (report.summary.failed > 0) { process.exit(1) }