@number10/ci-runner-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/dist/.tsbuildinfo.build +1 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +852 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/cliOptions.d.ts +36 -0
  9. package/dist/cliOptions.d.ts.map +1 -0
  10. package/dist/config/loadConfig.d.ts +14 -0
  11. package/dist/config/loadConfig.d.ts.map +1 -0
  12. package/dist/config/mapConfigToRun.d.ts +60 -0
  13. package/dist/config/mapConfigToRun.d.ts.map +1 -0
  14. package/dist/config/types.d.ts +70 -0
  15. package/dist/config/types.d.ts.map +1 -0
  16. package/dist/index.d.ts +8 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/internal/core/contracts/executor.d.ts +35 -0
  19. package/dist/internal/core/contracts/executor.d.ts.map +1 -0
  20. package/dist/internal/core/contracts/parser.d.ts +45 -0
  21. package/dist/internal/core/contracts/parser.d.ts.map +1 -0
  22. package/dist/internal/core/contracts/reporter.d.ts +34 -0
  23. package/dist/internal/core/contracts/reporter.d.ts.map +1 -0
  24. package/dist/internal/core/contracts/run.d.ts +60 -0
  25. package/dist/internal/core/contracts/run.d.ts.map +1 -0
  26. package/dist/internal/core/contracts/step.d.ts +82 -0
  27. package/dist/internal/core/contracts/step.d.ts.map +1 -0
  28. package/dist/internal/core/execution/nodeCommandExecutor.d.ts +8 -0
  29. package/dist/internal/core/execution/nodeCommandExecutor.d.ts.map +1 -0
  30. package/dist/internal/core/index.d.ts +10 -0
  31. package/dist/internal/core/index.d.ts.map +1 -0
  32. package/dist/internal/core/parsers/parserRegistry.d.ts +29 -0
  33. package/dist/internal/core/parsers/parserRegistry.d.ts.map +1 -0
  34. package/dist/internal/core/reporters/jsonFormatter.d.ts +10 -0
  35. package/dist/internal/core/reporters/jsonFormatter.d.ts.map +1 -0
  36. package/dist/internal/core/runner/pipelineRunner.d.ts +34 -0
  37. package/dist/internal/core/runner/pipelineRunner.d.ts.map +1 -0
  38. package/dist/parsers/defaultStepParsers.d.ts +8 -0
  39. package/dist/parsers/defaultStepParsers.d.ts.map +1 -0
  40. package/dist/reporters/prettyReporter.d.ts +46 -0
  41. package/dist/reporters/prettyReporter.d.ts.map +1 -0
  42. package/dist/runPipeline.d.ts +26 -0
  43. package/dist/runPipeline.d.ts.map +1 -0
  44. package/package.json +42 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sources":["../src/cliOptions.ts","../src/internal/core/execution/nodeCommandExecutor.ts","../src/internal/core/parsers/parserRegistry.ts","../src/internal/core/reporters/jsonFormatter.ts","../src/internal/core/runner/pipelineRunner.ts","../src/config/mapConfigToRun.ts","../src/config/loadConfig.ts","../src/parsers/defaultStepParsers.ts","../src/reporters/prettyReporter.ts","../src/runPipeline.ts","../src/cli.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport type { CliOutputFormat } from './config/types.js'\n\n/**\n * Parsed CLI runtime options.\n */\nexport interface CliOptions {\n /** Absolute working directory for config and execution. */\n readonly cwd: string\n /** Optional explicit config file path. */\n readonly configPath?: string\n /** Selected output format. */\n readonly format: CliOutputFormat\n /** Emits full output for successful steps when true. */\n readonly verbose: boolean\n /** Enables rerun mode on file changes when true. */\n readonly watch: boolean\n /** Stops on first hard failure when true. */\n readonly failFast: boolean\n /** Prints usage and exits when true. */\n readonly help: boolean\n}\n\n/**\n * Parses process arguments for the ci-runner CLI.\n *\n * @param argv Raw argument list excluding node and script path.\n * @param baseCwd Base working directory.\n * @returns Parsed CLI options.\n * @throws Error when an argument is invalid.\n */\nexport const parseCliOptions = (argv: readonly string[], baseCwd: string): CliOptions => {\n let configPath: string | undefined\n let format: CliOutputFormat = 'pretty'\n let verbose = false\n let watch = false\n let failFast = false\n let help = false\n let cwd = baseCwd\n\n for (let index = 0; index < argv.length; index += 1) {\n const argument = argv[index]\n if (!argument) {\n continue\n }\n\n if (argument === '--help' || argument === '-h') {\n help = true\n continue\n }\n\n if (argument === '--verbose') {\n verbose = true\n continue\n }\n\n if (argument === '--watch') {\n watch = true\n continue\n }\n\n if (argument === '--fail-fast') {\n failFast = true\n continue\n }\n\n if (argument === '--format') {\n const nextValue = argv[index + 1]\n if (!nextValue) {\n throw new Error('--format requires a value')\n }\n if (nextValue !== 'pretty' && nextValue !== 'json') {\n throw new Error('--format must be \"pretty\" or \"json\"')\n }\n format = nextValue\n index += 1\n continue\n }\n\n if (argument.startsWith('--format=')) {\n const value = argument.slice('--format='.length)\n if (value !== 'pretty' && value !== 'json') {\n throw new Error('--format must be \"pretty\" or \"json\"')\n }\n format = value\n continue\n }\n\n if (argument === '--config') {\n const nextValue = argv[index + 1]\n if (!nextValue) {\n throw new Error('--config requires a value')\n }\n configPath = nextValue\n index += 1\n continue\n }\n\n if (argument.startsWith('--config=')) {\n configPath = argument.slice('--config='.length)\n continue\n }\n\n if (argument === '--cwd') {\n const nextValue = argv[index + 1]\n if (!nextValue) {\n throw new Error('--cwd requires a value')\n }\n cwd = resolve(baseCwd, nextValue)\n index += 1\n continue\n }\n\n if (argument.startsWith('--cwd=')) {\n cwd = resolve(baseCwd, argument.slice('--cwd='.length))\n continue\n }\n\n throw new Error(`Unknown argument: ${argument}`)\n }\n\n return {\n cwd,\n configPath,\n format,\n verbose,\n watch,\n failFast,\n help,\n }\n}\n\n/**\n * Returns help text for the ci-runner CLI.\n *\n * @returns Human-readable usage text.\n */\nexport const getCliHelpText = (): string => {\n return [\n 'Usage: ci-runner [options]',\n '',\n 'Options:',\n ' --config <path> Config file path (default: ci.config.ts or ci.config.json)',\n ' --format <type> Output format: pretty | json (default: pretty)',\n ' --verbose Show stdout/stderr for successful steps',\n ' --watch Re-run on file changes',\n ' --fail-fast Stop after first non-optional failure',\n ' --cwd <path> Base working directory',\n ' -h, --help Show this help',\n ].join('\\n')\n}\n","import { spawn } from 'node:child_process'\n\nimport type {\n CommandExecutionRequest,\n CommandExecutionResult,\n CommandExecutor,\n} from '../contracts/executor.js'\n\n/**\n * Creates a Node.js shell command executor.\n *\n * @returns Command executor implementation.\n */\nexport const createNodeCommandExecutor = (): CommandExecutor => {\n return async (request: CommandExecutionRequest): Promise<CommandExecutionResult> => {\n const startedAt = Date.now()\n\n return await new Promise<CommandExecutionResult>((resolve) => {\n const env: NodeJS.ProcessEnv = { ...process.env, ...request.env }\n const child = spawn(request.command, {\n cwd: request.cwd,\n env,\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n\n let stdout = ''\n let stderr = ''\n let timedOut = false\n let error: unknown\n let closed = false\n\n const timeoutHandle =\n typeof request.timeoutMs === 'number' && request.timeoutMs > 0\n ? setTimeout(() => {\n timedOut = true\n child.kill('SIGTERM')\n }, request.timeoutMs)\n : null\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8')\n })\n\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8')\n })\n\n child.on('error', (spawnError: Error) => {\n error = spawnError\n })\n\n child.on('close', (exitCode: number | null, signal: NodeJS.Signals | null) => {\n if (closed) {\n return\n }\n\n closed = true\n if (timeoutHandle) {\n clearTimeout(timeoutHandle)\n }\n\n const durationMs = Date.now() - startedAt\n const successful = !timedOut && exitCode === 0 && error === undefined\n\n resolve({\n successful,\n timedOut,\n durationMs,\n exitCode,\n signal,\n stdout,\n stderr,\n error,\n })\n })\n })\n }\n}\n","import type {\n ParsedStepMetrics,\n StepOutputParser,\n StepParserResolver,\n} from '../contracts/parser.js'\nimport type { PipelineStep, StepExecutionOutput } from '../contracts/step.js'\n\n/**\n * In-memory parser registry with ordered fallback resolution.\n */\nexport class StepParserRegistry implements StepParserResolver {\n private readonly parsers: StepOutputParser[]\n\n /**\n * Creates a parser registry.\n *\n * @param parsers Initial parser list.\n */\n public constructor(parsers: readonly StepOutputParser[] = []) {\n this.parsers = [...parsers]\n }\n\n /**\n * Adds a parser to the registry.\n *\n * @param parser Parser instance.\n */\n public register(parser: StepOutputParser): void {\n this.parsers.push(parser)\n }\n\n /**\n * Parses output using the first matching parser that returns a metric.\n *\n * @param step Step definition.\n * @param output Step output payload.\n * @returns Parsed metric or null.\n */\n public parse(step: PipelineStep, output: StepExecutionOutput): ParsedStepMetrics | null {\n for (const parser of this.parsers) {\n if (!parser.matches(step)) {\n continue\n }\n\n const parsed = parser.parse(output)\n if (parsed) {\n return parsed\n }\n }\n\n return null\n }\n}\n","import type { PipelineRunResult } from '../contracts/run.js'\n\n/**\n * Formats pipeline result data as JSON output.\n *\n * @param result Pipeline run result.\n * @param indentation Number of spaces used for indentation.\n * @returns JSON representation.\n */\nexport const formatPipelineResultAsJson = (result: PipelineRunResult, indentation = 2): string => {\n return JSON.stringify(result, null, indentation)\n}\n","import type { CommandExecutionResult } from '../contracts/executor.js'\nimport type { PipelineRunOptions, PipelineRunResult, PipelineSummary } from '../contracts/run.js'\nimport type { PipelineStep, StepResult, StepResultReason, StepStatus } from '../contracts/step.js'\n\n/**\n * Pipeline execution engine for sequential CI step orchestration.\n */\nexport class PipelineRunner {\n private readonly options: Required<\n Pick<PipelineRunOptions, 'continueOnError' | 'now' | 'sleep'>\n > &\n Omit<PipelineRunOptions, 'continueOnError' | 'now' | 'sleep'>\n\n /**\n * Creates a pipeline runner.\n *\n * @param options Runtime options.\n */\n public constructor(options: PipelineRunOptions) {\n this.options = {\n ...options,\n continueOnError: options.continueOnError ?? true,\n now: options.now ?? Date.now,\n sleep:\n options.sleep ??\n ((durationMs: number): Promise<void> => {\n return new Promise((resolve) => {\n setTimeout(resolve, durationMs)\n })\n }),\n }\n }\n\n /**\n * Executes all configured pipeline steps.\n *\n * @returns Final pipeline result.\n */\n public async run(): Promise<PipelineRunResult> {\n const runStartedAt = this.options.now()\n const stepResults: StepResult[] = []\n\n await this.emitPipelineStart()\n\n for (const [index, step] of this.options.steps.entries()) {\n await this.emitStepStart(step, index)\n\n const stepResult = await this.executeStep(step)\n stepResults.push(stepResult)\n\n await this.emitStepComplete(stepResult, index)\n\n const isHardFailure = stepResult.status === 'failed' || stepResult.status === 'timed_out'\n if (!this.options.continueOnError && isHardFailure) {\n break\n }\n }\n\n const runFinishedAt = this.options.now()\n const summary = buildSummary(stepResults, runFinishedAt - runStartedAt)\n const exitCode: 0 | 1 = summary.failed > 0 || summary.timedOut > 0 ? 1 : 0\n\n const result: PipelineRunResult = {\n steps: stepResults,\n summary,\n exitCode,\n startedAt: runStartedAt,\n finishedAt: runFinishedAt,\n }\n\n await this.emitPipelineComplete(result)\n\n return result\n }\n\n private async executeStep(step: PipelineStep): Promise<StepResult> {\n const startedAt = this.options.now()\n const retryPolicy = normalizeRetryPolicy(step)\n const mergedEnv: NodeJS.ProcessEnv = { ...this.options.env, ...step.env }\n\n let attempts = 0\n let lastExecution: CommandExecutionResult | null = null\n\n while (attempts < retryPolicy.maxAttempts) {\n attempts += 1\n\n const execution = await this.options.executor({\n command: step.command,\n cwd: step.cwd ?? this.options.cwd ?? process.cwd(),\n env: mergedEnv,\n timeoutMs: step.timeoutMs,\n })\n\n lastExecution = execution\n\n if (execution.successful) {\n return this.buildStepResult({\n step,\n status: 'passed',\n reason: undefined,\n attempts,\n startedAt,\n output: execution,\n })\n }\n\n const timedOut = execution.timedOut\n const canRetryTimeout = retryPolicy.retryOnTimeout && timedOut\n const canRetryFailure = !timedOut\n const canRetry =\n attempts < retryPolicy.maxAttempts &&\n (canRetryFailure || canRetryTimeout) &&\n retryPolicy.maxAttempts > 1\n\n if (canRetry) {\n if (retryPolicy.delayMs > 0) {\n await this.options.sleep(retryPolicy.delayMs)\n }\n continue\n }\n\n return this.buildFailedResult(step, attempts, startedAt, execution)\n }\n\n const fallbackOutput = createFallbackExecutionResult()\n\n return this.buildStepResult({\n step,\n status: 'failed',\n reason: 'command_failed',\n attempts,\n startedAt,\n output: lastExecution ?? fallbackOutput,\n })\n }\n\n private buildFailedResult(\n step: PipelineStep,\n attempts: number,\n startedAt: number,\n output: CommandExecutionResult\n ): StepResult {\n if (step.optional) {\n return this.buildStepResult({\n step,\n status: 'skipped',\n reason: 'optional_step_failed',\n attempts,\n startedAt,\n output,\n })\n }\n\n if (output.timedOut) {\n return this.buildStepResult({\n step,\n status: 'timed_out',\n reason: 'command_timeout',\n attempts,\n startedAt,\n output,\n })\n }\n\n return this.buildStepResult({\n step,\n status: 'failed',\n reason: 'command_failed',\n attempts,\n startedAt,\n output,\n })\n }\n\n private buildStepResult(input: {\n step: PipelineStep\n status: StepStatus\n reason: StepResultReason | undefined\n attempts: number\n startedAt: number\n output: CommandExecutionResult\n }): StepResult {\n const finishedAt = this.options.now()\n const metrics = this.options.parserResolver?.parse(input.step, input.output) ?? null\n\n return {\n id: input.step.id,\n name: input.step.name,\n status: input.status,\n reason: input.reason,\n attempts: input.attempts,\n retried: input.attempts > 1,\n startedAt: input.startedAt,\n finishedAt,\n durationMs: finishedAt - input.startedAt,\n output: {\n exitCode: input.output.exitCode,\n signal: input.output.signal,\n stdout: input.output.stdout,\n stderr: input.output.stderr,\n },\n metrics,\n }\n }\n\n private async emitPipelineStart(): Promise<void> {\n const reporters = this.options.reporters ?? []\n for (const reporter of reporters) {\n await reporter.onPipelineStart?.(this.options.steps)\n }\n }\n\n private async emitStepStart(step: PipelineStep, index: number): Promise<void> {\n const reporters = this.options.reporters ?? []\n for (const reporter of reporters) {\n await reporter.onStepStart?.(step, index)\n }\n }\n\n private async emitStepComplete(result: StepResult, index: number): Promise<void> {\n const reporters = this.options.reporters ?? []\n for (const reporter of reporters) {\n await reporter.onStepComplete?.(result, index)\n }\n }\n\n private async emitPipelineComplete(result: PipelineRunResult): Promise<void> {\n const reporters = this.options.reporters ?? []\n for (const reporter of reporters) {\n await reporter.onPipelineComplete?.(result)\n }\n }\n}\n\n/**\n * Creates a pipeline runner instance.\n *\n * @param options Runtime options.\n * @returns Pipeline runner.\n */\nexport const createPipelineRunner = (options: PipelineRunOptions): PipelineRunner => {\n return new PipelineRunner(options)\n}\n\nconst normalizeRetryPolicy = (\n step: PipelineStep\n): {\n maxAttempts: number\n delayMs: number\n retryOnTimeout: boolean\n} => {\n const maxAttempts = Math.max(1, step.retry?.maxAttempts ?? 1)\n const delayMs = Math.max(0, step.retry?.delayMs ?? 0)\n const retryOnTimeout = step.retry?.retryOnTimeout ?? false\n\n return {\n maxAttempts,\n delayMs,\n retryOnTimeout,\n }\n}\n\nconst buildSummary = (stepResults: readonly StepResult[], durationMs: number): PipelineSummary => {\n const passed = stepResults.filter((result) => result.status === 'passed').length\n const failed = stepResults.filter((result) => result.status === 'failed').length\n const skipped = stepResults.filter((result) => result.status === 'skipped').length\n const timedOut = stepResults.filter((result) => result.status === 'timed_out').length\n\n return {\n total: stepResults.length,\n passed,\n failed,\n skipped,\n timedOut,\n durationMs,\n }\n}\n\nconst createFallbackExecutionResult = (): CommandExecutionResult => {\n return {\n successful: false,\n timedOut: false,\n durationMs: 0,\n exitCode: null,\n signal: null,\n stdout: '',\n stderr: '',\n }\n}\n","import { resolve } from 'node:path'\n\nimport type { CiRunnerConfig, CliConfigStep } from './types.js'\n\n/**\n * Runtime step contract passed into the pipeline engine.\n */\nexport interface MappedPipelineStep {\n /** Stable step id. */\n readonly id: string\n /** Display name shown in output. */\n readonly name: string\n /** Shell command to execute. */\n readonly command: string\n /** Working directory override for this step. */\n readonly cwd?: string\n /** Environment additions for this step. */\n readonly env?: Readonly<Record<string, string>>\n /** Optional failure policy. */\n readonly optional?: boolean\n /** Step timeout in milliseconds. */\n readonly timeoutMs?: number\n /** Retry policy for this step. */\n readonly retry?: CliConfigStep['retry']\n}\n\n/**\n * Runtime options subset consumed by the pipeline engine.\n */\nexport interface MappedPipelineRunOptions {\n /** Ordered runtime steps. */\n readonly steps: readonly MappedPipelineStep[]\n /** Steps excluded from execution with reason metadata. */\n readonly excludedSteps: readonly ExcludedPipelineStep[]\n /** Base working directory for step execution. */\n readonly cwd: string\n /** Base environment for step execution. */\n readonly env: NodeJS.ProcessEnv\n /** Continue after hard failures when true. */\n readonly continueOnError: boolean\n}\n\n/**\n * Exclusion metadata for one configured step.\n */\nexport interface ExcludedPipelineStep {\n /** Stable step id. */\n readonly id: string\n /** Display name shown in output. */\n readonly name: string\n /** Machine-readable exclusion reason. */\n readonly reason: 'disabled' | 'env_mismatch'\n /** Required environment values when excluded by env mismatch. */\n readonly requiredEnv?: Readonly<Record<string, string>>\n}\n\ninterface StepExclusion {\n readonly reason: ExcludedPipelineStep['reason']\n readonly requiredEnv?: Readonly<Record<string, string>>\n}\n\n/**\n * Maps loaded config to core run options.\n *\n * @param config Parsed CLI config.\n * @param cwd Base working directory.\n * @param failFast CLI fail-fast override.\n * @returns Core run options subset.\n */\nexport const mapConfigToRun = (\n config: CiRunnerConfig,\n cwd: string,\n failFast: boolean\n): MappedPipelineRunOptions => {\n const runCwd = config.cwd ? resolve(cwd, config.cwd) : cwd\n const env = { ...process.env, ...config.env }\n\n const steps: MappedPipelineStep[] = []\n const excludedSteps: ExcludedPipelineStep[] = []\n\n for (const step of config.steps) {\n const exclusion = getExclusion(step, env)\n if (exclusion) {\n excludedSteps.push({\n id: step.id,\n name: step.name,\n reason: exclusion.reason,\n requiredEnv: exclusion.requiredEnv,\n })\n continue\n }\n\n steps.push(mapStep(step, runCwd))\n }\n\n const continueOnError = failFast ? false : (config.continueOnError ?? true)\n\n return {\n steps,\n excludedSteps,\n cwd: runCwd,\n env,\n continueOnError,\n }\n}\n\nconst mapStep = (step: CliConfigStep, runCwd: string): MappedPipelineStep => {\n return {\n id: step.id,\n name: step.name,\n command: step.command,\n cwd: step.cwd ? resolve(runCwd, step.cwd) : runCwd,\n env: step.env,\n optional: step.optional,\n timeoutMs: step.timeoutMs,\n retry: step.retry,\n }\n}\n\nconst getExclusion = (step: CliConfigStep, env: NodeJS.ProcessEnv): StepExclusion | null => {\n if (step.enabled === false) {\n return { reason: 'disabled' }\n }\n\n const envConditions = step.when?.env\n if (!envConditions) {\n return null\n }\n\n const missingConditions: Record<string, string> = {}\n\n for (const [key, expectedValue] of Object.entries(envConditions)) {\n if (env[key] !== expectedValue) {\n missingConditions[key] = expectedValue\n }\n }\n\n if (Object.keys(missingConditions).length > 0) {\n return {\n reason: 'env_mismatch',\n requiredEnv: missingConditions,\n }\n }\n\n return null\n}\n","import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nimport ts from 'typescript'\n\nimport type { CiRunnerConfig, CliConfigStep } from './types.js'\n\n/**\n * Loads and validates a ci-runner config file.\n *\n * @param cwd Base working directory.\n * @param configPath Optional explicit config file path.\n * @returns Parsed config with resolved metadata.\n * @throws Error when config cannot be loaded or is invalid.\n */\nexport const loadCiRunnerConfig = async (\n cwd: string,\n configPath?: string\n): Promise<{ config: CiRunnerConfig; configFilePath: string }> => {\n const resolvedConfigPath = await resolveConfigPath(cwd, configPath)\n if (!resolvedConfigPath) {\n throw new Error('No config file found. Expected ci.config.ts or ci.config.json')\n }\n\n const loadedConfig = await loadConfigByExtension(resolvedConfigPath)\n const config = parseCiRunnerConfig(loadedConfig)\n\n return {\n config,\n configFilePath: resolvedConfigPath,\n }\n}\n\nconst resolveConfigPath = async (cwd: string, configPath?: string): Promise<string | null> => {\n if (configPath) {\n return resolve(cwd, configPath)\n }\n\n const candidates = [resolve(cwd, 'ci.config.ts'), resolve(cwd, 'ci.config.json')]\n\n for (const candidate of candidates) {\n try {\n await readFile(candidate, 'utf8')\n return candidate\n } catch {\n continue\n }\n }\n\n return null\n}\n\nconst loadConfigByExtension = async (configFilePath: string): Promise<unknown> => {\n if (configFilePath.endsWith('.json')) {\n const content = await readFile(configFilePath, 'utf8')\n return JSON.parse(content) as unknown\n }\n\n if (configFilePath.endsWith('.ts')) {\n return await loadTypeScriptConfig(configFilePath)\n }\n\n throw new Error(`Unsupported config extension: ${configFilePath}`)\n}\n\nconst loadTypeScriptConfig = async (configFilePath: string): Promise<unknown> => {\n const source = await readFile(configFilePath, 'utf8')\n const transpiled = ts.transpileModule(source, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ES2022,\n esModuleInterop: true,\n },\n fileName: configFilePath,\n reportDiagnostics: true,\n })\n\n if (transpiled.diagnostics && transpiled.diagnostics.length > 0) {\n const message = ts.formatDiagnosticsWithColorAndContext(transpiled.diagnostics, {\n getCurrentDirectory: (): string => dirname(configFilePath),\n getCanonicalFileName: (fileName: string): string => fileName,\n getNewLine: (): string => '\\n',\n })\n throw new Error(`Failed to transpile ${configFilePath}\\n${message}`)\n }\n\n const tempDirectory = await mkdtemp(resolve(tmpdir(), 'ci-runner-config-'))\n const tempFilePath = resolve(tempDirectory, 'config.mjs')\n\n try {\n await writeFile(tempFilePath, transpiled.outputText, 'utf8')\n const moduleUrl = `${pathToFileURL(tempFilePath).href}?v=${Date.now()}`\n const loadedModule = (await import(moduleUrl)) as {\n readonly default?: unknown\n readonly config?: unknown\n }\n\n if (loadedModule.default !== undefined) {\n return unwrapNestedDefault(loadedModule.default)\n }\n\n if (loadedModule.config !== undefined) {\n return loadedModule.config\n }\n\n throw new Error(`Config module ${configFilePath} must export default or named \"config\"`)\n } finally {\n await rm(tempDirectory, { recursive: true, force: true })\n }\n}\n\nconst unwrapNestedDefault = (value: unknown): unknown => {\n if (!isRecord(value)) {\n return value\n }\n\n if ('default' in value) {\n return value.default\n }\n\n return value\n}\n\nconst parseCiRunnerConfig = (value: unknown): CiRunnerConfig => {\n if (!isRecord(value)) {\n throw new Error('Config must be an object')\n }\n\n const stepsValue = value.steps\n if (!Array.isArray(stepsValue)) {\n throw new Error('Config must provide a steps array')\n }\n\n const steps = stepsValue.map(parseConfigStep)\n\n const continueOnError = parseOptionalBoolean(value.continueOnError, 'continueOnError')\n const env = parseOptionalStringRecord(value.env, 'env')\n const cwd = parseOptionalString(value.cwd, 'cwd')\n\n const output = parseOutputConfig(value.output)\n\n return {\n steps,\n continueOnError,\n env,\n cwd,\n output,\n }\n}\n\nconst parseConfigStep = (value: unknown, index: number): CliConfigStep => {\n if (!isRecord(value)) {\n throw new Error(`steps[${index}] must be an object`)\n }\n\n const id = parseRequiredString(value.id, `steps[${index}].id`)\n const name = parseRequiredString(value.name, `steps[${index}].name`)\n const command = parseRequiredString(value.command, `steps[${index}].command`)\n const enabled = parseOptionalBoolean(value.enabled, `steps[${index}].enabled`)\n const cwd = parseOptionalString(value.cwd, `steps[${index}].cwd`)\n const env = parseOptionalStringRecord(value.env, `steps[${index}].env`)\n const optional = parseOptionalBoolean(value.optional, `steps[${index}].optional`)\n const timeoutMs = parseOptionalNumber(value.timeoutMs, `steps[${index}].timeoutMs`)\n const retry = parseOptionalRetry(value.retry, `steps[${index}].retry`)\n const when = parseOptionalCondition(value.when, `steps[${index}].when`)\n\n return {\n id,\n name,\n command,\n enabled,\n cwd,\n env,\n optional,\n timeoutMs,\n retry,\n when,\n }\n}\n\nconst parseOutputConfig = (value: unknown): CiRunnerConfig['output'] | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (!isRecord(value)) {\n throw new Error('output must be an object')\n }\n\n const format = value.format\n if (format !== undefined && format !== 'pretty' && format !== 'json') {\n throw new Error('output.format must be \"pretty\" or \"json\"')\n }\n\n const verbose = parseOptionalBoolean(value.verbose, 'output.verbose')\n\n return {\n format,\n verbose,\n }\n}\n\nconst parseOptionalRetry = (value: unknown, path: string): CliConfigStep['retry'] | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (!isRecord(value)) {\n throw new Error(`${path} must be an object`)\n }\n\n const maxAttempts = parseRequiredNumber(value.maxAttempts, `${path}.maxAttempts`)\n const delayMs = parseOptionalNumber(value.delayMs, `${path}.delayMs`)\n const retryOnTimeout = parseOptionalBoolean(value.retryOnTimeout, `${path}.retryOnTimeout`)\n\n return {\n maxAttempts,\n delayMs,\n retryOnTimeout,\n }\n}\n\nconst parseOptionalCondition = (\n value: unknown,\n path: string\n): CliConfigStep['when'] | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (!isRecord(value)) {\n throw new Error(`${path} must be an object`)\n }\n\n const env = parseOptionalStringRecord(value.env, `${path}.env`)\n\n return {\n env,\n }\n}\n\nconst parseRequiredString = (value: unknown, path: string): string => {\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`${path} must be a non-empty string`)\n }\n\n return value\n}\n\nconst parseRequiredNumber = (value: unknown, path: string): number => {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n throw new Error(`${path} must be a valid number`)\n }\n\n return value\n}\n\nconst parseOptionalString = (value: unknown, path: string): string | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (typeof value !== 'string') {\n throw new Error(`${path} must be a string`)\n }\n\n return value\n}\n\nconst parseOptionalNumber = (value: unknown, path: string): number | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (typeof value !== 'number' || Number.isNaN(value)) {\n throw new Error(`${path} must be a valid number`)\n }\n\n return value\n}\n\nconst parseOptionalBoolean = (value: unknown, path: string): boolean | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (typeof value !== 'boolean') {\n throw new Error(`${path} must be a boolean`)\n }\n\n return value\n}\n\nconst parseOptionalStringRecord = (\n value: unknown,\n path: string\n): Readonly<Record<string, string>> | undefined => {\n if (value === undefined) {\n return undefined\n }\n\n if (!isRecord(value)) {\n throw new Error(`${path} must be an object`)\n }\n\n const entries = Object.entries(value)\n const parsed: Record<string, string> = {}\n\n for (const [key, entryValue] of entries) {\n if (typeof entryValue !== 'string') {\n throw new Error(`${path}.${key} must be a string`)\n }\n parsed[key] = entryValue\n }\n\n return parsed\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import type { ParsedStepMetrics, StepOutputParser } from '../internal/core/index.js'\n\n/**\n * Creates default parsers for common test outputs.\n *\n * @returns Parser list.\n */\nexport const createDefaultStepParsers = (): readonly StepOutputParser[] => {\n return [\n {\n id: 'vitest-summary-parser',\n matches: (step): boolean => {\n return stepContainsKeyword(step, 'vitest')\n },\n parse: (output): ParsedStepMetrics | null => {\n const cleanOutput = stripAnsi(`${output.stdout}\\n${output.stderr}`)\n const vitestMatch = cleanOutput.match(/\\bTests?\\s+(\\d+)\\s+passed\\b/i)\n if (!vitestMatch) {\n return null\n }\n\n return {\n label: 'tests_passed',\n value: Number(vitestMatch[1]),\n }\n },\n },\n {\n id: 'playwright-summary-parser',\n matches: (step): boolean => {\n return stepContainsKeyword(step, 'playwright') || stepContainsKeyword(step, 'e2e')\n },\n parse: (output): ParsedStepMetrics | null => {\n const cleanOutput = stripAnsi(`${output.stdout}\\n${output.stderr}`)\n const playwrightMatch = cleanOutput.match(/^\\s*(\\d+)\\s+passed(?:\\s|\\()/im)\n if (!playwrightMatch) {\n return null\n }\n\n return {\n label: 'tests_passed',\n value: Number(playwrightMatch[1]),\n }\n },\n },\n {\n id: 'generic-tests-parser',\n matches: (step): boolean => {\n return stepContainsKeyword(step, 'test')\n },\n parse: (output): ParsedStepMetrics | null => {\n const cleanOutput = stripAnsi(`${output.stdout}\\n${output.stderr}`)\n const genericMatch = cleanOutput.match(/(^|\\s)(\\d+)\\s+passed(\\s|$)/i)\n if (!genericMatch) {\n return null\n }\n\n return {\n label: 'tests_passed',\n value: Number(genericMatch[2]),\n }\n },\n },\n {\n id: 'lint-warning-summary-parser',\n matches: (step): boolean => {\n return stepContainsKeyword(step, 'lint')\n },\n parse: (output): ParsedStepMetrics | null => {\n const cleanOutput = stripAnsi(`${output.stdout}\\n${output.stderr}`)\n const warnings = parseLintWarnings(cleanOutput)\n if (warnings === null) {\n return null\n }\n\n return {\n label: 'warnings',\n value: warnings,\n }\n },\n },\n {\n id: 'workspace-task-summary-parser',\n matches: (): boolean => true,\n parse: (output): ParsedStepMetrics | null => {\n const cleanOutput = stripAnsi(`${output.stdout}\\n${output.stderr}`)\n return parseWorkspaceTaskMetric(cleanOutput)\n },\n },\n ]\n}\n\nconst parseWorkspaceTaskMetric = (cleanOutput: string): ParsedStepMetrics | null => {\n const turboTaskMatch = cleanOutput.match(/Tasks:\\s*\\d+\\s+\\w+,\\s*(\\d+)\\s+total/i)\n if (turboTaskMatch) {\n return {\n label: 'tasks',\n value: Number(turboTaskMatch[1]),\n }\n }\n\n const pnpmScopeMatch = cleanOutput.match(\n /Scope:\\s*(?:all\\s+)?(\\d+)(?:\\s+of\\s+\\d+)?\\s+workspace\\s+projects?/i\n )\n if (pnpmScopeMatch) {\n return {\n label: 'tasks',\n value: Number(pnpmScopeMatch[1]),\n }\n }\n\n const nxProjectMatch = cleanOutput.match(/Successfully ran target .* for (\\d+) projects?/i)\n if (nxProjectMatch) {\n return {\n label: 'tasks',\n value: Number(nxProjectMatch[1]),\n }\n }\n\n const taskHeaders = extractPnpmTaskHeaders(cleanOutput)\n if (taskHeaders.length > 0) {\n return {\n label: 'tasks',\n value: taskHeaders.length,\n }\n }\n\n return null\n}\n\nconst parseLintWarnings = (cleanOutput: string): number | null => {\n const warningMatches = [\n ...cleanOutput.matchAll(/✖\\s+\\d+\\s+problems?\\s+\\(\\s*\\d+\\s+errors?,\\s*(\\d+)\\s+warnings?\\s*\\)/gi),\n ]\n if (warningMatches.length === 0) {\n return null\n }\n\n const warnings = warningMatches.reduce((sum, match) => {\n const warningCountText = match[1]\n if (!warningCountText) {\n return sum\n }\n\n return sum + Number(warningCountText)\n }, 0)\n\n return warnings\n}\n\nconst extractPnpmTaskHeaders = (cleanOutput: string): readonly string[] => {\n const headerMatches =\n cleanOutput.match(/(^|\\n)(?!\\s*[|│])([^\\n$]+?\\s+[a-z0-9:_-]+\\$\\s[^\\n]*)/gi) ?? []\n const normalized = headerMatches\n .map((line) => line.replace(/^\\s+/, '').trim())\n .map((line) => line.replace(/\\s+/g, ' '))\n\n return [...new Set(normalized)]\n}\n\nconst stepContainsKeyword = (\n step: {\n readonly id: string\n readonly name: string\n readonly command: string\n },\n keyword: string\n): boolean => {\n const source = `${step.id} ${step.name} ${step.command}`.toLowerCase()\n return source.includes(keyword)\n}\n\nconst stripAnsi = (text: string): string => {\n // eslint-disable-next-line no-control-regex\n return text.replace(/\\x1b\\[[0-9;]*m/g, '')\n}\n","import type {\n PipelineReporter,\n PipelineRunResult,\n PipelineStep,\n StepResult,\n} from '../internal/core/index.js'\n\n/**\n * Options for the pretty console reporter.\n */\nexport interface PrettyReporterOptions {\n /** Emits stdout/stderr also for successful steps. */\n readonly verbose: boolean\n}\n\n/**\n * Compact console reporter with failure-focused detail output.\n */\nexport class PrettyReporter implements PipelineReporter {\n private readonly options: PrettyReporterOptions\n\n /**\n * Creates a pretty reporter.\n *\n * @param options Reporter options.\n */\n public constructor(options: PrettyReporterOptions) {\n this.options = options\n }\n\n /**\n * Handles pipeline start.\n *\n * @param steps Pipeline steps.\n */\n public onPipelineStart(steps: readonly PipelineStep[]): void {\n process.stdout.write(colorize(`ci-runner: executing ${steps.length} steps\\n`, 'blue'))\n }\n\n /**\n * Handles step start.\n *\n * @param step Current step.\n */\n public onStepStart(step: PipelineStep): void {\n process.stdout.write(colorize(`-> ${step.name}\\n`, 'blue'))\n }\n\n /**\n * Handles step completion.\n *\n * @param result Step result.\n */\n public onStepComplete(result: StepResult): void {\n const duration = `${result.durationMs}ms`\n if (result.status === 'passed') {\n const metricText =\n result.metrics && typeof result.metrics.value === 'number'\n ? ` (${result.metrics.value} ${result.metrics.label})`\n : ''\n process.stdout.write(colorize(`✓ ${result.name} ${duration}${metricText}\\n`, 'green'))\n if (this.options.verbose) {\n this.printOutput(result)\n }\n return\n }\n\n if (result.status === 'skipped') {\n process.stdout.write(\n colorize(\n `ℹ ${result.name} skipped (${result.reason ?? 'no reason'}, ${duration})\\n`,\n 'yellow'\n )\n )\n const missingScript = extractMissingScript(result)\n if (missingScript) {\n process.stdout.write(colorize(` note: missing script \"${missingScript}\"\\n`, 'yellow'))\n if (this.options.verbose) {\n this.printOutput(result)\n }\n return\n }\n\n this.printOutput(result)\n return\n }\n\n process.stdout.write(\n colorize(\n `✗ ${result.name} ${result.status} (${result.reason ?? 'no reason'}, ${duration})\\n`,\n 'red'\n )\n )\n this.printOutput(result)\n }\n\n /**\n * Handles pipeline completion.\n *\n * @param result Pipeline result.\n */\n public onPipelineComplete(result: PipelineRunResult): void {\n const summary = result.summary\n process.stdout.write('\\n')\n process.stdout.write(\n `Summary: total=${summary.total} passed=${summary.passed} skipped=${summary.skipped} failed=${summary.failed} timedOut=${summary.timedOut} duration=${summary.durationMs}ms\\n`\n )\n\n if (result.exitCode === 0) {\n process.stdout.write(colorize('Result: ✅ PASS\\n', 'green'))\n return\n }\n\n process.stdout.write(colorize('Result: FAIL\\n', 'red'))\n }\n\n private printOutput(result: StepResult): void {\n const stdout = result.output.stdout.trim()\n const stderr = result.output.stderr.trim()\n\n if (stdout) {\n process.stdout.write(colorize(' stdout:\\n', 'yellow'))\n process.stdout.write(indent(stdout))\n process.stdout.write('\\n')\n }\n\n if (stderr) {\n process.stdout.write(colorize(' stderr:\\n', 'yellow'))\n process.stdout.write(indent(stderr))\n process.stdout.write('\\n')\n }\n }\n}\n\nconst indent = (text: string): string => {\n return text\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n')\n}\n\nconst colorize = (text: string, color: 'red' | 'green' | 'yellow' | 'blue'): string => {\n const colors: Record<'red' | 'green' | 'yellow' | 'blue', string> = {\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n }\n\n return `${colors[color]}${text}\\x1b[0m`\n}\n\nconst extractMissingScript = (result: StepResult): string | null => {\n const combinedOutput = `${result.output.stdout}\\n${result.output.stderr}`\n const match = combinedOutput.match(/Missing script:\\s*\"?([a-z0-9:_-]+)\"?/i)\n if (!match || !match[1]) {\n return null\n }\n\n return match[1]\n}\n","import { watch } from 'node:fs'\nimport { relative } from 'node:path'\n\nimport {\n createNodeCommandExecutor,\n createPipelineRunner,\n formatPipelineResultAsJson,\n StepParserRegistry,\n type PipelineRunResult,\n} from './internal/core/index.js'\n\nimport { mapConfigToRun, type ExcludedPipelineStep } from './config/mapConfigToRun.js'\nimport { loadCiRunnerConfig } from './config/loadConfig.js'\nimport type { CliOutputFormat } from './config/types.js'\nimport { createDefaultStepParsers } from './parsers/defaultStepParsers.js'\nimport { PrettyReporter } from './reporters/prettyReporter.js'\n\n/**\n * Runtime options for a CLI execution.\n */\nexport interface RunCliPipelineOptions {\n /** Base working directory. */\n readonly cwd: string\n /** Optional explicit config path. */\n readonly configPath?: string\n /** Output format selection. */\n readonly format: CliOutputFormat\n /** Verbose output mode. */\n readonly verbose: boolean\n /** Enables fail-fast behavior. */\n readonly failFast: boolean\n /** Enables watch mode. */\n readonly watch: boolean\n}\n\n/**\n * Executes the pipeline according to CLI options.\n *\n * @param options CLI runtime options.\n * @returns Final exit code.\n */\nexport const runCliPipeline = async (options: RunCliPipelineOptions): Promise<number> => {\n const loadedConfig = await loadCiRunnerConfig(options.cwd, options.configPath)\n const effectiveFormat = loadedConfig.config.output?.format ?? options.format\n const effectiveVerbose = loadedConfig.config.output?.verbose ?? options.verbose\n\n const execute = async (): Promise<PipelineRunResult> => {\n const mappedRun = mapConfigToRun(loadedConfig.config, options.cwd, options.failFast)\n printExcludedStepHints(mappedRun.excludedSteps, effectiveFormat)\n const parserRegistry = new StepParserRegistry(createDefaultStepParsers())\n\n const runner = createPipelineRunner({\n ...mappedRun,\n executor: createNodeCommandExecutor(),\n parserResolver: parserRegistry,\n reporters:\n effectiveFormat === 'pretty' ? [new PrettyReporter({ verbose: effectiveVerbose })] : [],\n })\n\n return await runner.run()\n }\n\n if (!options.watch) {\n const result = await execute()\n if (effectiveFormat === 'json') {\n process.stdout.write(`${formatPipelineResultAsJson(result)}\\n`)\n }\n return result.exitCode\n }\n\n return await runWatchLoop(options.cwd, loadedConfig.configFilePath, effectiveFormat, execute)\n}\n\nconst printExcludedStepHints = (\n excludedSteps: readonly ExcludedPipelineStep[],\n format: CliOutputFormat\n): void => {\n if (format !== 'pretty' || excludedSteps.length === 0) {\n return\n }\n\n for (const step of excludedSteps) {\n if (step.reason === 'disabled') {\n process.stdout.write(`ℹ️ Skipping ${step.name} (enabled=false)\\n`)\n continue\n }\n\n if (step.reason === 'env_mismatch' && step.requiredEnv) {\n process.stdout.write(\n `ℹ️ Skipping ${step.name} (set ${formatRequiredEnv(step.requiredEnv)} to enable)\\n`\n )\n continue\n }\n\n process.stdout.write(`ℹ️ Skipping ${step.name}\\n`)\n }\n}\n\nconst formatRequiredEnv = (requiredEnv: Readonly<Record<string, string>>): string => {\n return Object.entries(requiredEnv)\n .sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))\n .map(([key, value]) => `${key}=${value}`)\n .join(' ')\n}\n\nconst runWatchLoop = async (\n cwd: string,\n configFilePath: string,\n format: CliOutputFormat,\n execute: () => Promise<PipelineRunResult>\n): Promise<number> => {\n const initialResult = await execute()\n if (format === 'json') {\n process.stdout.write(`${formatPipelineResultAsJson(initialResult)}\\n`)\n }\n\n process.stdout.write('Watch mode enabled. Waiting for file changes...\\n')\n\n let lastExitCode = initialResult.exitCode\n let running = false\n let rerunPending = false\n let debounceHandle: NodeJS.Timeout | null = null\n\n const runWithLock = async (): Promise<void> => {\n if (running) {\n rerunPending = true\n return\n }\n\n running = true\n try {\n do {\n rerunPending = false\n const result = await execute()\n lastExitCode = result.exitCode\n if (format === 'json') {\n process.stdout.write(`${formatPipelineResultAsJson(result)}\\n`)\n }\n } while (rerunPending)\n } finally {\n running = false\n }\n }\n\n const watcher = createWatcher(cwd, configFilePath, () => {\n if (debounceHandle) {\n clearTimeout(debounceHandle)\n }\n\n debounceHandle = setTimeout(() => {\n void runWithLock()\n }, 250)\n })\n\n await new Promise<void>((resolve) => {\n const stop = (): void => {\n watcher.close()\n if (debounceHandle) {\n clearTimeout(debounceHandle)\n }\n resolve()\n }\n\n process.on('SIGINT', stop)\n process.on('SIGTERM', stop)\n })\n\n return lastExitCode\n}\n\nconst createWatcher = (\n cwd: string,\n configFilePath: string,\n onRelevantChange: () => void\n): { close: () => void } => {\n const ignorePrefixes = ['node_modules', '.git', 'dist', 'coverage', 'out', 'build', '.tmp']\n\n try {\n const watcher = watch(cwd, { recursive: true }, (_, fileName) => {\n if (!fileName) {\n return\n }\n\n const relativePath = fileName.toString()\n if (shouldIgnore(relativePath, ignorePrefixes)) {\n return\n }\n\n const normalizedConfigPath = relative(cwd, configFilePath)\n const messagePath =\n relativePath === normalizedConfigPath ? `${relativePath} (config)` : relativePath\n process.stdout.write(`\\nChange detected: ${messagePath}\\n`)\n onRelevantChange()\n })\n\n return {\n close: (): void => watcher.close(),\n }\n } catch {\n process.stdout.write(\n 'Watch mode is not supported recursively on this platform. Running once without watch.\\n'\n )\n\n return {\n close: (): void => undefined,\n }\n }\n}\n\nconst shouldIgnore = (filePath: string, prefixes: readonly string[]): boolean => {\n return prefixes.some((prefix) => filePath === prefix || filePath.startsWith(`${prefix}/`))\n}\n","#!/usr/bin/env node\n\nimport { getCliHelpText, parseCliOptions } from './cliOptions.js'\nimport { runCliPipeline } from './runPipeline.js'\n\nconst run = async (): Promise<void> => {\n const options = parseCliOptions(process.argv.slice(2), process.cwd())\n\n if (options.help) {\n process.stdout.write(`${getCliHelpText()}\\n`)\n process.exitCode = 0\n return\n }\n\n const exitCode = await runCliPipeline(options)\n process.exitCode = exitCode\n}\n\nvoid run().catch((error: unknown) => {\n const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error)\n process.stderr.write(`${message}\\n`)\n process.exitCode = 1\n})\n"],"names":["parseCliOptions","argv","baseCwd","configPath","format","verbose","watch","failFast","help","cwd","index","argument","nextValue","value","resolve","getCliHelpText","createNodeCommandExecutor","request","startedAt","env","child","spawn","stdout","stderr","timedOut","error","closed","timeoutHandle","chunk","spawnError","exitCode","signal","durationMs","StepParserRegistry","parsers","parser","step","output","parsed","formatPipelineResultAsJson","result","indentation","PipelineRunner","options","runStartedAt","stepResults","stepResult","isHardFailure","runFinishedAt","summary","buildSummary","retryPolicy","normalizeRetryPolicy","mergedEnv","attempts","lastExecution","execution","canRetryTimeout","canRetryFailure","fallbackOutput","createFallbackExecutionResult","input","finishedAt","metrics","reporters","reporter","createPipelineRunner","maxAttempts","delayMs","retryOnTimeout","passed","failed","skipped","mapConfigToRun","config","runCwd","steps","excludedSteps","exclusion","getExclusion","mapStep","continueOnError","envConditions","missingConditions","key","expectedValue","loadCiRunnerConfig","resolvedConfigPath","resolveConfigPath","loadedConfig","loadConfigByExtension","parseCiRunnerConfig","candidates","candidate","readFile","configFilePath","content","loadTypeScriptConfig","source","transpiled","ts","message","dirname","fileName","tempDirectory","mkdtemp","tmpdir","tempFilePath","writeFile","loadedModule","pathToFileURL","unwrapNestedDefault","rm","isRecord","stepsValue","parseConfigStep","parseOptionalBoolean","parseOptionalStringRecord","parseOptionalString","parseOutputConfig","id","parseRequiredString","name","command","enabled","optional","timeoutMs","parseOptionalNumber","retry","parseOptionalRetry","when","parseOptionalCondition","path","parseRequiredNumber","entries","entryValue","createDefaultStepParsers","stepContainsKeyword","vitestMatch","stripAnsi","playwrightMatch","genericMatch","cleanOutput","warnings","parseLintWarnings","parseWorkspaceTaskMetric","turboTaskMatch","pnpmScopeMatch","nxProjectMatch","taskHeaders","extractPnpmTaskHeaders","warningMatches","sum","match","warningCountText","normalized","line","keyword","text","PrettyReporter","colorize","duration","metricText","missingScript","extractMissingScript","indent","color","runCliPipeline","effectiveFormat","effectiveVerbose","execute","mappedRun","printExcludedStepHints","parserRegistry","runWatchLoop","formatRequiredEnv","requiredEnv","leftKey","rightKey","initialResult","lastExitCode","running","rerunPending","debounceHandle","runWithLock","watcher","createWatcher","stop","onRelevantChange","ignorePrefixes","_","relativePath","shouldIgnore","normalizedConfigPath","relative","messagePath","filePath","prefixes","prefix","run"],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { CliOutputFormat } from './config/types.js';
2
+ /**
3
+ * Parsed CLI runtime options.
4
+ */
5
+ export interface CliOptions {
6
+ /** Absolute working directory for config and execution. */
7
+ readonly cwd: string;
8
+ /** Optional explicit config file path. */
9
+ readonly configPath?: string;
10
+ /** Selected output format. */
11
+ readonly format: CliOutputFormat;
12
+ /** Emits full output for successful steps when true. */
13
+ readonly verbose: boolean;
14
+ /** Enables rerun mode on file changes when true. */
15
+ readonly watch: boolean;
16
+ /** Stops on first hard failure when true. */
17
+ readonly failFast: boolean;
18
+ /** Prints usage and exits when true. */
19
+ readonly help: boolean;
20
+ }
21
+ /**
22
+ * Parses process arguments for the ci-runner CLI.
23
+ *
24
+ * @param argv Raw argument list excluding node and script path.
25
+ * @param baseCwd Base working directory.
26
+ * @returns Parsed CLI options.
27
+ * @throws Error when an argument is invalid.
28
+ */
29
+ export declare const parseCliOptions: (argv: readonly string[], baseCwd: string) => CliOptions;
30
+ /**
31
+ * Returns help text for the ci-runner CLI.
32
+ *
33
+ * @returns Human-readable usage text.
34
+ */
35
+ export declare const getCliHelpText: () => string;
36
+ //# sourceMappingURL=cliOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cliOptions.d.ts","sourceRoot":"","sources":["../src/cliOptions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,SAAS,MAAM,EAAE,EAAE,SAAS,MAAM,KAAG,UAmG1E,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAO,MAajC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import type { CiRunnerConfig } from './types.js';
2
+ /**
3
+ * Loads and validates a ci-runner config file.
4
+ *
5
+ * @param cwd Base working directory.
6
+ * @param configPath Optional explicit config file path.
7
+ * @returns Parsed config with resolved metadata.
8
+ * @throws Error when config cannot be loaded or is invalid.
9
+ */
10
+ export declare const loadCiRunnerConfig: (cwd: string, configPath?: string) => Promise<{
11
+ config: CiRunnerConfig;
12
+ configFilePath: string;
13
+ }>;
14
+ //# sourceMappingURL=loadConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadConfig.d.ts","sourceRoot":"","sources":["../../src/config/loadConfig.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,YAAY,CAAA;AAE/D;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,MAAM,EACX,aAAa,MAAM,KAClB,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAa5D,CAAA"}
@@ -0,0 +1,60 @@
1
+ import type { CiRunnerConfig, CliConfigStep } from './types.js';
2
+ /**
3
+ * Runtime step contract passed into the pipeline engine.
4
+ */
5
+ export interface MappedPipelineStep {
6
+ /** Stable step id. */
7
+ readonly id: string;
8
+ /** Display name shown in output. */
9
+ readonly name: string;
10
+ /** Shell command to execute. */
11
+ readonly command: string;
12
+ /** Working directory override for this step. */
13
+ readonly cwd?: string;
14
+ /** Environment additions for this step. */
15
+ readonly env?: Readonly<Record<string, string>>;
16
+ /** Optional failure policy. */
17
+ readonly optional?: boolean;
18
+ /** Step timeout in milliseconds. */
19
+ readonly timeoutMs?: number;
20
+ /** Retry policy for this step. */
21
+ readonly retry?: CliConfigStep['retry'];
22
+ }
23
+ /**
24
+ * Runtime options subset consumed by the pipeline engine.
25
+ */
26
+ export interface MappedPipelineRunOptions {
27
+ /** Ordered runtime steps. */
28
+ readonly steps: readonly MappedPipelineStep[];
29
+ /** Steps excluded from execution with reason metadata. */
30
+ readonly excludedSteps: readonly ExcludedPipelineStep[];
31
+ /** Base working directory for step execution. */
32
+ readonly cwd: string;
33
+ /** Base environment for step execution. */
34
+ readonly env: NodeJS.ProcessEnv;
35
+ /** Continue after hard failures when true. */
36
+ readonly continueOnError: boolean;
37
+ }
38
+ /**
39
+ * Exclusion metadata for one configured step.
40
+ */
41
+ export interface ExcludedPipelineStep {
42
+ /** Stable step id. */
43
+ readonly id: string;
44
+ /** Display name shown in output. */
45
+ readonly name: string;
46
+ /** Machine-readable exclusion reason. */
47
+ readonly reason: 'disabled' | 'env_mismatch';
48
+ /** Required environment values when excluded by env mismatch. */
49
+ readonly requiredEnv?: Readonly<Record<string, string>>;
50
+ }
51
+ /**
52
+ * Maps loaded config to core run options.
53
+ *
54
+ * @param config Parsed CLI config.
55
+ * @param cwd Base working directory.
56
+ * @param failFast CLI fail-fast override.
57
+ * @returns Core run options subset.
58
+ */
59
+ export declare const mapConfigToRun: (config: CiRunnerConfig, cwd: string, failFast: boolean) => MappedPipelineRunOptions;
60
+ //# sourceMappingURL=mapConfigToRun.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapConfigToRun.d.ts","sourceRoot":"","sources":["../../src/config/mapConfigToRun.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC7C,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACvD,iDAAiD;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,CAAA;IAC5C,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACxD;AAOD;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GACzB,QAAQ,cAAc,EACtB,KAAK,MAAM,EACX,UAAU,OAAO,KAChB,wBA+BF,CAAA"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Supported output formats for the CLI.
3
+ */
4
+ export type CliOutputFormat = 'pretty' | 'json';
5
+ /**
6
+ * Retry behavior for a config step.
7
+ */
8
+ export interface StepRetryPolicy {
9
+ /** Maximum execution attempts including the first run. */
10
+ readonly maxAttempts: number;
11
+ /** Delay between retry attempts in milliseconds. */
12
+ readonly delayMs?: number;
13
+ /** When true, retries are also allowed after timeout failures. */
14
+ readonly retryOnTimeout?: boolean;
15
+ }
16
+ /**
17
+ * Environment-based condition map for one step.
18
+ */
19
+ export interface CliStepCondition {
20
+ /**
21
+ * Exact environment variable matches required to execute a step.
22
+ */
23
+ readonly env?: Readonly<Record<string, string>>;
24
+ }
25
+ /**
26
+ * User-facing step definition loaded from config.
27
+ */
28
+ export interface CliConfigStep {
29
+ /** Stable step id. */
30
+ readonly id: string;
31
+ /** Display name shown in output. */
32
+ readonly name: string;
33
+ /** Shell command to execute. */
34
+ readonly command: string;
35
+ /** Enables execution for this step when true. */
36
+ readonly enabled?: boolean;
37
+ /** Relative or absolute working directory for this step. */
38
+ readonly cwd?: string;
39
+ /** Environment additions for this step. */
40
+ readonly env?: Readonly<Record<string, string>>;
41
+ /** Optional failure policy. */
42
+ readonly optional?: boolean;
43
+ /** Step timeout in milliseconds. */
44
+ readonly timeoutMs?: number;
45
+ /** Retry policy for this step. */
46
+ readonly retry?: StepRetryPolicy;
47
+ /** Optional execution condition. */
48
+ readonly when?: CliStepCondition;
49
+ }
50
+ /**
51
+ * Top-level CLI config model.
52
+ */
53
+ export interface CiRunnerConfig {
54
+ /** Ordered step list. */
55
+ readonly steps: readonly CliConfigStep[];
56
+ /** Continue running after hard failures when true. */
57
+ readonly continueOnError?: boolean;
58
+ /** Base environment merged into all steps. */
59
+ readonly env?: Readonly<Record<string, string>>;
60
+ /** Relative or absolute working directory for the whole pipeline. */
61
+ readonly cwd?: string;
62
+ /** Default output behavior from config. */
63
+ readonly output?: {
64
+ /** Preferred output format. */
65
+ readonly format?: CliOutputFormat;
66
+ /** Emits all step output on success when true. */
67
+ readonly verbose?: boolean;
68
+ };
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE/C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,kEAAkE;IAClE,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,iDAAiD;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAA;IAChC,oCAAoC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAA;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yBAAyB;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAA;IACxC,sDAAsD;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,+BAA+B;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAA;QACjC,kDAAkD;QAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAC3B,CAAA;CACF"}
@@ -0,0 +1,8 @@
1
+ export type { CliOptions } from './cliOptions.js';
2
+ export { getCliHelpText, parseCliOptions } from './cliOptions.js';
3
+ export type { CiRunnerConfig, CliConfigStep, CliOutputFormat, CliStepCondition, } from './config/types.js';
4
+ export { loadCiRunnerConfig } from './config/loadConfig.js';
5
+ export { mapConfigToRun } from './config/mapConfigToRun.js';
6
+ export type { RunCliPipelineOptions } from './runPipeline.js';
7
+ export { runCliPipeline } from './runPipeline.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjE,YAAY,EACV,cAAc,EACd,aAAa,EACb,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAE3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,35 @@
1
+ import type { StepExecutionOutput } from './step.js';
2
+ /**
3
+ * Input contract for command execution.
4
+ */
5
+ export interface CommandExecutionRequest {
6
+ /** Shell command to execute. */
7
+ readonly command: string;
8
+ /** Working directory used for this process. */
9
+ readonly cwd: string;
10
+ /** Environment variables merged for this process. */
11
+ readonly env: NodeJS.ProcessEnv;
12
+ /** Optional process timeout in milliseconds. */
13
+ readonly timeoutMs?: number;
14
+ }
15
+ /**
16
+ * Output contract from one command execution.
17
+ */
18
+ export interface CommandExecutionResult extends StepExecutionOutput {
19
+ /** True when command reached timeout handling path. */
20
+ readonly timedOut: boolean;
21
+ /** Total command duration in milliseconds. */
22
+ readonly durationMs: number;
23
+ /** True when command completed successfully. */
24
+ readonly successful: boolean;
25
+ /** Original error object for spawn-level failures. */
26
+ readonly error?: unknown;
27
+ }
28
+ /**
29
+ * Asynchronous abstraction for command execution.
30
+ *
31
+ * @param request Execution input data.
32
+ * @returns Command execution result.
33
+ */
34
+ export type CommandExecutor = (request: CommandExecutionRequest) => Promise<CommandExecutionResult>;
35
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../../src/internal/core/contracts/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,mBAAmB;IACjE,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,sBAAsB,CAAC,CAAA"}
@@ -0,0 +1,45 @@
1
+ import type { PipelineStep, StepExecutionOutput } from './step.js';
2
+ /**
3
+ * Structured metric extracted from raw command output.
4
+ */
5
+ export interface ParsedStepMetrics {
6
+ /** Human-readable metric label. */
7
+ readonly label: string;
8
+ /** Numeric or textual metric value. */
9
+ readonly value: number | string;
10
+ }
11
+ /**
12
+ * Parser contract for tool-specific output extraction.
13
+ */
14
+ export interface StepOutputParser {
15
+ /** Stable parser identifier. */
16
+ readonly id: string;
17
+ /**
18
+ * Checks whether this parser supports a step.
19
+ *
20
+ * @param step Step definition.
21
+ * @returns True when parser can parse this step output.
22
+ */
23
+ matches(step: PipelineStep): boolean;
24
+ /**
25
+ * Parses structured metrics from command output.
26
+ *
27
+ * @param output Captured process output.
28
+ * @returns Parsed metric or null when no metric could be extracted.
29
+ */
30
+ parse(output: StepExecutionOutput): ParsedStepMetrics | null;
31
+ }
32
+ /**
33
+ * Resolution interface for parser lookup and execution.
34
+ */
35
+ export interface StepParserResolver {
36
+ /**
37
+ * Parses output for a step using the first matching parser.
38
+ *
39
+ * @param step Step definition.
40
+ * @param output Captured process output.
41
+ * @returns Parsed metric or null.
42
+ */
43
+ parse(step: PipelineStep, output: StepExecutionOutput): ParsedStepMetrics | null;
44
+ }
45
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../src/internal/core/contracts/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAElE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IAEnB;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAA;IAEpC;;;;;OAKG;IACH,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,IAAI,CAAA;CAC7D;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,IAAI,CAAA;CACjF"}
@@ -0,0 +1,34 @@
1
+ import type { PipelineRunResult } from './run.js';
2
+ import type { PipelineStep, StepResult } from './step.js';
3
+ /**
4
+ * Event hooks for pipeline run reporting.
5
+ */
6
+ export interface PipelineReporter {
7
+ /**
8
+ * Called once before any step execution starts.
9
+ *
10
+ * @param steps Steps scheduled for execution.
11
+ */
12
+ onPipelineStart?(steps: readonly PipelineStep[]): Promise<void> | void;
13
+ /**
14
+ * Called before a single step starts.
15
+ *
16
+ * @param step Step definition.
17
+ * @param index Zero-based step index.
18
+ */
19
+ onStepStart?(step: PipelineStep, index: number): Promise<void> | void;
20
+ /**
21
+ * Called after a step completes.
22
+ *
23
+ * @param result Step execution result.
24
+ * @param index Zero-based step index.
25
+ */
26
+ onStepComplete?(result: StepResult, index: number): Promise<void> | void;
27
+ /**
28
+ * Called once after the pipeline completes.
29
+ *
30
+ * @param result Pipeline run result.
31
+ */
32
+ onPipelineComplete?(result: PipelineRunResult): Promise<void> | void;
33
+ }
34
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../../../src/internal/core/contracts/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEzD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,eAAe,CAAC,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAEtE;;;;;OAKG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAErE;;;;;OAKG;IACH,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAExE;;;;OAIG;IACH,kBAAkB,CAAC,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACrE"}
@@ -0,0 +1,60 @@
1
+ import type { CommandExecutor } from './executor.js';
2
+ import type { StepParserResolver } from './parser.js';
3
+ import type { PipelineReporter } from './reporter.js';
4
+ import type { PipelineStep, StepResult } from './step.js';
5
+ /**
6
+ * Summary counts for one pipeline run.
7
+ */
8
+ export interface PipelineSummary {
9
+ /** Total number of executed steps. */
10
+ readonly total: number;
11
+ /** Number of passed steps. */
12
+ readonly passed: number;
13
+ /** Number of failed steps. */
14
+ readonly failed: number;
15
+ /** Number of skipped steps. */
16
+ readonly skipped: number;
17
+ /** Number of timed out steps. */
18
+ readonly timedOut: number;
19
+ /** Total pipeline runtime in milliseconds. */
20
+ readonly durationMs: number;
21
+ }
22
+ /**
23
+ * Final pipeline run data.
24
+ */
25
+ export interface PipelineRunResult {
26
+ /** Ordered list of step results. */
27
+ readonly steps: readonly StepResult[];
28
+ /** Aggregated status summary. */
29
+ readonly summary: PipelineSummary;
30
+ /** Process-style exit code derived from result state. */
31
+ readonly exitCode: 0 | 1;
32
+ /** Run start timestamp in Unix milliseconds. */
33
+ readonly startedAt: number;
34
+ /** Run finish timestamp in Unix milliseconds. */
35
+ readonly finishedAt: number;
36
+ }
37
+ /**
38
+ * Runtime options used by the pipeline runner.
39
+ */
40
+ export interface PipelineRunOptions {
41
+ /** Steps to execute in order. */
42
+ readonly steps: readonly PipelineStep[];
43
+ /** Command executor implementation. */
44
+ readonly executor: CommandExecutor;
45
+ /** Optional reporters for lifecycle hooks. */
46
+ readonly reporters?: readonly PipelineReporter[];
47
+ /** Optional parser resolver for tool-specific metrics. */
48
+ readonly parserResolver?: StepParserResolver;
49
+ /** Default working directory when steps do not provide one. */
50
+ readonly cwd?: string;
51
+ /** Base environment merged into each step execution. */
52
+ readonly env?: NodeJS.ProcessEnv;
53
+ /** Continue after non-optional failures when true. */
54
+ readonly continueOnError?: boolean;
55
+ /** Time source injection for deterministic tests. */
56
+ readonly now?: () => number;
57
+ /** Sleep function injection for deterministic retry tests. */
58
+ readonly sleep?: (durationMs: number) => Promise<void>;
59
+ }
60
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../../src/internal/core/contracts/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEzD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAA;IACrC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAA;IACxB,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,iDAAiD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAChD,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAA;IAC5C,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,wDAAwD;IACxD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IAChC,sDAAsD;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACvD"}