/** * `qulib scaffold` — Q2 (scaffold-cli subtask). * * Wraps `scaffoldTests(url, options)` from ../scaffold-tests.js as a first-class * CLI surface (scaffold was previously only reachable programmatically / via MCP). * * This file owns the `scaffold` subcommand end-to-end and is registered from * cli/index.ts via `registerScaffoldCommand(program)` so this build agent never * edits index.ts itself (avoids collision with score-automation). It mirrors the * dynamic-import command style used by `cost` and the output-mode conventions of * `analyze` (write-to-disk by default, `--json` for a stdout-only run). * * Output modes (one stdout shape, mutually exclusive with disk writes): * default → write projectConfig + generated specs under --out (./qulib-scaffold) * --json → no disk writes; print the full ScaffoldResult-shaped JSON on stdout * * Honesty rules (root design principle: never emit false confidence): * - If analyze produced ZERO scenarios, we do NOT write an empty-but-confident * scaffold. Write mode exits non-zero with a clear message; --json emits an * explicit `{ empty: true, ... }` payload so a caller/agent can branch on it. * - `--framework playwright` currently maps to a not-implemented adapter * (PlaywrightAdapter.renderAll throws). Rather than surfacing a raw stack, we * translate it into an actionable error pointing at the supported framework. */ import type { Command } from 'commander'; import { type ScaffoldResult } from '../scaffold-tests.js'; import type { SpecValidationReport } from '../adapters/validate-specs.js'; import { type RecipeId } from '../schemas/recipe.schema.js'; /** Frameworks `scaffoldTests` accepts. Mirrors its `ScaffoldOptions['framework']`. */ declare const FRAMEWORKS: readonly ["cypress-e2e", "playwright"]; type ScaffoldFramework = (typeof FRAMEWORKS)[number]; /** A single file the scaffold wants on disk, with its repo-relative path. */ interface ScaffoldFile { /** Path relative to the --out root. */ relativePath: string; contents: string; } interface ScaffoldRunOptions { url: string; framework: ScaffoldFramework; maxPages?: number; out: string; json: boolean; recipes?: RecipeId[]; /** * When true, fail the command (non-zero exit) if any generated spec does not * parse/compile. The dry-run validation always runs; this flag controls * whether a validation failure is fatal vs merely reported. */ validateSpecs?: boolean; } /** * Raised when `--validate-specs` is set and at least one generated spec fails * the dry-run. Carries a non-zero `exitCode` so the CLI surfaces a hard failure * instead of writing a known-broken scaffold and exiting green. */ export declare class SpecValidationError extends Error { readonly exitCode = 1; constructor(message: string); } /** * Flatten a ScaffoldResult into the concrete files a scaffold project needs: * the framework config file, any support files, and one spec per generated test * (each at its own `outputPath`, which the adapter already namespaces e.g. * `cypress/e2e/.cy.ts`). Pure + side-effect-free so tests can assert on it. */ export declare function collectScaffoldFiles(result: ScaffoldResult): ScaffoldFile[]; /** * Apply the dry-run validation gate. * * Pure + side-effect-free (returns the warning text instead of logging) so it * is unit-testable in isolation: feed it an `ok: false` report and assert it * throws; feed it an `ok: true` report and assert it returns null. This is the * discrimination witness for the fatal path — `runScaffold` cannot produce a * broken spec on demand (the adapters always render valid code), so the gate's * reject-vs-pass behavior is proven here directly against a report. * * @returns a non-null warning string when validation failed but `validateSpecs` * was not set (caller should log it); null when all specs parsed. * @throws SpecValidationError when validation failed AND `validateSpecs` is set. */ export declare function enforceSpecValidation(validation: SpecValidationReport, validateSpecs: boolean): string | null; export declare function runScaffold(options: ScaffoldRunOptions): Promise; export declare function registerScaffoldCommand(program: Command): void; export {}; //# sourceMappingURL=scaffold-run.d.ts.map