import { type Logger } from '../utility/logging/logger.ts';
import { Readable } from 'node:stream';
interface ApplicationConfig {
    package: string;
    install?: {
        command?: string;
        timeout?: number;
        allowInstallScripts?: boolean;
    };
    [key: string]: unknown;
}
export declare class InvalidPackageIdentifierError extends TypeError {
    constructor(applicationName: string, packageIdentifier: unknown);
}
export declare class InvalidInstallPropertyError extends TypeError {
    constructor(applicationName: string, installProperty: unknown);
}
export declare class InvalidInstallCommandError extends TypeError {
    constructor(applicationName: string, command: unknown);
}
export declare class InvalidInstallTimeoutError extends TypeError {
    constructor(applicationName: string, timeout: unknown);
}
export declare function assertApplicationConfig(applicationName: string, applicationConfig: Record<'package', unknown> & Record<string, unknown>): asserts applicationConfig is ApplicationConfig;
/**
 * Returns true when npm/git stderr indicates an SSH authentication failure —
 * git exits 128 with the standard "could not read" message, or the SSH layer
 * reports a missing uid (no SSH daemon user), explicit publickey denial, or
 * an unverified host key.
 */
export declare function isSSHAuthFailure(stderr: string): boolean;
/**
 * Extract an application given payload (content of the application) or package (npm-compatible identifier to the application).
 *
 * Only one of `application.payload` or `application.package` should be specified; otherwise, an error is thrown.
 *
 * Writes the application to the configured components root directory using the `application.name` and overwrites any existing directory.
 *
 * This method should only be called from the main thread
 */
export declare function extractApplication(application: Application): Promise<void>;
/**
 * Install an application to its relative `application.dirPath` using either a
 * configured `application.install` command, a derived package manager from the
 * application's `package.json#devEngines`, or falling back to the default
 * package manager, `npm`.
 *
 * Will return early if `node_modules` already exists within the `application.dirPath`
 *
 * This method should only be called from the main thread
 */
export declare function installApplication(application: Application): Promise<void>;
/**
 * Callback invoked once per complete line of install stdout/stderr from
 * `nonInteractiveSpawn`. Threaded through `installApplication` to the underlying spawn
 * so a deploy can stream `npm install` output back to the caller as an SSE `install`
 * event in real time, rather than waiting for the process to exit. Line-buffered so a
 * chunk that splits mid-line never fires a partial line.
 */
export type OnInstallLine = (manager: string, stream: 'stdout' | 'stderr', line: string) => void;
interface ApplicationOptions {
    name: string;
    payload?: Buffer | string | Readable;
    packageIdentifier?: string;
    install?: {
        command?: string;
        timeout?: number;
        allowInstallScripts?: boolean;
    };
    onInstallLine?: OnInstallLine;
}
export declare class Application {
    name: string;
    payload?: Buffer | string | Readable;
    packageIdentifier?: string;
    install?: {
        command?: string;
        timeout?: number;
        allowInstallScripts?: boolean;
    };
    onInstallLine?: OnInstallLine;
    dirPath: string;
    logger: Logger;
    packageManagerPrefix: string;
    constructor({ name, payload, packageIdentifier, install, onInstallLine }: ApplicationOptions);
}
/**
 * Based on an old implementation for a method called `getPkgPrefix()` that was used
 * during the installation process in order to actually resolve what the user specifies for a
 * component matching some of npm's package resolution rules.
 */
export declare function derivePackageIdentifier(packageIdentifier: string): string;
/**
 * Extract and install the specified application.
 *
 * This method should only be called from the main thread
 *
 * Bracketed with `deploy:start`/`deploy:end` lifecycle broadcasts so every
 * Harper thread's file watchers can suppress restart-on-change events while
 * the component directory is being rewritten — see harper#488 and
 * `components/deployLifecycle.ts`. The broadcast is best-effort: if it fails
 * (e.g. workers haven't started yet during initial install), the deploy still
 * proceeds.
 *
 * @param application The application to prepare.
 * @returns A promise that resolves when all preparation steps complete.
 */
export declare function prepareApplication(application: Application): Promise<void>;
/**
 * Install all applications specified in the root config.
 *
 * This method should only be called from the main thread otherwise certain
 * operations may conflict with each other (such as writing to the same directory).
 */
export declare function installApplications(): Promise<void>;
export declare function nonInteractiveSpawn(applicationName: string, command: string, args: string[], cwd: string, timeoutMs?: number, onLine?: (stream: 'stdout' | 'stderr', line: string) => void): Promise<{
    stdout: string;
    stderr: string;
    code: number;
}>;
export declare function getEnvBuiltInComponents(): {
    name: string;
    packageIdentifier: string;
}[];
export {};
