/** * `cleo check pr` — unified local pre-PR gate (T11956 · DHQ-073 · Epic T11679). * * Runs the SAME high-signal gates that CI runs, locally, in one command, and * returns a single pass/fail summary so an agent can self-verify BEFORE * opening a PR. This closes the DHQ-073 gap: there was no single "run exactly * the CI required-gates locally" command, so agents repeatedly hit * Type-Check / Canon-Drift / Install-Test failures only after CI ran. * * Design (CORE-first, per AGENTS.md Package-Boundary Check) * -------------------------------------------------------- * The gate REGISTRY and the RUNNER live here in `@cleocode/core`. The CLI * handler in `packages/cleo` is a thin dispatch that calls {@link runPrGate} * and renders the result. No business logic lives in the CLI layer. * * Memory safety * ------------- * Heavy gates (build, typecheck, test) are cgroup-capped on Linux via * `systemd-run --user --scope -p MemoryMax=… -p MemorySwapMax=0` when the * binary is available — mirroring the project's OOM-safety discipline. The cap * is best-effort: if `systemd-run` is absent (macOS / minimal CI) the gate * runs uncapped. * * @task T11956 * @epic T11679 (DHQ burn-down) * @see docs/release/branch-protection-setup.md § "Required Status Checks" */ /** * A single runnable pre-PR gate. The `command` + `args` are executed verbatim * (no shell) from the repository root. */ export interface PrGateDef { /** Stable machine id (kebab-case) used in results and `--only` filters. */ readonly id: string; /** Human-readable label shown in the summary. */ readonly label: string; /** The executable to run (e.g. `pnpm`, `node`, `cleo`). */ readonly command: string; /** Arguments passed to the executable. */ readonly args: readonly string[]; /** * Whether this gate is memory-heavy and should be cgroup-capped on Linux. * Lint gates are cheap; build/typecheck/test are heavy. */ readonly heavy: boolean; /** * `core` gates run by default. `full` gates run only with `full: true` — * the complete CI lint surface, which is slower and rarely needed for a * focused change. */ readonly tier: 'core' | 'full'; /** One-line rationale shown in `--list`. */ readonly description: string; } /** * The canonical pre-PR gate registry. The `core` tier mirrors the gates that * actually gate `main` and that agents most commonly trip; the `full` tier * adds the complete standalone-lint surface for an exhaustive local sweep. * * Ordered cheapest-first so a fast lint failure surfaces before the slow * build/test gates run. */ export declare const PR_GATES: readonly PrGateDef[]; /** Outcome of a single gate. */ export interface PrGateRunResult { /** Gate id (matches {@link PrGateDef.id}). */ readonly id: string; /** Gate label. */ readonly label: string; /** Final status. `skipped` means the gate was filtered out by `--only`. */ readonly status: 'pass' | 'fail' | 'skipped'; /** Process exit code (null if the process could not be spawned or skipped). */ readonly exitCode: number | null; /** Wall-clock duration in milliseconds. */ readonly durationMs: number; /** Whether the gate was cgroup-capped on this run. */ readonly capped: boolean; /** Last lines of combined stdout/stderr (trimmed) for failure triage. */ readonly outputTail: string; } /** Aggregate result of a `cleo check pr` run. */ export interface PrGateSummary { /** Repository root the gates ran against. */ readonly repoRoot: string; /** True iff every non-skipped gate passed. */ readonly passed: boolean; /** Per-gate results in execution order. */ readonly gates: readonly PrGateRunResult[]; /** Roll-up counts. */ readonly summary: { readonly pass: number; readonly fail: number; readonly skipped: number; }; } /** Options controlling a {@link runPrGate} run. */ export interface RunPrGateOptions { /** Run the full standalone-lint surface in addition to the core tier. */ readonly full?: boolean; /** Restrict the run to these gate ids (others reported as `skipped`). */ readonly only?: readonly string[]; /** Continue running remaining gates after the first failure (default true). */ readonly keepGoing?: boolean; /** MemoryMax for heavy gates on Linux (default `16G`). */ readonly memoryMax?: string; /** * Override the working tree the gates run in. Defaults to the git toplevel * of `process.cwd()` (so an agent inside a worktree validates THAT worktree, * incl. uncommitted changes — not whatever `CLEO_ROOT` points at). */ readonly cwd?: string; /** * Streaming sink for human progress. Receives one line per lifecycle event. * Defaults to a no-op so the function is pure-by-default for tests. */ readonly onProgress?: (line: string) => void; } /** * Resolve the gate set for a run: the `core` tier always, plus the `full` * tier when requested, then narrowed by `only` (which marks the rest skipped). * * @param opts run options * @returns the gates to execute (in registry order) plus the skipped set * @internal exported for unit testing */ export declare function selectPrGates(opts: Pick): { toRun: PrGateDef[]; skipped: PrGateDef[]; }; /** * Build the argv for a gate, wrapping heavy gates in a cgroup-capped * `systemd-run --user --scope` (via the spawn-wrapper SSoT) when available. * * Delegates to {@link buildSpawnArgs} from * `packages/core/src/resources/spawn-wrapper.ts` — the ONLY constructor of * `systemd-run` argv for cleo children (T11993 SSoT enforcement). * * @param gate the gate definition * @param memoryMax MemoryMax value (e.g. `16G`); passed as a resource override. * @returns `{ command, args, capped }` * @internal exported for unit testing */ export declare function buildGateArgv(gate: PrGateDef, memoryMax: string): { command: string; args: string[]; capped: boolean; }; /** * Resolve the working tree the gates run in: the git toplevel of * `process.cwd()` (so the gates validate the agent's actual checkout/worktree * incl. uncommitted changes). Falls back to {@link getProjectRoot} when not in * a git work tree. * * @returns absolute path to the working-tree root * @internal exported for unit testing */ export declare function resolveWorkingTree(): string; /** * Run the unified pre-PR gate suite and return a structured summary. * * Each gate runs as a child process from the repository root. Heavy gates are * cgroup-capped on Linux when `systemd-run` is available. By default the run * continues after a failure (so the agent sees every problem at once); pass * `keepGoing: false` to stop at the first failure. * * This function performs no process I/O of its own beyond `onProgress` * callbacks — the CLI layer owns stdout/stderr rendering. * * @param opts run options * @returns the aggregate {@link PrGateSummary} */ export declare function runPrGate(opts?: RunPrGateOptions): PrGateSummary; /** * Render a {@link PrGateSummary} as a human-readable, multi-line report * (no trailing newline). The CLI writes this to stderr while the LAFS envelope * goes to stdout — keeping presentation logic in core so the CLI stays a thin * dispatch (AGENTS.md Package-Boundary Check). * * @param summary the aggregate result of a `cleo check pr` run * @returns the formatted human report */ export declare function formatPrGateSummary(summary: PrGateSummary): string; //# sourceMappingURL=pr-gate.d.ts.map