/**
 * The Vigilbase-managed install of Cloudflare's cf (spec "one command", decision 5).
 *
 * When no usable cf is found, the full flow may install the pinned release
 * into `<configDir>/cf/<version>/` with the npm that ships with this Node:
 *
 * - npm runs as `process.execPath <npm-cli.js> install --prefix <staging> …`
 *   with no shell, from the fresh 0700 staging directory, with the user's
 *   environment (npm needs their npmrc, proxy and CA settings) minus every
 *   `CF_*` / `CLOUDFLARE_*` variable and, defensively, any variable whose
 *   value holds a session code, a verification token or `--email`. (npx 10
 *   passes arguments only in argv, not in the environment:
 *   `npm_lifecycle_script` is just the bin name.)
 * - `--ignore-scripts`: cf runs `--version`, `--dry-run` and API reads without
 *   lifecycle scripts. `--omit=optional`: the optional dependencies are the
 *   workerd and sharp platform binaries (about 150 MB). In cf 1.0.0-beta.13
 *   they are loaded only by `--local` mode and the `workers`, `deploy` and
 *   `previews` command trees (static and dynamic import graph of
 *   `dist/*.mjs`), none of which the checkup runs; see LOCAL.md.
 * - Integrity is pinned: after npm exits, the staging lockfile must record
 *   `node_modules/cf` at exactly the pinned version and npm `dist.integrity`,
 *   and the installed package.json must agree; otherwise the staging
 *   directory is deleted (CF_INSTALL_FAILED). Only then is it renamed into
 *   place, so a half-finished install is never used. `locateCf` still applies
 *   its identity checks to the result.
 * - Ctrl-C while npm runs kills npm and removes the staging directory. Staging
 *   directories left by a crash or a closed terminal are removed by the next
 *   install once they are older than the npm timeout (a concurrent install is
 *   always younger), and by `logout`.
 */
import { type ChildProcess, type SpawnOptions } from 'node:child_process';
import { LocalCheckupError } from '../errors.js';
/** The cf release the CLI installs; `integrity` is npm's `dist.integrity` for it. */
export declare const MANAGED_CF: Readonly<{
    version: "1.0.0-beta.13";
    integrity: "sha512-dCjpzCJvjudIu8IQbXCJfy9diFoyHU84D/30K4lJp7jUaBgvjJypsMFzLqvUFOuwhF1ggR/igsLqXyehAOR2FQ==";
    /** Measured `du` of the install without optional dependencies (darwin-arm64: 73 MB). */
    approxSize: "about 75 MB";
}>;
export declare const NPM_INSTALL_TIMEOUT_MS: number;
export declare const NPM_STDERR_TAIL_LINES = 20;
export type SpawnFn = (command: string, args: readonly string[], options: SpawnOptions) => ChildProcess;
/** `<configDir>/cf`: every managed version, plus any leftover staging directory. */
export declare function managedCfRoot(configDir: string): string;
export declare function managedCfInstallDir(configDir: string, version?: string): string;
export declare function managedCfPackageDir(installDir: string): string;
/** The npm arguments after `process.execPath`. */
export declare function npmInstallArgv(npmCli: string, prefix: string, version?: string): string[];
/**
 * The npm to run: `npm_execpath` when it names an existing `npm-cli.js` (or
 * `npx-cli.js`, whose sibling is used), otherwise the npm bundled beside this
 * Node. `null` when neither exists.
 */
export declare function resolveNpmCli(options?: {
    env: NodeJS.ProcessEnv;
    execPath?: string;
    platform?: NodeJS.Platform;
    exists?: (target: string) => boolean;
}): string | null;
/** The user's environment minus Cloudflare variables and anything carrying a session code, token or `--email`. */
export declare function npmChildEnv(parent: NodeJS.ProcessEnv): Record<string, string>;
/**
 * True when every lockfile npm wrote records `node_modules/cf` at the pinned
 * version and integrity (at least one must exist), and the installed
 * package.json has that version.
 */
export declare function verifyManagedInstall(installDir: string, pin?: {
    version: string;
    integrity: string;
}): Promise<boolean>;
/** The managed cf package directory when a verified install exists, else null. */
export declare function findManagedCf(configDir: string): Promise<string | null>;
/** Create `dir` 0700 if missing; refuse a symlink or non-directory in its place. */
export declare function ensurePrivateDir(dir: string): Promise<void>;
/** A CF_INSTALL_FAILED error that carries the redacted tail of npm's stderr. */
export declare class CfInstallError extends LocalCheckupError {
    readonly npmOutput: string[];
    constructor(message: string, npmOutput?: string[]);
}
/** The last lines of npm's stderr, dropping any line that could carry a registry credential. */
export declare function npmStderrTail(stderr: string, lines?: number): string[];
/** Remove `.staging-*` leftovers older than `maxAgeMs`; a younger one may belong to a concurrent install. */
export declare function removeStaleStaging(root: string, maxAgeMs?: number, now?: number): Promise<string[]>;
/**
 * Install the pinned cf into `<configDir>/cf/<version>/` and return its
 * package directory. Throws CF_INSTALL_FAILED (a `CfInstallError`) when npm
 * is missing or fails, or the result does not match the pin; the staging
 * directory is always removed (on Ctrl-C too).
 */
export declare function installManagedCf(options: {
    configDir: string;
    env: NodeJS.ProcessEnv;
    spawn?: SpawnFn;
    npmCli?: string | null;
    timeoutMs?: number;
    /** Replace a verified install too (it was found but cf could not run). */
    replace?: boolean;
    /** Runs first on Ctrl-C during the install (the caller stops its spinner). */
    onInterrupt?: () => void;
}): Promise<string>;
/** `logout`: remove every managed cf version (and any staging leftovers). */
export declare function removeManagedCf(configDir: string): Promise<{
    path: string;
    removed: boolean;
}>;
