/** * `graph --workspace` parallel runner. * * Fans a graph run out across every workspace unit detected by the * language adapters' `discoverWorkspaceUnits` hook by spawning one * child process per unit, each running `graph --json`. Each * child has its own Node heap, so the per-unit memory ceiling that * Phase 6 already provides scales naturally: * N units × ~per-unit-budget ≈ total budget. Concurrency is capped at * `os.cpus().length - 1` (or a caller override) so we don't * oversubscribe. * * Polyglot per spec D8b: callers compose units from multiple adapters * via `discoverPolyglotUnits` and pass the flattened list. The runner * itself is language-agnostic — it only sees opaque `WorkspaceUnit`s. */ import { type LanguageAdapter, type Signal, type WorkspaceUnit } from '@opensip-cli/core'; import type { ResolutionMode } from '../types.js'; /** * Per-unit result from a `graph --workspace` fan-out — one entry per * child process spawned by `runWorkspaceUnitsInParallel`. */ export interface WorkspaceUnitRunResult { /** Human-readable unit id (e.g. `core`, `cli`, `crate-foo`). */ readonly unitId: string; /** Absolute root dir the child was spawned against. */ readonly rootDir: string; /** * Project-relative path for display. Empty string if `rootDir` isn't * under `cwd`. */ readonly displayPath: string; /** * The child run's signals, parsed from its `--json` {@link SignalEnvelope} * stdout (ADR-0011). These carry OpenSIP-mapped `ruleId`/`source` (the * child applies Option A); the parent reverse-maps to engine slugs only * where the dashboard session payload needs them. */ readonly signals: readonly Signal[]; readonly exitCode: number; readonly stderr: string; } /** * Inputs to `runWorkspaceUnitsInParallel`. `units` is the flattened * polyglot list typically produced by `discoverPolyglotUnits`. */ export interface RunWorkspaceUnitsInput { readonly cwd: string; /** Exact OpenSIP config selected by the parent invocation, when present. */ readonly configPath?: string; readonly units: readonly WorkspaceUnit[]; /** * Path to the CLI entry script — typically `process.argv[1]` from * the parent. Children invoke `node graph * --json`. */ readonly cliScript: string; /** Override concurrency for tests. Default: cpus()-1, min 1. */ readonly concurrency?: number; /** Forwarded to children if true. */ readonly noCache?: boolean; /** * Edge resolution tier. Forwarded to each child as `--resolution * ` so a `--workspace --resolution fast` run is fast per unit, * not silently exact. Omitted/`'exact'` ⇒ children use their default. */ readonly resolution?: ResolutionMode; /** * Optional adapter id. Forwarded to each child as `--language ` so * workspace fan-out preserves the parent's explicit adapter selection. */ readonly language?: string; /** * `--recipe `: forwarded to each child as `--recipe ` so a * `--workspace --recipe ` run selects the same rule subset per * unit. Children re-resolve the recipe in their own scope (resolved * `Rule` objects can't cross the process boundary). Omitted ⇒ children * use the default recipe. */ readonly recipe?: string; /** Test override (ms) for the per-unit hard kill-timeout. */ readonly hardKillTimeoutMs?: number; } /** * Aggregate output from `runWorkspaceUnitsInParallel` — per-unit * results plus a single boolean indicating whether any child failed. */ export interface RunWorkspaceUnitsOutput { readonly perUnit: readonly WorkspaceUnitRunResult[]; readonly anyChildFailed: boolean; } /** * Aggregate WorkspaceUnits across all adapters that implement the * discovery hook. Per spec D8b: in a polyglot repo (e.g. TS frontend + * Cargo backend) both adapters contribute units to one combined fan- * out. Adapters without the hook contribute zero units (D5). * * Returns units sorted by `rootDir` for deterministic fan-out order. */ export declare function discoverPolyglotUnits(rootDir: string, adapters: readonly LanguageAdapter[]): Promise; /** * Spawn one child process per WorkspaceUnit, run `graph * --json` in each, and aggregate the parsed findings. Concurrency is * capped (default `cpus()-1`). Always resolves; child failures are * surfaced via `anyChildFailed`. */ export declare function runWorkspaceUnitsInParallel(input: RunWorkspaceUnitsInput): Promise; //# sourceMappingURL=workspace-runner.d.ts.map