/**
 * API Client for Vigthoria Backend
 * Connects to coder.vigthoria.io API endpoints
 */
import { Config } from './config.js';
import { Logger } from './logger.js';
export type CLIErrorCategory = 'auth' | 'repo_session' | 'model_backend' | 'bridge' | 'network' | 'timeout' | 'parsing' | 'tool_execution' | 'credits';
export declare const VIGTHORIA_HUB_CREDITS_URL = "https://hub.vigthoria.io/credits";
export declare const VIGTHORIA_SERVER_TEMPORARILY_UNAVAILABLE_MESSAGE = "Vigthoria Server is temporarily not available. Please try again later. If the issue persists, please contact support.";
export type ChatRoutePreference = 'coder' | 'models' | 'selfhosted';
export type ChatRequestOptions = {
    /** @deprecated Use connectTimeoutMs + idleTimeoutMs. Kept for legacy callers. */
    timeoutMs?: number;
    fastFail?: boolean;
    /** When true with fastFail, only try preferredRoute (no fallback hops). */
    singleRoute?: boolean;
    connectTimeoutMs?: number;
    idleTimeoutMs?: number;
    stream?: boolean;
    preferredRoute?: ChatRoutePreference;
    onRouteAttempt?: (routeLabel: string) => void;
    onStreamDelta?: (chunk: string) => void;
};
export declare class CLIError extends Error {
    category: CLIErrorCategory;
    statusCode?: number;
    endpoint?: string;
    walletUrl?: string;
    topupUrl?: string;
    balance?: number;
    constructor(message: string, category: CLIErrorCategory, opts?: {
        statusCode?: number;
        endpoint?: string;
        cause?: Error;
        walletUrl?: string;
        topupUrl?: string;
        balance?: number;
    });
}
/** Classify an axios or fetch error into a structured CLIError. */
export declare function classifyError(error: unknown, fallbackCategory?: CLIErrorCategory): CLIError;
/** Format a CLIError for user-facing display. */
export declare function formatCLIError(err: CLIError): string;
export declare function sanitizeUserFacingPathText(input: string): string;
export declare function sanitizeUserFacingErrorText(input: string): string;
export declare function isServerRuntime(): boolean;
export declare function describeUpstreamStatus(status: number): string;
export declare function propagateError(err: any): never;
export interface ChatMessage {
    role: 'user' | 'assistant' | 'system';
    content: string;
}
export interface ChatResponse {
    id: string;
    message: string;
    model: string;
    usage?: {
        prompt_tokens: number;
        completion_tokens: number;
        total_tokens: number;
    };
}
export interface V3AgentWorkflowResponse {
    content: string;
    taskId: string | null;
    contextId?: string | null;
    backendUrl: string;
    partial?: boolean;
    metadata?: Record<string, unknown>;
    changedFiles?: Record<string, string>;
}
export interface FrontendPreviewGateResult {
    required: boolean;
    passed: boolean;
    backendUrl?: string;
    entryPath?: string;
    assetPaths?: {
        css: string[];
        js: string[];
    };
    artifacts?: {
        manifestPath?: string;
        screenshotPath?: string;
        previewFileUrl?: string;
        screenshotCaptured?: boolean;
        screenshotError?: string;
    };
    modes?: {
        design?: {
            ready: boolean;
            devices?: string[];
            variantCount?: number;
        };
        live?: {
            ready: boolean;
            entryPoint?: string;
        };
        production?: {
            ready: boolean;
            deploymentTarget?: string;
            recommendedCommand?: string;
        };
    };
    summary?: Record<string, unknown>;
    processingTimeMs?: number;
    error?: string;
}
export interface OperatorWorkflowResponse {
    content: string;
    workflowId: string | null;
    contextId?: string | null;
    backendUrl: string;
    savedWorkflow?: {
        id: string;
        name?: string | null;
        sourceWorkflowId?: string | null;
    } | null;
    metadata?: Record<string, unknown>;
    changedFiles?: Record<string, string>;
}
export interface StreamChunk {
    type: 'content' | 'done' | 'error';
    content?: string;
    error?: string;
}
export interface EndpointHealthStatus {
    name: string;
    endpoint: string;
    ok: boolean;
    error?: string;
    details?: Record<string, unknown>;
}
export interface APIHealthStatus {
    overallOk: boolean;
    coder: EndpointHealthStatus;
    models: EndpointHealthStatus;
    selfHosted: EndpointHealthStatus | null;
}
export interface CapabilityTruthStatus {
    overallOk: boolean;
    v3Agent: EndpointHealthStatus;
    hyperLoop: EndpointHealthStatus;
    repoMemory: EndpointHealthStatus;
    devtoolsBridge: EndpointHealthStatus;
}
export interface VigFlowTemplateSummary {
    id: string;
    name: string;
    description: string;
    category: string;
    icon?: string;
    tags: string[];
    isBuiltin: boolean;
    source: string;
    createdAt?: string;
}
export interface VigFlowWorkflowSummary {
    id: string;
    name: string;
    description: string;
    isActive: boolean;
    version: string;
    tags: string[];
    nodeCount: number;
    executionCount: number;
    lastExecutedAt?: string;
    createdAt?: string;
    updatedAt?: string;
}
export interface VigFlowWorkflowCreation {
    id: string;
    name: string;
    fromTemplate?: string;
}
export interface ResolvedVigFlowWorkflowTarget {
    id: string;
    name: string;
    selector: string;
    matchedBy: 'id' | 'name' | 'search';
}
export interface VigFlowExecutionResult {
    executionId: string;
    status: string;
    result?: unknown;
    error?: string;
    nodesExecuted?: number;
}
export interface VigFlowExecutionStatus {
    id: string;
    workflowId: string;
    status: string;
    startedAt?: string;
    completedAt?: string;
    nodesExecuted?: number;
    totalNodes?: number;
    result?: unknown;
    error?: string;
    progress?: Record<string, unknown>;
    duration?: number;
}
export interface VigthoriUser {
    id: string;
    username: string;
    email: string;
    isAdmin: boolean;
    subscription: {
        plan: string;
        projectLimit: number;
        storageLimit: number;
        viagen6Access: boolean;
        aiModelsLimit: number;
        prioritySupport: boolean;
        teamCollaboration: boolean;
        adminAccess: boolean;
    };
}
export declare class APIClient {
    private client;
    private modelRouterClient;
    private selfHostedModelRouterClient;
    private config;
    private logger;
    private ws;
    private vigFlowTokens;
    private _httpsAgent;
    private lastChatTransportErrors;
    private clientToolErrors;
    private pendingV3ClientToolTasks;
    /** Tracks files mutated via client_tool_request during an active V3 SSE stream. */
    private activeV3StreamedFiles;
    private activeV3StreamContext;
    constructor(config: Config, logger: Logger);
    /**
     * Destroy keep-alive sockets so the Node.js event loop can drain
     * naturally.  Call this before exiting commands that run HTTP probes
     * (e.g. `status`) to avoid the libuv UV_HANDLE_CLOSING assertion
     * on Windows / Node 25+.
     */
    destroy(): void;
    /** Exposed for Balanced 4B agent routing (local inference :8016). */
    getSelfHostedModelsApiUrl(): string | null;
    login(email: string, password: string): Promise<boolean>;
    loginWithToken(token: string): Promise<boolean>;
    private extractUserProfile;
    private refreshToken;
    getSubscriptionStatus(): Promise<void>;
    private getAccessToken;
    /**
     * Validate the current auth token against the Coder API.
     * By default this fails open on network errors to keep offline commands usable.
     */
    validateToken(options?: {
        allowNetworkFailOpen?: boolean;
        enforceTokenShape?: boolean;
    }): Promise<{
        valid: boolean;
        error?: string;
    }>;
    getV3AgentBaseUrls(preferLocal?: boolean): string[];
    getV3AgentRunUrl(baseUrl: string): string;
    getV3AgentContinueUrl(baseUrl: string): string;
    getV3AgentBackgroundUrl(baseUrl: string, suffix?: string): string;
    getOperatorBaseUrls(): string[];
    getOperatorStreamUrl(baseUrl: string): string;
    getMcpBaseUrls(): string[];
    getVigFlowBaseUrls(): string[];
    getTemplateServiceBaseUrls(): string[];
    private isFrontendTask;
    /**
     * Returns true when the prompt describes a read-only / analysis task.
     * Used to suppress preview gate and other write-oriented side effects.
     */
    isAnalysisOnlyTask(message?: string, context?: Record<string, any>): boolean;
    private normalizeWorkspaceRelativePath;
    private listFrontendWorkspaceFiles;
    private chooseFrontendPreviewEntry;
    private extractLinkedFrontendAssets;
    private gatherFrontendPreviewArtifacts;
    private captureFrontendPreviewScreenshot;
    private evaluateFrontendVisualProof;
    private persistFrontendPreviewArtifacts;
    runTemplateServicePreviewGate(message?: string, context?: Record<string, any>): Promise<FrontendPreviewGateResult>;
    private getMcpContextCreateUrl;
    private getMcpContextUrl;
    private getMcpHeaders;
    getV3AgentHeaders(): Promise<Record<string, string>>;
    /**
     * Ensure the V3 service key is available in config.
     * If not already set via env or stored config, fetches it from the Coder API
     * using the current user's auth token and caches it for this session and beyond.
     */
    ensureV3ServiceKey(): Promise<void>;
    runV3HealthCheck(): Promise<{
        healthy: boolean;
        endpoint: string;
        error?: string;
    }>;
    private runV3AgentAuthPreflight;
    private executeV3AgentRunRequest;
    private getVigFlowAccessToken;
    private getVigFlowHeaders;
    private withVigFlow;
    /**
     * Build the correct sub-path for VigFlow endpoints.
     * Local servers (e.g. localhost:5060) need `/api/…` prefix.
     * The remote gateway URL already ends with `/api/vigflow`, so appending
     * another `/api/…` would double the prefix and cause 404s.
     */
    private vigFlowEndpoint;
    listVigFlowTemplates(options?: {
        category?: string;
        search?: string;
    }): Promise<VigFlowTemplateSummary[]>;
    listVigFlowWorkflows(): Promise<VigFlowWorkflowSummary[]>;
    resolveVigFlowWorkflow(selector: string): Promise<ResolvedVigFlowWorkflowTarget>;
    useVigFlowTemplate(templateId: string, options?: {
        name?: string;
        variables?: Record<string, unknown>;
    }): Promise<VigFlowWorkflowCreation>;
    runVigFlowWorkflow(workflowId: string, options?: {
        data?: Record<string, unknown>;
        executionOptions?: Record<string, unknown>;
    }): Promise<VigFlowExecutionResult>;
    getVigFlowExecutionStatus(executionId: string): Promise<VigFlowExecutionStatus>;
    /** Maximum serialized context length accepted by the V3 server. */
    private static readonly V3_CONTEXT_CHAR_LIMIT;
    buildV3AgentContext(context?: Record<string, any>): string;
    /**
     * Compact a V3 context payload so the serialized JSON stays under
     * the server's character limit.  Progressively sheds bulk:
     *   1. Trim workspaceFiles values to fit budget
     *   2. Drop workspaceFiles entirely
     *   3. Truncate history
     *   4. Truncate file list
     *   5. Drop readmeExcerpt
     */
    private compactV3Context;
    /** Remove duplicate functionIndex entries that poison model context after compaction. */
    private dedupeBrainPayload;
    buildMinimalV3AgentContext(context?: Record<string, any>): string;
    private extractEmergencyAppName;
    private materializeEmergencySaaSWorkspace;
    private ensureExecutionContext;
    bindExecutionContext(context?: Record<string, any>): Promise<Record<string, any>>;
    private resolveAgentTargetPath;
    private isLikelyWindowsPath;
    private resolveServerBindableWorkspacePath;
    private getDisplayWorkspaceName;
    private buildPublicWorkspaceDescriptor;
    private buildPublicRuntimeEnvironment;
    private buildLocalWorkspaceSummary;
    /**
     * Collect text file contents from the workspace for V3 agent hydration.
     * Budget: up to ~2 MB total, per-file cap 200 KB, skip binary extensions.
     */
    collectWorkspaceFileContents(rootPath: string, filePaths: string[]): Record<string, string>;
    hasAgentWorkspaceOutput(context?: Record<string, any>): boolean;
    getAgentWorkspaceSnapshot(rootPath: string): {
        fileCount: number;
        paths: string[];
        signature: string;
    };
    waitForAgentWorkspaceSettle(context?: Record<string, any>, options?: Record<string, any>): Promise<void>;
    extractExpectedWorkspaceFiles(message?: string, context?: Record<string, any>): string[];
    captureV3AgentStreamMutation(event: any, streamedFiles: Record<string, string>, serverRoot?: string | null): void;
    private applyV3AgentStreamEventToWorkspace;
    private resolveV3ClientToolPath;
    private recordV3ClientToolMutation;
    private executeV3ClientToolRequest;
    private handleV3ClientToolRequest;
    private writeV3AgentWorkspaceFile;
    private deleteV3AgentWorkspaceFile;
    recoverAgentWorkspaceFiles(context?: Record<string, any>, streamedFiles?: Record<string, string>, expectedFiles?: string[]): void;
    normalizeAgentWorkspaceRelativePath(rawPath: string, rootPath?: string): string;
    ensureAgentFrontendPolish(message?: string, context?: Record<string, any>): Promise<void>;
    private injectSectionBeforeFooter;
    private injectNavLink;
    private ensureReferencedFrontendAssets;
    private buildFallbackFrontendCss;
    private buildFallbackFrontendJs;
    private replaceMissingLocalAssetReferences;
    formatV3AgentResponse(data: any): string;
    private sanitizeV3AgentResponseText;
    /**
     * Build a human-readable answer from the tool results in a V3 event
     * stream when the server didn't emit a proper complete/message event.
     */
    private synthesizeAnswerFromV3Events;
    private sanitizeV3AgentEventForUser;
    private resolveAgentChangedFiles;
    private finalizeV3AgentWorkflowResponse;
    collectV3AgentStream(response: Response, context?: Record<string, any>): Promise<any>;
    runV3AgentWorkflow(message: string, context?: Record<string, any>): Promise<V3AgentWorkflowResponse>;
    startV3BackgroundJob(message: string, context?: Record<string, any>): Promise<any>;
    listV3BackgroundJobs(limit?: number): Promise<any[]>;
    getV3BackgroundJob(jobId: string): Promise<any>;
    cancelV3BackgroundJob(jobId: string): Promise<any>;
    getV3BackgroundJobFiles(jobId: string): Promise<{
        status: string;
        files: Record<string, string>;
        file_count: number;
        local_workspace_path?: string;
    }>;
    applyV3BackgroundJobFiles(jobId: string, context?: Record<string, any>): Promise<{
        applied: string[];
        skipped: string[];
        status: string;
    }>;
    private formatOperatorResponse;
    runOperatorWorkflow(message: string, context?: Record<string, any>): Promise<OperatorWorkflowResponse>;
    /**
     * Chat API - Direct Vigthoria Models API Architecture
     *
     * PRIMARY: api.vigthoria.io - Direct access to Vigthoria Model Router
     *          This is the centralized public API for all AI operations.
     *          Works for both authenticated and unauthenticated users.
     *
     * FALLBACK: Coder Cloud API - For authenticated users only
     *
     * NO localhost fallbacks - CLI is for external users, not server-side!
     */
    chat(messages: ChatMessage[], model: string, useLocal?: boolean): Promise<ChatResponse>;
    private shouldSkipCloudRoutes;
    private tryChatWithModel;
    private trySelfHostedChatWithModel;
    private getFallbackModelId;
    private isCloudModelId;
    private canUseCloudModel;
    private resolvePermittedModelId;
    private shouldSimulateCloudFailure;
    private shouldTrySelfHostedFallback;
    private isSelfHostedPreferredModel;
    private getSelfHostedFallbackModelId;
    chatStream(messages: ChatMessage[], model: string): AsyncGenerator<StreamChunk>;
    chatWithCallback(messages: ChatMessage[], model: string, onChunk: (chunk: string) => void, onDone: () => void, onError: (error: Error) => void): Promise<void>;
    private chatComplete;
    generateCode(prompt: string, language: string, model: string): Promise<string>;
    /**
     * Ensure code has balanced curly braces by appending missing closing braces.
     */
    private ensureBalancedBraces;
    /**
     * Quick JS/TS syntax validation using Node's built-in parser.
     * Returns true if the code parses without errors.
     */
    private validateJsSyntax;
    /**
     * Extract the first complete function/class from code.
     * Used as last-resort when the model keeps over-producing.
     */
    private extractFirstFunction;
    /**
     * Detect if code is excessively over-engineered for a short prompt.
     * E.g. a "multiply function" request producing 20+ lines.
     */
    private codeIsOverEngineered;
    /**
     * Detect if generated code contains DOM/HTML pollution inappropriate
     * for a pure programming language like JavaScript, Python, etc.
     */
    private codeContainsDomPollution;
    /**
     * Strip DOM pollution from generated code, keeping only the pure logic.
     * Used as last-resort fallback when the model repeatedly ignores constraints.
     */
    private stripDomPollution;
    generateProject(prompt: string, projectType: string, model: string): Promise<{
        code: string;
        plan?: any;
        quality?: {
            lineCount: number;
            score: number;
            checks: {
                hasAnimations: boolean;
                hasNeonEffects: boolean;
                hasResponsive: boolean;
                hasFontAwesome: boolean;
                hasGoogleFonts: boolean;
            };
        };
    }>;
    explainCode(code: string, language: string): Promise<string>;
    reviewCode(code: string, language: string): Promise<{
        score: number;
        issues: {
            type: string;
            line: number;
            message: string;
            severity: string;
        }[];
        suggestions: string[];
    }>;
    /**
     * Lightweight client-side heuristic scan: catches common code smells
     * AND logic/arithmetic bugs so review never returns "score 30, no issues".
     */
    private heuristicCodeIssues;
    fixCode(code: string, language: string, fixType: string): Promise<{
        fixed: string;
        changes: {
            line: number;
            before: string;
            after: string;
            reason: string;
        }[];
    }>;
    /**
     * Compute a semantic diff between original and fixed code using
     * Longest Common Subsequence (LCS) to avoid the line-shift inflation
     * bug where inserting one line flags all subsequent lines as changed.
     */
    private computeSemanticDiff;
    /**
     * Lightweight client-side syntax error detection.
     * Returns a human-readable description of obvious errors, or empty string.
     */
    private detectSyntaxErrors;
    /**
     * Strip comment lines that the model added during a fix but were not
     * present in the original code.  Used for syntax-only fixes where the
     * model tends to annotate its changes with "// Fixed ..." comments.
     */
    private stripInjectedComments;
    /**
     * Ensure the fixed code hasn't lost closing delimiters relative to the
     * original.  Counts {, }, (, ), [, ] outside strings/comments and if
     * the fix has fewer closers than the original, appends the missing ones.
     */
    private repairBracketBalance;
    private resolveModelId;
    private getCoderHealth;
    /**
     * Fast preflight for local agent loop — probes model backends in parallel
     * so users see a clear pass/fail before "Planning..." hangs on slow routes.
     */
    runChatModelPreflight(requestedModel?: string): Promise<{
        healthy: boolean;
        endpoint: string;
        error?: string;
        routes: Array<{
            name: string;
            ok: boolean;
            error?: string;
        }>;
    }>;
    mapPreflightEndpointToRoute(endpoint: string): ChatRoutePreference | null;
    getLastChatTransportErrors(): string[];
    getClientToolErrors(): string[];
    clearAgentRunDiagnostics(): void;
    private recordClientToolError;
    submitClientToolResult(contextId: string, callId: string, result: {
        success: boolean;
        output: string;
        error?: string;
    }, backendUrl?: string | null): Promise<void>;
    private isHealthyServicePayload;
    private extractModelCount;
    private probeModelList;
    private getModelsHealth;
    private getSelfHostedHealth;
    private getV3AgentHealth;
    private getHyperLoopHealth;
    private getRepoMemoryHealth;
    runSelfHealingCycle(_originalPrompt: string, _workspacePath: string, _context?: Record<string, any>): Promise<{
        healingAttempted: boolean;
        passed: boolean;
        tool: string;
    }>;
    attemptV3ServiceRecovery(reason?: string, _options?: Record<string, any>): Promise<{
        recovered: boolean;
        message: string;
    }>;
    getDevtoolsBridgeStatus(): Promise<EndpointHealthStatus>;
    getCapabilityTruthStatus(context?: Record<string, any>): Promise<CapabilityTruthStatus>;
    getHealthStatus(): Promise<APIHealthStatus>;
    healthCheck(): Promise<boolean>;
}
