/**
 * Cloud dispatch type definitions.
 *
 * Defines the provider-agnostic interface that all cloud backends (Rush, Codex,
 * Factory) implement, plus the shared task and event types that flow through
 * the dispatch pipeline.
 */
/**
 * Normalize a provider's raw wire status into the canonical `CloudTaskStatus`.
 *
 * Each cloud backend speaks its own status vocabulary and had its own copy of
 * this mapping, which had drifted. This dispatches per provider while keeping
 * provider-specific defaults explicit:
 *   - `rush`        — switch over the Factory Floor's known strings; includes
 *                     `allocating` and stopped/resumable `idle` states, has no
 *                     `queued`, default `running`.
 *   - `codex`       — substring match on the lowercased CLI status; default
 *                     `running`.
 *   - `antigravity` — substring match on the (possibly `undefined`) Interactions
 *                     API status; default `completed` (its synchronous response
 *                     is terminal), and `undefined`-safe.
 *
 * Factory's `mapResultStatus` is structurally different (it maps a droid *exit*
 * result, not a lifecycle string) and deliberately stays in `factory.ts`.
 */
export function normalizeProviderStatus(provider, wireStatus) {
    switch (provider) {
        case 'rush':
            return normalizeRushStatus(wireStatus ?? '');
        case 'codex':
            return normalizeCodexStatus(wireStatus ?? '');
        case 'antigravity':
            return normalizeAntigravityStatus(wireStatus);
        case 'cursor':
            return normalizeCursorStatus(wireStatus ?? '');
    }
}
/** Cursor Cloud run status → canonical enum. Unknown non-terminal states remain running. */
function normalizeCursorStatus(s) {
    switch (s.toUpperCase()) {
        case 'CREATING': return 'queued';
        case 'RUNNING': return 'running';
        case 'FINISHED': return 'completed';
        case 'ERROR':
        case 'EXPIRED': return 'failed';
        case 'CANCELLED': return 'cancelled';
        default: return 'running';
    }
}
/** Rush Factory Floor status → canonical enum. Default `running`; no `queued`. */
function normalizeRushStatus(s) {
    switch (s) {
        case 'allocating': return 'allocating';
        case 'running': return 'running';
        case 'idle':
        case 'paused':
        case 'needs_review': return 'idle';
        case 'input_required': return 'input_required';
        case 'completed': return 'completed';
        case 'failed': return 'failed';
        case 'cancelled': return 'cancelled';
        default: return 'running';
    }
}
/** Codex Cloud CLI status → canonical enum. Substring match; default `running`. */
function normalizeCodexStatus(s) {
    const lower = s.toLowerCase();
    if (lower.includes('queued') || lower.includes('pending'))
        return 'queued';
    if (lower.includes('running') || lower.includes('in_progress'))
        return 'running';
    if (lower.includes('idle') || lower.includes('paused') || lower.includes('needs_review'))
        return 'idle';
    if (lower.includes('completed') || lower.includes('succeeded') || lower.includes('success'))
        return 'completed';
    if (lower.includes('failed') || lower.includes('error'))
        return 'failed';
    if (lower.includes('cancelled') || lower.includes('canceled'))
        return 'cancelled';
    return 'running';
}
/**
 * Antigravity Interactions API status → canonical enum. Substring match,
 * `undefined`-safe; default `completed` because the synchronous response is
 * already terminal.
 */
function normalizeAntigravityStatus(s) {
    const lower = (s ?? '').toLowerCase();
    if (lower.includes('queue') || lower.includes('pending'))
        return 'queued';
    if (lower.includes('run') || lower.includes('progress'))
        return 'running';
    if (lower.includes('idle') || lower.includes('paused') || lower.includes('needs_review'))
        return 'idle';
    if (lower.includes('complete') || lower.includes('success'))
        return 'completed';
    if (lower.includes('fail') || lower.includes('error'))
        return 'failed';
    if (lower.includes('cancel'))
        return 'cancelled';
    return 'completed';
}
/** Maximum images allowed per dispatch (matches Cursor Background Agents). */
export const MAX_IMAGES_PER_DISPATCH = 5;
/**
 * Collapse `repo` + `repos` into a single deduped list. Exported so callers,
 * tests, and every provider share the same resolution — one source of truth
 * for "which repos does this dispatch target?".
 */
export function resolveDispatchRepos(options) {
    const out = [];
    const seen = new Set();
    const candidates = [];
    if (options.repos)
        candidates.push(...options.repos);
    if (options.repo)
        candidates.push(options.repo);
    for (const raw of candidates) {
        const trimmed = typeof raw === 'string' ? raw.trim() : '';
        if (!trimmed)
            continue;
        const key = trimmed.toLowerCase();
        if (seen.has(key))
            continue;
        seen.add(key);
        out.push(trimmed);
    }
    return out;
}
/**
 * Thrown by a provider's `dispatch()` when it needs a pre-provisioned target
 * (Codex env / Factory computer) and none was supplied. The CLI catches this
 * to offer a picker (`listTargets`) or actionable guidance, instead of a raw
 * error. `kind` names the missing flag; `guidance` is shown when the target
 * can't be enumerated.
 */
export class MissingTargetError extends Error {
    kind;
    guidance;
    constructor(kind, message, guidance) {
        super(message);
        this.kind = kind;
        this.guidance = guidance;
        this.name = 'MissingTargetError';
    }
}
