Ctrl K
ComunidadGuías…

scripts/check.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { spawn, spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import {
  closeSync,
  existsSync,
  mkdirSync,
  mkdtempSync,
  openSync,
  readFileSync,
  rmSync,
  writeFileSync,
} from "node:fs";
import { dirname, relative, resolve } from "node:path";
import { availableParallelism } from "node:os";
import { fileURLToPath } from "node:url";
import { stripVTControlCharacters } from "node:util";

/**
 * Local development checks, not a replacement for CI: standalone Playwright,
 * Docker sandbox, and deployed-service e2e suites are excluded.
 * Storybook tests require installed Playwright Chromium browser binaries.
 * Integration suites need configured .env/.env.test and local infrastructure.
 * This command does not provision services or reset databases; selected tests
 * can still run their own setup hooks. See --help for modes and options.
 */
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");

export function createOutput(
  env = process.env,
  stdout = process.stdout,
  stderr = process.stderr,
) {
  const terminal = Boolean(stdout.isTTY && stderr.isTTY && env.TERM !== "dumb");
  let color = terminal;
  if (Object.hasOwn(env, "NO_COLOR") || env.TERM === "dumb") color = false;
  else if (Object.hasOwn(env, "FORCE_COLOR")) color = env.FORCE_COLOR !== "0";
  else if (stdout.hasColors && stderr.hasColors)
    color = terminal && stdout.hasColors() && stderr.hasColors();
  // Children write to log files, so their TTY detection cannot see our terminal.
  const childEnv = {
    ...env,
    FORCE_COLOR: color ? (env.FORCE_COLOR ?? "1") : "0",
  };
  if (color) delete childEnv.NO_COLOR;
  else childEnv.NO_COLOR = "1";
  return {
    terminal,
    childEnv,
    paint: (code, text) =>
      color ? `\x1b[${code}m${text}\x1b[0m` : stripVTControlCharacters(text),
    indent: (text) =>
      (color ? text : stripVTControlCharacters(text))
        .split("\n")
        .map((line) => `    ${line}`)
        .join("\n"),
  };
}

const checkTasks = [
  { name: "typecheck", label: "Types" },
  { name: "lint", label: "Lint", runner: "oxlint" },
  {
    name: "test",
    label: "Tests",
    runner: "vitest",
    suite: "server",
    suiteLabel: "Server",
  },
  {
    name: "test-client",
    label: "Tests",
    runner: "vitest",
    suite: "client",
    suiteLabel: "Client",
  },
  {
    name: "test-storybook",
    label: "Tests",
    runner: "vitest",
    suite: "storybook",
    suiteLabel: "Storybook",
  },
];

const components = ["format", "typecheck", "lint", "knip", "tests"];

export function parseOptions(args) {
  const options = {
    branch: false,
    base: "origin/main",
    all: false,
    dryRun: false,
  };
  for (let index = 0; index < args.length; index++) {
    const arg = args[index];
    if (arg === "--branch") options.branch = true;
    else if (arg === "--all") options.all = true;
    else if (arg === "--dry-run") options.dryRun = true;
    else if (["--only", "-o", "--skip", "-s"].includes(arg)) {
      const value = args[++index];
      if (!value || value.startsWith("-"))
        throw new Error(`${arg} requires a comma-separated list of checks`);
      const names = value.split(",");
      for (const name of names) {
        if (!components.includes(name))
          throw new Error(
            `Unknown check: ${JSON.stringify(name)}. Choose from: ${components.join(", ")}`,
          );
      }
      const key = arg === "--only" || arg === "-o" ? "only" : "skip";
      options[key] = [...new Set([...(options[key] ?? []), ...names])];
    } else if (arg === "--base") {
      const base = args[++index];
      if (!base || base.startsWith("-"))
        throw new Error("--base requires a Git ref");
      options.base = base;
      options.branch = true;
    } else if (arg === "--help" || arg === "-h") options.help = true;
    else throw new Error(`Unknown argument: ${arg}`);
  }
  if (options.only && options.skip)
    throw new Error("--only and --skip cannot be combined");
  return options;
}

function capture(command, args) {
  const result = spawnSync(command, args, {
    cwd: root,
    encoding: "utf8",
    env: createOutput({ ...process.env, NO_COLOR: "1" }).childEnv,
    maxBuffer: 64 * 1024 * 1024,
  });
  if (result.error) throw result.error;
  if (result.status !== 0) {
    if (command === "pnpm" && args.includes("turbo")) {
      mkdirSync(resolve(root, ".turbo"), { recursive: true });
      const logFile = resolve(root, ".turbo/check-planning.log");
      writeFileSync(logFile, `${result.stdout ?? ""}${result.stderr ?? ""}`, {
        mode: 0o600,
      });
      throw new Error(
        `Unable to plan checks. Task-runner details: ${relative(root, logFile)}`,
      );
    }
    throw new Error(`${command} ${args.join(" ")} failed:\n${result.stderr}`);
  }
  return result.stdout;
}

export function collectChanges(git, base) {
  const paths = new Set();
  // Separate diffs retain staged changes even if the working tree undoes them.
  for (const args of [
    ["diff", "--name-only", "--no-renames", "-z", base, "HEAD", "--"],
    ["diff", "--name-only", "--no-renames", "-z", "--cached", "--"],
    ["diff", "--name-only", "--no-renames", "-z", "--"],
    ["ls-files", "--others", "--exclude-standard", "-z"],
  ]) {
    for (const path of git(args).split("\0").filter(Boolean)) paths.add(path);
  }
  return [...paths].sort();
}

export function createPlan(
  files,
  packages,
  options,
  base,
  taskGraph,
  exists = existsSync,
) {
  const commands = [];
  const checks = new Set(
    (options.only ?? components).filter(
      (name) => !options.skip?.includes(name),
    ),
  );
  if (!options.all && files.length === 0) return commands;
  const codeFiles = files.filter(
    (file) => !/\.(md|mdx|png|jpg|jpeg|svg|gif|ico)$/.test(file),
  );
  if (!options.all && codeFiles.length === 0) return commands;

  const changes = classifyChanges(codeFiles, packages, options, taskGraph);
  const packageChecks = planPackageChecks(
    codeFiles,
    packages,
    checks,
    base,
    taskGraph,
    exists,
    changes,
  );
  return [
    ...planRepositoryChecks(
      files,
      codeFiles,
      options,
      checks,
      exists,
      changes.analysisFiles,
    ),
    ...packageChecks,
  ];
}

function classifyChanges(codeFiles, packages, options, taskGraph) {
  const owner = (file) =>
    packages.find((pkg) => file.startsWith(`${pkg.path}/`));
  // Turbo inputs select checks, including consumers of files outside packages.
  // Retain policy fallbacks for toolchain changes and unknown root resources;
  // skipping metadata here does not validate workflow/editor configuration.
  let broad = options.all;
  let jsToolchainChanged = false;
  const direct = new Set();
  const fullRoots = new Set();
  const analysisFiles = [];
  for (const file of codeFiles) {
    const pkg = owner(file);
    if (pkg) {
      direct.add(pkg.name);
      analysisFiles.push(file);
      // Enterprise source aliases are not all declared workspace dependencies.
      if (file.startsWith("ee/")) broad = true;
      continue;
    }
    if (
      /^(\.github|\.vscode|\.cursor)\//.test(file) ||
      /^scripts\/check\.(mjs|test\.mjs)$/.test(file) ||
      file === "scripts/vitest/ci-reporter.test.mjs"
    )
      continue;
    if (
      /^(prettier\.config\.[cm]?js|\.prettierrc(?:\.[^/]+)?|\.prettierignore|\.editorconfig)$/.test(
        file,
      )
    ) {
      // Consumer tasks declare formatting configuration in their Turbo inputs.
      continue;
    }
    analysisFiles.push(file);
    if (/^knip\.[^/]+$/.test(file)) continue;
    if (
      /^(package\.json|pnpm-lock\.yaml|pnpm-workspace\.yaml|\.npmrc|\.nvmrc|tsconfig(?:\.[^/]+)?\.json|eslint\.config\.[cm]?js|vitest\.workspace\.[cm]?[jt]s)$/.test(
        file,
      ) ||
      file.startsWith("patches/")
    ) {
      jsToolchainChanged = true;
      for (const consumer of packages) {
        // These packages expose Cargo tasks through pnpm, not JS/TS checks.
        if (
          consumer.path !== "ai-gateway" &&
          consumer.path !== "packages/native"
        )
          fullRoots.add(consumer.name);
      }
      continue;
    }
    if (taskGraph.inputs.has(file)) continue;
    // New root files remain conservative until their consumers are mapped.
    broad = true;
  }
  // Turbo supplies transitive dependents, including dev dependencies, rather
  // than maintaining a second package graph from manifest dependency fields.
  const fullPackages = new Set(
    packages
      .filter((pkg) => fullRoots.has(pkg.name))
      .flatMap((pkg) => [pkg.name, ...pkg.dependents]),
  );
  const affected = new Set([
    ...direct,
    ...fullPackages,
    ...[...taskGraph.affected].map((task) =>
      task.slice(0, task.lastIndexOf("#")),
    ),
  ]);

  return {
    broad,
    jsToolchainChanged,
    direct,
    fullPackages,
    affected,
    analysisFiles,
  };
}

function planPackageChecks(
  codeFiles,
  packages,
  checks,
  base,
  taskGraph,
  exists,
  changes,
) {
  const selected = selectPackageChecks(
    codeFiles,
    packages,
    checks,
    taskGraph,
    exists,
    changes,
  );
  const packageChecks = [];
  const targets = new Set();
  const schedule = (task, names) => {
    for (const name of names) targets.add(`${name}#${task}`);
  };
  const prepare = (taskId) => {
    const task = taskGraph.tasks.get(taskId);
    if (!task) throw new Error(`Missing Turbo task graph for ${taskId}`);
    const directPrerequisites = [];
    for (const dependency of task.dependencies) {
      // Related suites need build/generation prerequisites, not upstream suites.
      if (
        checkTasks.some(
          (task) => task.suite && dependency.endsWith(`#${task.name}`),
        )
      )
        continue;
      targets.add(dependency);
      directPrerequisites.push(dependency);
    }
    const prerequisites = new Set();
    const visit = (taskId) => {
      if (prerequisites.has(taskId)) return;
      prerequisites.add(taskId);
      const prerequisite = taskGraph.tasks.get(taskId);
      if (!prerequisite)
        throw new Error(`Missing Turbo task graph for ${taskId}`);
      for (const dependency of prerequisite.dependencies) visit(dependency);
    };
    for (const dependency of directPrerequisites) visit(dependency);
    // Turbo traverses packages without a matching script but does not execute them.
    return [...prerequisites].filter(
      (taskId) => taskGraph.tasks.get(taskId).command !== "<NONEXISTENT>",
    );
  };
  // File-only TypeScript checks miss downstream errors. Keep project-wide
  // incremental checks and let Turbo run prerequisite builds/code generation;
  // those prerequisites can compile native code even without Rust checks.
  schedule(
    "typecheck",
    selected
      .filter(({ tasks }) => tasks.some((task) => task.name === "typecheck"))
      .map(({ pkg }) => pkg.name),
  );

  // Test suites narrow together; lint narrows independently. Keep group order
  // stable because Turbo targets and printed package checks preserve insertion order.
  const groups = [
    checkTasks.filter((task) => task.name === "lint"),
    checkTasks.filter((task) => task.suite),
  ];
  for (const group of groups) {
    const full = new Map(group.map((task) => [task.name, []]));
    for (const { pkg, tasks, ownFiles, canNarrow, externalTasks } of selected) {
      const checks = group.filter((task) => tasks.includes(task));
      const related =
        canNarrow &&
        checks.every(
          (task) =>
            !externalTasks.has(task.name) &&
            pkg.scripts[task.name].includes(task.runner),
        );
      for (const task of checks) {
        if (
          task.runner === "oxlint" &&
          pkg.scripts[task.name].includes("oxlint")
        ) {
          // Keep dependency preparation in Turbo before file-specific linting.
          const prerequisites = prepare(`${pkg.name}#${task.name}`);
          const details = related
            ? planNarrowedCheck(task, pkg, ownFiles, base, exists)
            : { label: `${task.label} · ${pkg.name}`, args: [] };
          packageChecks.push({
            ...details,
            args: ["--filter", pkg.name, "run", task.name, ...details.args],
            requiresTurbo: true,
            prerequisites,
          });
          continue;
        }
        if (!related) {
          full.get(task.name).push(pkg.name);
          continue;
        }
        // Narrowed checks bypass full-suite caches; only package scripts receive
        // file/changed flags. Prerequisite builds still run through Turbo.
        // Import-based selection cannot discover runtime reads; use --all for those.
        prepare(`${pkg.name}#${task.name}`);
        const details = planNarrowedCheck(task, pkg, ownFiles, base, exists);
        packageChecks.push({
          ...details,
          args: ["--filter", pkg.name, "run", task.name, ...details.args],
          requiresTurbo: true,
        });
      }
    }
    for (const [task, names] of full) schedule(task, names);
  }
  if (targets.size > 0) {
    // One graph lets Turbo deduplicate prerequisite work while running tasks
    // sequentially. File-specific commands wait for successful preparation.
    const checks = [
      ...new Set(
        checkTasks
          .filter((task) =>
            [...targets].some((target) => target.endsWith(`#${task.name}`)),
          )
          .map((task) => task.label),
      ),
    ];
    const checkPackages = new Set(
      [...targets]
        .filter((target) =>
          checkTasks.some((task) => target.endsWith(`#${task.name}`)),
        )
        .map((target) => target.slice(0, target.lastIndexOf("#"))),
    );
    packageChecks.unshift({
      label:
        checks.length > 0
          ? `${checks.join(", ")} & dependencies · ${[...checkPackages].join(", ")}`
          : "Dependencies",
      args: [
        "exec",
        "turbo",
        "run",
        "--summarize",
        "--output-logs=errors-only",
        "--ui=stream",
        "--log-prefix=none",
        "--concurrency=1",
        ...targets,
        "--continue=dependencies-successful",
      ],
      isTurboBatch: true,
    });
  }

  return packageChecks;
}

function selectPackageChecks(
  codeFiles,
  packages,
  checks,
  taskGraph,
  exists,
  changes,
) {
  const { broad, direct, fullPackages, affected } = changes;
  const owner = (file) =>
    packages.find((pkg) => file.startsWith(`${pkg.path}/`));
  return packages.flatMap((pkg) => {
    const tasks = checkTasks.filter((task) =>
      isTaskSelected(pkg, task, checks, taskGraph, changes),
    );
    if (tasks.length === 0) return [];
    const ownFiles = codeFiles.filter((file) => owner(file)?.name === pkg.name);
    const sourceOnly =
      ownFiles.length > 0 &&
      ownFiles.every(
        (file) =>
          file.startsWith(`${pkg.path}/src/`) &&
          /\.[cm]?[jt]sx?$/.test(file) &&
          exists(resolve(root, file)),
      );
    const dependencyChanged = pkg.dependencies.some((dependency) =>
      affected.has(dependency),
    );
    return [
      {
        pkg,
        tasks,
        ownFiles,
        canNarrow:
          !broad &&
          direct.has(pkg.name) &&
          !fullPackages.has(pkg.name) &&
          !dependencyChanged &&
          sourceOnly,
        externalTasks: new Set(
          tasks
            .filter((task) =>
              codeFiles.some(
                (file) =>
                  !file.startsWith(`${pkg.path}/`) &&
                  taskGraph.tasks
                    .get(`${pkg.name}#${task.name}`)
                    .inputFiles.has(file),
              ),
            )
            .map((task) => task.name),
        ),
      },
    ];
  });
}

function isTaskSelected(pkg, task, checks, taskGraph, changes) {
  const { broad, jsToolchainChanged, direct, fullPackages } = changes;
  const component = task.suite ? "tests" : task.name;
  if (!checks.has(component)) return false;
  if (!pkg.scripts[task.name]) return false;
  if (broad) return true;
  if (
    jsToolchainChanged &&
    (pkg.path === "ai-gateway" || pkg.path === "packages/native") &&
    !direct.has(pkg.name)
  )
    return false;
  return (
    fullPackages.has(pkg.name) ||
    taskGraph.affected.has(`${pkg.name}#${task.name}`)
  );
}

function planNarrowedCheck(task, pkg, ownFiles, base, exists) {
  if (task.suite) {
    return {
      label: `${task.suiteLabel} tests · ${pkg.name}`,
      progressLabel: `${pkg.name} · ${task.suiteLabel} tests`,
      args: ["--changed", base, "--passWithNoTests"],
      testSuites: [task.suite],
    };
  }
  const lintFiles = new Set(ownFiles);
  for (const file of ownFiles) {
    if (!/\.stories\.tsx?$/.test(file)) continue;
    for (const extension of ["ts", "tsx"]) {
      const clientTest = file.replace(
        /\.stories\.tsx?$/,
        `.clienttest.${extension}`,
      );
      if (exists(resolve(root, clientTest))) lintFiles.add(clientTest);
    }
  }
  return {
    label: `Lint · ${pkg.name} · ${lintFiles.size} file${lintFiles.size === 1 ? "" : "s"}`,
    args: [
      "--no-error-on-unmatched-pattern",
      ...[...lintFiles].map((file) => `./${relative(pkg.path, file)}`),
    ],
  };
}

function planRepositoryChecks(
  files,
  codeFiles,
  options,
  checks,
  exists,
  analysisFiles,
) {
  const formatted = files.filter(
    (file) =>
      /\.(js|jsx|ts|tsx|css)$/.test(file) && exists(resolve(root, file)),
  );
  const repositoryFormatting =
    options.all ||
    codeFiles.some((file) => /prettier|(^|\/)\.editorconfig$/.test(file));
  const repositoryChecks = [
    {
      component: "format",
      when: repositoryFormatting,
      label: "Formatting · repository-wide",
      args: ["run", "format:check"],
    },
    {
      component: "format",
      when: !repositoryFormatting && formatted.length > 0,
      label: `Formatting · ${formatted.length} file${formatted.length === 1 ? "" : "s"}`,
      args: [
        "exec",
        "prettier",
        "--check",
        "--",
        ...formatted.map((file) => `./${file}`),
      ],
    },
    {
      component: "tests",
      when:
        options.all ||
        files.some((file) =>
          /^scripts\/vitest\/ci-reporter\.(ts|test\.mjs)$/.test(file),
        ),
      label: "Vitest reporter tests",
      args: ["exec", "node", "--test", "scripts/vitest/ci-reporter.test.mjs"],
    },
    {
      component: "knip",
      // Removing an import can orphan unchanged exports anywhere in the graph.
      when:
        options.all ||
        analysisFiles.some((file) =>
          /\.[cm]?[jt]sx?$|\.jsonc?$|\.ya?ml$|knip\./.test(file),
        ),
      label: "Unused code · repository-wide",
      args: [
        "exec",
        "knip",
        "--cache",
        "--cache-location",
        ".turbo/check-knip/cache",
      ],
      isKnip: true,
    },
  ];
  return [
    ...repositoryChecks
      .filter((check) => check.when && checks.has(check.component))
      .map(({ when, component, ...check }) => check),
  ];
}

function loadWorkspace(base) {
  const workspace = JSON.parse(
    capture("pnpm", [
      "exec",
      "turbo",
      "query",
      `query {
        packages { items { name path directDependencies { items { name } } allDependents { items { name } } } }
        affectedTasks(base: ${JSON.stringify(base)}, head: "HEAD", tasks: ${JSON.stringify(checkTasks.map((task) => task.name))}) {
          items { fullName name command reason {
            __typename
            ... on TaskAllChanged { description }
            ... on TaskFileChanged { filePath }
          } }
        }
      }`,
    ]),
  );
  if ((workspace.errors?.length ?? 0) > 0) {
    throw new Error(
      `Turbo package graph query failed: ${workspace.errors.map((error) => error.message).join("; ")}`,
    );
  }
  const packages = workspace.data.packages.items
    // Turbo includes its synthetic workspace root; it is not a check target.
    .filter((pkg) => pkg.name !== "//")
    .map((pkg) => {
      const manifest = JSON.parse(
        readFileSync(resolve(root, pkg.path, "package.json"), "utf8"),
      );
      return {
        name: pkg.name,
        path: pkg.path,
        scripts: manifest.scripts ?? {},
        dependencies: pkg.directDependencies.items
          .filter((dependency) => dependency.name !== "//")
          .map((dependency) => dependency.name),
        dependents: pkg.allDependents.items.map((dependent) => dependent.name),
      };
    })
    .sort((a, b) => b.path.length - a.path.length);
  const dryRun = JSON.parse(
    capture("pnpm", [
      "exec",
      "turbo",
      "run",
      ...checkTasks.map((task) => task.name),
      "--dry=json",
    ]),
  );
  const taskGraph = {
    affected: new Set(),
    tasks: new Map(),
    inputs: new Set(),
  };
  for (const task of dryRun.tasks) {
    const inputFiles = new Set(
      Object.keys(task.inputs).map((file) =>
        relative(root, resolve(root, task.directory, file)),
      ),
    );
    taskGraph.tasks.set(task.taskId, { ...task, inputFiles });
    for (const file of inputFiles) taskGraph.inputs.add(file);
  }
  for (const task of workspace.data.affectedTasks.items) {
    // Turbo 2.11 includes runnable prerequisites in this collection, labelled
    // with this synthetic reason. Select affected checks, not those prerequisites;
    // execution still follows their normal Turbo dependency edges.
    if (
      task.reason.__typename === "TaskAllChanged" &&
      task.reason.description === "required by an affected task"
    )
      continue;
    if (task.reason.__typename === "TaskFileChanged") {
      // Deleted files are absent from live dry-run inputs but still affect tasks.
      taskGraph.inputs.add(task.reason.filePath);
      taskGraph.tasks.get(task.fullName)?.inputFiles.add(task.reason.filePath);
    }
    if (task.command && checkTasks.some((check) => check.name === task.name)) {
      taskGraph.affected.add(task.fullName);
    }
  }
  return { packages, taskGraph };
}

function prepareKnipCache() {
  const files = [
    ...new Set(
      capture("git", [
        "ls-files",
        "--cached",
        "--others",
        "--exclude-standard",
        "-z",
      ])
        .split("\0")
        .filter((file) => file && existsSync(resolve(root, file))),
    ),
  ].sort();
  // File topology matters even across commits/branch switches: adding a missing
  // import target can resolve an error in an otherwise unchanged source file.
  const hash = createHash("sha256").update(JSON.stringify(files));
  for (const file of files) {
    if (
      /\.(jsonc?|ya?ml)$|(^|\/)([^/]*config[^/]*|knip[^/]*|\.[^/]*rc[^/]*|\.gitignore|\.storybook)(\/|$)/i.test(
        file,
      ) ||
      file === "scripts/check.mjs"
    ) {
      hash.update(
        JSON.stringify([file, readFileSync(resolve(root, file), "utf8")]),
      );
    }
  }
  const key = hash.digest("hex");
  const directory = resolve(root, ".turbo/check-knip");
  const keyFile = resolve(directory, "key");
  let previousKey;
  try {
    previousKey = readFileSync(keyFile, "utf8");
  } catch {
    // Missing cache metadata must never allow an older cache to be reused.
  }
  if (previousKey === key) return;
  rmSync(resolve(directory, "cache"), { recursive: true, force: true });
  mkdirSync(directory, { recursive: true });
  writeFileSync(keyFile, key, { mode: 0o600 });
}

async function runCheck(check, outputDirectory, checkIndex) {
  if (check.isKnip) prepareKnipCache();
  const reports = [];
  for (const [stepIndex, command] of (check.steps ?? [check.args]).entries()) {
    const reportFile = check.testSuites
      ? resolve(outputDirectory, `${checkIndex}-${stepIndex}.json`)
      : null;
    const args = reportFile
      ? [
          ...command,
          "--reporter=default",
          "--reporter=json",
          `--outputFile.json=${reportFile}`,
        ]
      : command;
    // Disk-backed capture avoids truncating verbose failures or exhausting a
    // pipe buffer while successful commands remain completely quiet.
    const outputFile = resolve(
      outputDirectory,
      `${checkIndex}-${stepIndex}.log`,
    );
    const output = openSync(outputFile, "w", 0o600);
    let result;
    try {
      result = await new Promise((resolve) => {
        const child = spawn("pnpm", args, {
          cwd: root,
          env: createCheckEnv(),
          stdio: ["ignore", output, output],
        });
        let error;
        child.on("error", (cause) => {
          error = cause;
        });
        child.on("close", (status, signal) => {
          resolve({ status, signal, error });
        });
      });
    } finally {
      closeSync(output);
    }
    if (reportFile) {
      let files = null;
      try {
        const report = JSON.parse(readFileSync(reportFile, "utf8"));
        files = report.testResults.map((file) => ({
          path: relative(root, file.name),
          passed: file.assertionResults.filter(
            (test) => test.status === "passed",
          ).length,
          failed: file.assertionResults.filter(
            (test) => test.status === "failed",
          ).length,
          skipped: file.assertionResults.filter((test) =>
            ["pending", "skipped", "todo", "disabled"].includes(test.status),
          ).length,
        }));
      } catch {
        // Startup failures can prevent Vitest from writing its report. Never
        // misrepresent a missing report as a successful run with no tests.
      }
      reports.push({ suite: check.testSuites[stepIndex], files, outputFile });
    }
    // Do not run a suite whose prerequisite generation/build failed.
    if (result.error || result.signal || result.status !== 0) {
      return {
        failure: { ...result, outputFile },
        reports,
        successfulTurboTasks: check.isTurboBatch
          ? collectDiagnostics(outputFile, true).successfulTaskIds
          : [],
      };
    }
  }
  return { failure: null, reports };
}

export function createCheckEnv(env = process.env) {
  return createOutput({
    ...env,
    VITEST_MAX_WORKERS: "1",
    CARGO_BUILD_JOBS: "1",
    RUST_TEST_THREADS: "1",
    RAYON_NUM_THREADS: "1",
    GOMAXPROCS: "1",
    UV_THREADPOOL_SIZE: "1",
  }).childEnv;
}

export async function* runPlan(plan, outputDirectory, cpus, run = runCheck) {
  const pending = new Map();
  const weights = new Map();
  const hasTurbo = plan.some((check) => check.isTurboBatch);
  let nextIndex = 0;
  let foreground = null;
  let turboFailed = false;
  let successfulTurboTasks = new Set();
  try {
    while (nextIndex < plan.length || pending.size > 0) {
      const weight = plan[nextIndex]?.isTurboBatch ? Math.max(1, cpus - 1) : 1;
      const used = [...weights.values()].reduce((sum, value) => sum + value, 0);
      if (
        foreground === null &&
        nextIndex < plan.length &&
        used + weight <= cpus
      ) {
        const checkIndex = nextIndex++;
        const check = plan[checkIndex];
        if (
          check.requiresTurbo &&
          turboFailed &&
          !check.prerequisites?.every((taskId) =>
            successfulTurboTasks.has(taskId),
          )
        ) {
          yield { type: "skipped", check, checkIndex };
          continue;
        }
        const promise = (async () => {
          const startedAt = performance.now();
          try {
            const { failure, reports, successfulTurboTasks } = await run(
              check,
              outputDirectory,
              checkIndex,
            );
            return {
              type: "completed",
              check,
              checkIndex,
              result: failure,
              reports,
              successfulTurboTasks,
              durationMs: performance.now() - startedAt,
            };
          } catch (error) {
            return { type: "completed", check, checkIndex, error };
          }
        })();
        pending.set(checkIndex, promise);
        weights.set(checkIndex, weight);
        if (!check.requiresTurbo && !(check.isKnip && hasTurbo)) {
          foreground = checkIndex;
        }
        yield { type: "started", check, checkIndex };
        continue;
      }
      const outcome = await Promise.race(pending.values());
      pending.delete(outcome.checkIndex);
      weights.delete(outcome.checkIndex);
      if (outcome.checkIndex === foreground) foreground = null;
      if (outcome.check.isTurboBatch && outcome.result) {
        turboFailed = true;
        successfulTurboTasks = new Set(outcome.successfulTurboTasks);
      }
      yield outcome;
    }
  } finally {
    // An interrupted consumer or unexpected error must not delete logs while
    // background checks are still writing to them. Promises capture rejections.
    await Promise.all(pending.values());
  }
}

function collectDiagnostics(outputFile, isTurboBatch) {
  const captured = readFileSync(outputFile, "utf8").trimEnd();
  if (!isTurboBatch) return { captured, tasks: [], complete: true };

  // Read task logs from the summary rather than trying to strip runner
  // banners/progress from mixed output, which can hide real diagnostics.
  const summaryPath = stripVTControlCharacters(captured)
    .match(/^\s*Summary:\s+(.+\.json)\s*$/m)?.[1]
    ?.trim();
  let failedTasks = [];
  let successfulTaskIds = [];
  if (summaryPath) {
    try {
      const summary = JSON.parse(
        readFileSync(resolve(root, summaryPath), "utf8"),
      );
      successfulTaskIds = summary.tasks
        .filter(
          (task) =>
            task.execution?.exitCode === 0 || task.cache?.status === "HIT",
        )
        .map((task) => task.taskId);
      failedTasks = summary.tasks.filter(
        (task) =>
          Number.isInteger(task.execution?.exitCode) &&
          task.execution.exitCode !== 0,
      );
    } catch {
      /** Missing summaries fall back to captured runner output. */
    }
  }
  const tasks = failedTasks.map((task) => {
    let diagnostics = "";
    try {
      diagnostics = readFileSync(resolve(root, task.logFile), "utf8").trimEnd();
    } catch {
      // Missing logs must not prevent other failed tasks being shown.
    }
    return {
      taskId: task.taskId,
      exitCode: task.execution.exitCode,
      diagnostics,
    };
  });
  return {
    captured,
    tasks,
    successfulTaskIds,
    complete: tasks.length > 0 && tasks.every((task) => task.diagnostics),
  };
}

async function main() {
  const options = parseOptions(process.argv.slice(2));
  if (options.help) {
    console.log(
      "Turbo tasks run sequentially. Nested worker pools are limited to one worker during check.\n",
    );
    console.log(
      "Usage: pnpm check [--branch] [--base <ref>] [--all] [--only <checks> | --skip <checks>] [--dry-run]\n\nDefault: all applicable checks for staged, unstaged, and untracked changes.\n--branch: changes since merge-base with origin/main, plus local changes.\n--base: override branch target (implies --branch).\n--all: check every package within the selected checks.\n--only, -o: run only the comma-separated checks.\n--skip, -s: exclude the comma-separated checks. Cannot combine with --only.\nChecks: format, typecheck, lint, knip, tests. Build/generation prerequisites still run.\n--dry-run: print checks without running them.",
    );
    return;
  }
  const commandStartedAt = performance.now();
  const git = (args) => capture("git", args);
  // Compare branch work to the common ancestor, not the target branch's tip.
  // Callers must fetch stale remote refs; missing refs deliberately fail rather
  // than falling back to a comparison that could silently miss changes.
  const base = options.branch
    ? git(["merge-base", "HEAD", options.base]).trim()
    : git(["rev-parse", "HEAD"]).trim();
  const files = collectChanges(git, base);
  const output = createOutput();
  const cpus = Math.max(1, Math.floor(availableParallelism() / 2));
  console.log(`Task concurrency budget: ${cpus}`);
  printHeader(files, options, output);
  const { packages, taskGraph } = loadWorkspace(base);
  const plan = createPlan(files, packages, options, base, taskGraph);
  if (plan.length === 0) {
    console.log(`No applicable checks (${elapsed(commandStartedAt)}).`);
    return;
  }
  if (options.dryRun) {
    printPlan(plan);
    return;
  }
  const results = await executePlan(plan, output, cpus);
  if (results.interrupted) {
    process.exitCode = 1;
    return;
  }
  printSummary(results, commandStartedAt, output);
}

function elapsed(startedAt) {
  return `${((performance.now() - startedAt) / 1000).toFixed(1)}s`;
}

function printHeader(files, options, { paint }) {
  let scope = "Local checks";
  if (options.all) scope = "All packages";
  else if (options.branch) scope = `Branch checks · ${options.base}`;
  let selection = "all checks";
  if (options.only) selection = `only ${options.only.join(", ")}`;
  else if (options.skip) selection = `skip ${options.skip.join(", ")}`;
  console.log(
    paint(
      "1",
      `${scope} · ${selection} · ${files.length} changed file${files.length === 1 ? "" : "s"}`,
    ),
  );
  for (const file of files) {
    const parts = file.split("/");
    const display =
      file.length > 100 && parts.length > 5
        ? `${parts.slice(0, 4).join("/")}/…/${parts.at(-1)}`
        : file;
    console.log(`  ${display}`);
  }
  if (files.length === 0) console.log("  No changed files.");
  console.log("");
}

function printPlan(plan) {
  for (const { label, args, steps } of plan) {
    for (const command of steps ?? [args]) {
      console.log(
        `\n${label}: pnpm ${command.map((arg) => JSON.stringify(arg)).join(" ")}`,
      );
    }
  }
}

async function executePlan(plan, { terminal, paint, indent }, cpus) {
  mkdirSync(resolve(root, ".turbo"), { recursive: true });
  const outputDirectory = mkdtempSync(resolve(root, ".turbo/check-"));
  let retainLogs = false;
  const failed = [];
  let passedChecks = 0;
  let emptyChecks = 0;
  const skipped = [];
  const rowWidth = Math.min(
    100,
    Math.max(60, ...plan.map((check) => check.label.length + 4)),
  );
  const statusLine = (marker, label, duration, code) => {
    const padding = " ".repeat(Math.max(2, rowWidth - label.length));
    return `${paint(code, marker)} ${label}${padding}${paint("2", duration)}`;
  };
  const active = new Map();
  let progressLines = 0;
  const clearProgress = () => {
    if (progressLines === 0) return;
    process.stdout.write(`\x1b[${progressLines}A\r\x1b[0J`);
    progressLines = 0;
  };
  try {
    for await (const outcome of runPlan(plan, outputDirectory, cpus)) {
      clearProgress();
      if (outcome.type === "started") {
        active.set(outcome.checkIndex, outcome.check);
        if (!terminal) {
          console.log(
            `Running: ${outcome.check.progressLabel ?? outcome.check.label}`,
          );
        }
      } else if (outcome.type === "skipped") {
        const { check } = outcome;
        console.error(statusLine("○", `${check.label} · skipped`, "—", "33"));
        console.error(
          indent("Package checks or dependency preparation failed."),
        );
        skipped.push(check.label);
      } else {
        active.delete(outcome.checkIndex);
        if (outcome.error) throw outcome.error;
        const { check, result, reports, durationMs } = outcome;
        const duration = `${(durationMs / 1000).toFixed(1)}s`;
        const { label, isTurboBatch } = check;
        const noTests =
          reports.length > 0 &&
          reports.every((report) => report.files?.length === 0);
        const resultLabel = describeResult(label, reports, noTests);
        if (result) {
          console.error(statusLine("✗", resultLabel, duration, "31"));
        } else if (noTests) {
          console.log(statusLine("○", resultLabel, duration, "33"));
          emptyChecks++;
        } else {
          console.log(statusLine("✓", resultLabel, duration, "32"));
          passedChecks++;
        }
        if (printReports(reports, indent)) retainLogs = true;
        if (result) {
          if (printFailure(result, isTurboBatch, indent)) retainLogs = true;
          failed.push(label);
          console.error("");
          if (result.signal) {
            return { interrupted: true };
          }
        }
      }
      if (terminal && active.size > 0) {
        const lines = [
          `Running${active.size > 1 ? " in parallel" : ""}:`,
          ...[...active.values()].map(
            (check) => `  ${check.progressLabel ?? check.label}`,
          ),
        ];
        const width = Math.max(1, (process.stdout.columns ?? 80) - 1);
        const display = lines.map((line) =>
          line.length > width ? `${line.slice(0, width - 1)}…` : line,
        );
        process.stdout.write(`${paint("2", display.join("\n"))}\n`);
        progressLines = display.length;
      }
    }
  } finally {
    clearProgress();
    if (!retainLogs) rmSync(outputDirectory, { recursive: true, force: true });
  }
  return { failed, passedChecks, emptyChecks, skipped, interrupted: false };
}

function printSummary(
  { failed, passedChecks, emptyChecks, skipped },
  commandStartedAt,
  { paint },
) {
  const summary = [];
  if (failed.length > 0) summary.push(`${failed.length} failed`);
  if (passedChecks) summary.push(`${passedChecks} passed`);
  if (emptyChecks) summary.push(`${emptyChecks} no related tests`);
  if (skipped.length > 0) summary.push(`${skipped.length} skipped`);
  if (failed.length > 0 || skipped.length > 0) {
    console.error(
      `\n${paint("31", "Failed")} · ${summary.join(", ")} · ${elapsed(commandStartedAt)}`,
    );
    for (const label of failed) console.error(`  ${paint("31", "✗")} ${label}`);
    process.exitCode = 1;
  } else
    console.log(
      `\n${paint("32", "Passed")} · ${summary.join(", ")} · ${elapsed(commandStartedAt)}`,
    );
}

function describeResult(label, reports, noTests) {
  if (noTests) return `${label} · no related tests`;
  if (reports.length === 0 || reports.some((report) => report.files === null))
    return label;
  const files = reports.flatMap((report) => report.files);
  const totals = files.reduce(
    (sum, file) => ({
      passed: sum.passed + file.passed,
      failed: sum.failed + file.failed,
      skipped: sum.skipped + file.skipped,
    }),
    { passed: 0, failed: 0, skipped: 0 },
  );
  return `${label} · ${describeTestCounts(totals)} across ${files.length} file${files.length === 1 ? "" : "s"}`;
}

function describeTestCounts({ passed, failed, skipped }) {
  const counts = [`${passed} passed`];
  if (failed > 0) counts.push(`${failed} failed`);
  if (skipped > 0) counts.push(`${skipped} skipped`);
  return counts.join(", ");
}

function printReports(reports, indent) {
  let retainLogs = false;
  for (const report of reports) {
    if (report.files === null) {
      retainLogs = true;
      console.error(
        indent(
          `${report.suite}: test report unavailable. Details: ${relative(root, report.outputFile)}`,
        ),
      );
      continue;
    }
    for (const file of report.files) {
      console.log(indent(`${file.path} — ${describeTestCounts(file)}`));
    }
  }
  return retainLogs;
}

function printFailure(result, isTurboBatch, indent) {
  if (result.error) console.error(indent(result.error.message));
  const diagnostics = collectDiagnostics(result.outputFile, isTurboBatch);
  if (!isTurboBatch) {
    if (diagnostics.captured) console.error(indent(diagnostics.captured));
    return false;
  }
  for (const task of diagnostics.tasks) {
    console.error(indent(`\n${task.taskId} failed (exit ${task.exitCode}):`));
    console.error(
      indent(
        task.diagnostics || "No diagnostic output was recorded for this task.",
      ),
    );
  }
  if (!diagnostics.complete) {
    if (diagnostics.captured) console.error(indent(diagnostics.captured));
    console.error(
      indent(
        `Some task diagnostics were unavailable. Runner details: ${relative(root, result.outputFile)}`,
      ),
    );
    return true;
  }
  return false;
}

if (
  process.argv[1] &&
  resolve(process.argv[1]) === fileURLToPath(import.meta.url)
) {
  try {
    await main();
  } catch (error) {
    console.error(
      createOutput().paint(
        "31",
        error instanceof Error ? error.message : String(error),
      ),
    );
    process.exitCode = 1;
  }
}