/**
 * GitHub check run integration module.
 *
 * Creates and updates check runs at key lifecycle points using the Checks API.
 * Per locked decisions:
 * - Check runs created (queued) at trigger match time (before agent picks up the job)
 * - Both per-job AND overall workflow check runs: kici/{workflow} and kici/{workflow}/job/{job}
 * - Success ONLY if ALL jobs pass
 * - Cancelled/timed-out use 'cancelled' conclusion
 * - All API calls are fire-and-forget (non-blocking)
 *
 * Check run IDs are tracked in-memory after creation so that subsequent
 * updates (job complete, workflow complete) can reference them via checks.update().
 *
 * Enriched output:
 * - Live step progress with checklist-style updates (debounced at 5s)
 * - Failed check runs include step names, error messages, exit codes, and log context
 * - Check run annotations link failures to step source locations in workflow files (.kici/workflows/*.ts)
 *
 * Currently GitHub-only. Non-GitHub providers are handled gracefully (no-op with log).
 *
 * Note: The engine-level CheckStatusPoster interface (packages/engine/src/provider/check-status-poster.ts)
 * provides a provider-agnostic API for posting security-related check statuses (holds, approvals,
 * workflow modifications). The GitHub implementation is at packages/orchestrator/src/providers/github/check-status-poster.ts.
 * This CheckRunReporter handles execution lifecycle checks (queued, in_progress, completed per job/workflow).
 * Future cleanup may unify both under CheckStatusPoster, but they serve different purposes today.
 */
import { type GitHubAppConfig } from '../providers/github/auth.js';
import type { ProviderRegistry } from '../provider-registry.js';
import type { StepLogBuffer } from './step-log-buffer.js';
import { type SourceLocationData } from './check-run-summary.js';
import type { CheckRunTrackingStore } from './check-run-tracking-store.js';
import { ExecutionJobStatus } from '@kici-dev/engine';
/**
 * Dependencies for the CheckRunReporter.
 */
interface CheckRunReporterDeps {
    /**
     * Provider registry for per-routing-key credential lookup.
     * When provided, the reporter resolves GitHub App credentials by routing key
     * from the registry's CloneTokenProvider config. Takes precedence over githubConfig.
     */
    providerRegistry?: ProviderRegistry;
    /**
     * GitHub App config for creating Octokit instances.
     * Fallback for backward compatibility when providerRegistry is not provided
     * or when no routing key is available.
     */
    githubConfig?: GitHubAppConfig;
    /** Step log buffer for enriched failure summaries. */
    stepLogBuffer?: StepLogBuffer;
    /**
     * DB-backed tracking store. When provided, every per-key state mutation
     * (check-run ID, step-progress array, build creation marker,
     * in-progress-sent flag) is written through to the store so a replacement
     * coord on Raft leader switch can recover the state. When omitted (the
     * back-compat path used by unit tests that don't need HA correctness),
     * the reporter operates entirely from in-memory `Map`s.
     */
    trackingStore?: CheckRunTrackingStore;
    /** Resolver for step source locations from the lock file (for annotations). */
    getStepSourceLocations?: (workflowName: string, jobName: string) => SourceLocationData[] | undefined;
    /**
     * Base URL of the user-facing dashboard (e.g.
     * `https://dashboard.example.com/dashboard`). When set AND
     * `getOrgPublicAlias()` returns an alias, the reporter populates
     * `details_url = <dashboardUrl>/r/orgs/<alias>/runs/<runId>` on
     * every check-run create/update. When unset, no `details_url` is
     * emitted (preserving today's behavior).
     */
    dashboardUrl?: string;
    /**
     * Resolver for the orchestrator's owning org public alias. Typically
     * wired to `PlatformClient.getOrgPublicAlias()`. Returns the
     * `oal_<12-char>` alias supplied by Platform on `auth.success`, or
     * `undefined` before auth completes / when running against a
     * Platform that predates the alias plumbing.
     */
    getOrgPublicAlias?: () => string | undefined;
}
/**
 * Options for setPending.
 */
interface SetPendingOptions {
    provider: string;
    owner: string;
    repo: string;
    sha: string;
    workflowName: string;
    jobNames: string[];
    installationId?: number;
    /** Routing key for per-app credential lookup (e.g., "github:12345"). */
    routingKey?: string;
    /** Explicit requestId for trace context (falls back to AsyncLocalStorage context). */
    requestId?: string;
    /** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
    runId?: string;
}
/**
 * Options for setBuildPending.
 */
interface SetBuildPendingOptions {
    provider: string;
    owner: string;
    repo: string;
    sha: string;
    workflowName: string;
    installationId?: number;
    /** Routing key for per-app credential lookup (e.g., "github:12345"). */
    routingKey?: string;
    /** Explicit requestId for trace context (falls back to AsyncLocalStorage context). */
    requestId?: string;
    /** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
    runId?: string;
}
/**
 * Options for setBuildComplete.
 */
interface SetBuildCompleteOptions {
    provider: string;
    owner: string;
    repo: string;
    sha: string;
    workflowName: string;
    status: Extract<ExecutionJobStatus, 'success' | 'failed' | 'cancelled' | 'timed_out_stale'>;
    installationId?: number;
    /** Routing key for per-app credential lookup (e.g., "github:12345"). */
    routingKey?: string;
    description?: string;
    /** Explicit requestId for trace context (falls back to AsyncLocalStorage context). */
    requestId?: string;
    /** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
    runId?: string;
}
/**
 * Options for updateJobStatus.
 */
interface UpdateJobStatusOptions {
    provider: string;
    owner: string;
    repo: string;
    sha: string;
    workflowName: string;
    jobName: string;
    state: Extract<ExecutionJobStatus, 'success' | 'failed' | 'cancelled' | 'timed_out_stale'>;
    installationId?: number;
    /** Routing key for per-app credential lookup (e.g., "github:12345"). */
    routingKey?: string;
    description?: string;
    /** Explicit requestId for trace context (falls back to AsyncLocalStorage context). */
    requestId?: string;
    /** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
    runId?: string;
    /** Additional data from the agent (e.g., stepResults). */
    data?: Record<string, unknown>;
    /** Run ID for StepLogBuffer lookup. */
    runIdForLogs?: string;
    /** Job ID for StepLogBuffer lookup. */
    jobId?: string;
}
/**
 * Options for updateWorkflowStatus.
 */
interface UpdateWorkflowStatusOptions {
    provider: string;
    owner: string;
    repo: string;
    sha: string;
    workflowName: string;
    overallStatus: Extract<ExecutionJobStatus, 'success' | 'failed' | 'cancelled' | 'timed_out_stale'>;
    installationId?: number;
    /** Routing key for per-app credential lookup (e.g., "github:12345"). */
    routingKey?: string;
    description?: string;
    /** Explicit requestId for trace context (falls back to AsyncLocalStorage context). */
    requestId?: string;
    /** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
    runId?: string;
}
/**
 * Options for updateStepProgress.
 */
interface UpdateStepProgressOptions {
    provider: string;
    owner: string;
    repo: string;
    sha: string;
    workflowName: string;
    jobName: string;
    stepIndex: number;
    stepName: string;
    state: 'running' | 'success' | 'failed' | 'skipped' | 'cancelled' | 'error';
    durationMs?: number;
    installationId?: number;
    /** Routing key for per-app credential lookup (e.g., "github:12345"). */
    routingKey?: string;
    requestId?: string;
    runId?: string;
}
/**
 * Reports check run status to Git hosting providers.
 *
 * Currently supports GitHub via the Checks API (checks.create / checks.update).
 * Non-GitHub providers are handled gracefully (no-op with warning log).
 *
 * All public methods are fire-and-forget: they return void immediately
 * and log errors internally without propagating them.
 */
export declare class CheckRunReporter {
    private deps;
    /**
     * L1 cache: composite key → check run ID.
     *
     * Backed by `check_run_tracking.check_run_id` when `deps.trackingStore`
     * is wired. On a miss the cache falls through to the store; on a store
     * miss the lookup returns undefined and the caller logs + skips.
     *
     * Without the store this Map IS the source of truth (single-coord
     * deployments, unit tests).
     */
    private readonly checkRunIds;
    /**
     * L1 cache: in-flight build-creation promises. The DB-backed counterpart
     * lives in `check_run_tracking.build_creation_state`; this Map is needed
     * locally so a same-process `setBuildComplete` can await the
     * in-progress `setBuildPending` promise (the DB column is a state
     * marker, not an awaitable).
     */
    private readonly pendingBuildCreations;
    /** L1 cache: step-progress entries (synced to `check_run_tracking.step_progress_json`). */
    private readonly stepProgress;
    /**
     * L1 cache: per-key debounce timers. NOT persisted — on coord failover
     * the next update either flushes immediately (because the DB row's
     * `updated_at` is older than the debounce window) or starts a fresh
     * timer.
     */
    private readonly progressTimers;
    /** L1 cache: first in-progress sent flag (synced to `check_run_tracking.in_progress_sent_at`). */
    private readonly inProgressSent;
    /**
     * L1 cache: runId → set of check-run composite keys. Synced to the
     * indexed `check_run_tracking.run_id` column so a replacement coord can
     * still find every key for a runId at cleanup time.
     */
    private readonly runIdToKeys;
    constructor(deps: CheckRunReporterDeps);
    /**
     * Update the provider registry used for per-routing-key credential lookup.
     * Called after config reload when the provider registry is rebuilt.
     */
    updateRegistry(newRegistry: ProviderRegistry): void;
    /**
     * Late-bind the public-alias resolver. Called from `server.ts` /
     * `standalone.ts` after `PlatformClient` is constructed so the reporter
     * can pull the freshly-authenticated org's alias when building
     * `details_url`. orchestrator-core can't pass it at construction time
     * because the platform client is created later (after the HTTP server
     * starts).
     */
    setOrgPublicAliasResolver(resolver: () => string | undefined): void;
    /**
     * Set pending (queued) check runs for a workflow and all its jobs.
     * Called at trigger match time (before agent picks up the job).
     * Fire-and-forget: errors are logged but don't block the pipeline.
     *
     * Creates check runs via checks.create with status 'queued'.
     * Per locked decision: both per-job AND overall workflow check runs.
     * Name format: kici/{workflow-name}, kici/{workflow-name}/job/{job-name}
     */
    setPending(opts: SetPendingOptions): void;
    /**
     * Same as setPending but returns a Promise that resolves when check runs
     * are created. Used by the RunCoordinator for rerouted jobs where the
     * check runs MUST exist before job dispatch to ensure updates work.
     */
    setPendingAwait(opts: SetPendingOptions): Promise<void>;
    /**
     * Update a specific job's check run.
     * Called when a job reaches a terminal state.
     * Fire-and-forget: errors are logged but don't block the pipeline.
     */
    updateJobStatus(opts: UpdateJobStatusOptions): void;
    /**
     * Update the overall workflow check run.
     * Called when ALL jobs in a workflow reach terminal state.
     * Per locked decision: success ONLY if ALL jobs pass.
     * Fire-and-forget: errors are logged but don't block the pipeline.
     */
    updateWorkflowStatus(opts: UpdateWorkflowStatusOptions): void;
    /**
     * Clean up stale check runs left by a dead orchestrator.
     *
     * Unlike updateJobStatus/updateWorkflowStatus (which rely on in-memory checkRunId),
     * this method discovers check runs via the GitHub API by listing check runs for the
     * commit SHA and matching on the `kici/` name prefix. This allows a replacement
     * orchestrator to clean up check runs it didn't create.
     *
     * Uses the GitHub App to look up the installation for each repo, then lists and
     * updates any stuck "in_progress" check runs with a "timed_out" conclusion.
     *
     * Fire-and-forget: errors are logged but don't block.
     */
    cleanupStaleCheckRuns(opts: {
        provider: string;
        routingKey: string;
        owner: string;
        repo: string;
        sha: string;
        workflowName: string;
        jobNames: string[];
    }): void;
    /**
     * Update live step progress for a job's check run.
     * Called each time a step starts, completes, or fails.
     * The first 'running' step triggers an immediate in_progress transition.
     * Subsequent updates are debounced (5 seconds) to prevent API rate limiting.
     * Fire-and-forget: errors are logged but don't block the pipeline.
     */
    updateStepProgress(opts: UpdateStepProgressOptions): void;
    /**
     * Set a build check run to pending (queued).
     * Called when a build job is dispatched for dependency installation and/or bundle compilation.
     * Separate from execution check runs so users see build progress independently.
     * Fire-and-forget: errors are logged but don't block the pipeline.
     *
     * Check run name format: kici/{workflowName}/setup
     */
    setBuildPending(opts: SetBuildPendingOptions): void;
    /**
     * Update a build check run to completed.
     * Called when the build job finishes (success, failure, or cancellation).
     * Fire-and-forget: errors are logged but don't block the pipeline.
     */
    setBuildComplete(opts: SetBuildCompleteOptions): void;
    /**
     * Clean up step-progress entries, debounce timers, and DB rows for a
     * completed run. Called when the execution tracker prunes the run.
     *
     * In-memory cleanup is synchronous; the DB cleanup is fire-and-forget
     * because the caller (run-pruning hook) is on the response-shaping path
     * and shouldn't block on a network round-trip. Failure logs but does
     * not propagate.
     */
    cleanupRun(runId: string): void;
    /**
     * Hydrate the L1 caches from the DB after a leader switch (or any
     * boot-time recovery). Called once on coord become-leader so the
     * runIdToKeys reverse map is populated for any future cleanupRun calls
     * without requiring a DB round-trip per cleanup. If no store is wired,
     * this is a no-op.
     */
    recoverState(): Promise<void>;
    /** Track a check run key associated with a runId for later cleanup. */
    private trackRunKey;
    /**
     * Parse a composite L1 cache key back into the (provider, owner, repo,
     * sha, check_name) tuple used by the store. The key format is fixed by
     * `checkRunKey()`; provider defaults to 'github' because today's
     * reporter only writes check runs for GitHub.
     */
    private parseKey;
    /**
     * Write-through helper: persist a check-run ID to L1 + the store.
     * Used by `setPending` / `setBuildPending` after a successful
     * `checks.create()`.
     */
    private persistCheckRunId;
    /**
     * Read-through helper: look up a check-run ID. Checks L1 first, falls
     * through to the store on miss, caches the result on hit. Returns
     * undefined when neither layer has the ID — the caller logs + skips.
     */
    private resolveCheckRunId;
    /**
     * Write-through helper: persist updated step-progress entries.
     */
    private persistStepProgress;
    /**
     * Write-through helper: mark the first running-step transition as sent.
     */
    private persistInProgressSent;
    /**
     * Write-through helper: stamp `build_creation_state = 'pending'`.
     */
    private persistBuildCreationPending;
    /**
     * Resolve GitHub App credentials for a given routing key.
     *
     * Resolution order:
     * 1. If providerRegistry is provided AND routingKey is given, look up the bundle
     *    by routing key and extract config from the CloneTokenProvider's getAppConfig().
     * 2. Fall back to the direct githubConfig dep (backward compatible).
     *
     * Returns undefined if no config is available.
     */
    private resolveGithubConfig;
    /**
     * Resolve trace IDs for check run summaries.
     * Priority: explicit option value > AsyncLocalStorage context > 'N/A'
     */
    private resolveTraceIds;
    /**
     * Append trace IDs to a check run summary string.
     */
    private appendTraceIds;
    private checkRunKey;
    /**
     * Build the `details_url` for a check run pointing at the dashboard's
     * public-alias resolver (`/r/orgs/<oal_xxx>/runs/<runId>`). Returns
     * `undefined` when either the dashboard URL or the alias is missing,
     * or when the runId is the synthetic `'N/A'` sentinel from
     * `resolveTraceIds` (no real run to link to). Strips any trailing
     * slash on `dashboardUrl` so the concatenation produces a single
     * separator.
     */
    private buildDetailsUrl;
    private doSetPending;
    private doUpdateJobStatus;
    private doUpdateWorkflowStatus;
    private doCleanupStaleCheckRuns;
    private doUpdateStepProgress;
    /**
     * Flush pending progress update to GitHub.
     */
    private flushProgress;
    private doSetBuildPending;
    private doSetBuildComplete;
    /**
     * Map internal build status to GitHub Checks conclusion and description.
     */
    private mapBuildConclusion;
    /**
     * Map internal job state to GitHub Checks conclusion and description.
     */
    private mapJobConclusion;
    /**
     * Map internal workflow state to GitHub Checks conclusion and description.
     */
    private mapWorkflowConclusion;
    /**
     * Create a check run via the GitHub Checks API.
     * Returns the check run ID on success, or undefined on failure.
     */
    private createCheckRun;
    /**
     * Update an existing check run via the GitHub Checks API.
     * Supports both 'completed' and 'in_progress' statuses.
     */
    private updateCheckRun;
}
/**
 * Build a meaningful failure description from agent job status data.
 *
 * Examines `stepResults` for the first failed step, falling back to
 * `data.error`, and finally to a generic "Job failed" message.
 */
export declare function buildJobFailureDescription(data: Record<string, unknown>): string;
export {};
//# sourceMappingURL=check-run-reporter.d.ts.map