import type { BuildCredentials } from '../../schemas/build.js';
export type CiSecretProvider = 'github' | 'gitlab';
export interface CiSecretEntry {
    key: string;
    value: string;
    masked: boolean;
}
export interface CiSecretTarget {
    provider: CiSecretProvider;
    label: string;
    cli: 'gh' | 'glab';
}
export interface CiSecretDiscovery {
    targets: CiSecretTarget[];
    setup: CiSecretSetupAdvice[];
    notes: string[];
}
export interface CiSecretSetupAdvice {
    target: CiSecretTarget;
    reason: 'not-installed' | 'not-authenticated';
    message: string;
    commands: string[];
}
interface CommandRunOptions {
    input?: string;
}
export interface CommandRunResult {
    status: number | null;
    stdout: string;
    stderr: string;
    error?: Error;
}
export type CommandRunner = (command: string, args: string[], options?: CommandRunOptions) => CommandRunResult;
/**
 * Async runner. Used by the wizard so spawned `gh` / `glab` calls don't block
 * the Node event loop — without this, `ink-spinner`'s animation freezes for
 * the entire duration of every shell-out, which feels like the wizard has hung.
 *
 * Tests can pass either a sync (CommandRunner) or async runner — every helper
 * that calls runner.* does so via `await` so a sync runner returning a plain
 * result still works (Promise.resolve coerces it).
 */
export type AsyncCommandRunner = (command: string, args: string[], options?: CommandRunOptions) => CommandRunResult | Promise<CommandRunResult>;
export declare function runCommand(command: string, args: string[], options?: CommandRunOptions): CommandRunResult;
/**
 * Non-blocking shell-out. Mirrors `runCommand`'s shape but uses `spawn` so
 * the Node event loop is free to tick spinners and process input while gh /
 * glab work. Default for any wizard-side helper that needs to render UI
 * during the call.
 */
export declare function runCommandAsync(command: string, args: string[], options?: CommandRunOptions): Promise<CommandRunResult>;
export declare function createCiSecretEntries(credentials: Partial<BuildCredentials>, apiKey?: string): CiSecretEntry[];
export declare function detectCiSecretTargets(runner?: CommandRunner): CiSecretDiscovery;
export declare function getCiSecretTargetLabel(target: CiSecretTarget | null | undefined): string;
/**
 * Resolve the concrete `owner/repo` (GitHub) or `group/project` (GitLab) the
 * `gh` / `glab` CLI will target from the current working directory.
 *
 * Returns null when the CLI can't determine the repo (e.g. cwd is not a git
 * repo, multiple remotes with no `gh-resolved` config, auth scopes missing).
 *
 * The wizard MUST show this string to the user and require explicit
 * confirmation before any `gh secret set` / `glab variable set` runs — those
 * commands silently overwrite without backup, so the user has to know which
 * repo they're about to mutate.
 */
export declare function getCiSecretRepoLabel(target: CiSecretTarget, runner?: CommandRunner): string | null;
/**
 * Non-blocking variant of `getCiSecretRepoLabel`. Identical logic, but
 * `await`s the runner so the event loop can tick during the gh/glab call —
 * lets Ink spinners actually animate during the resolution.
 */
export declare function getCiSecretRepoLabelAsync(target: CiSecretTarget, runner?: AsyncCommandRunner): Promise<string | null>;
export declare function listExistingCiSecretKeys(target: CiSecretTarget, keys: string[], runner?: CommandRunner): string[];
/** Non-blocking variant of `listExistingCiSecretKeys`. */
export declare function listExistingCiSecretKeysAsync(target: CiSecretTarget, keys: string[], runner?: AsyncCommandRunner): Promise<string[]>;
export declare function uploadCiSecrets(target: CiSecretTarget, entries: CiSecretEntry[], existingKeys?: string[], runner?: CommandRunner): void;
/**
 * Non-blocking variant of `uploadCiSecrets`. Calls `onProgress(current, total,
 * keyName)` before every `gh secret set` / `glab variable set` so the wizard
 * can render "Pushing N of M: <KEY>…" instead of a frozen spinner.
 *
 * Pushes are still sequential — gh/glab don't have a bulk-set API, and
 * parallelising would risk rate limits + makes failure semantics ambiguous.
 */
export declare function uploadCiSecretsAsync(target: CiSecretTarget, entries: CiSecretEntry[], existingKeys?: string[], runner?: AsyncCommandRunner, onProgress?: (current: number, total: number, keyName: string) => void): Promise<void>;
export {};
