import type { PackageManagerType } from '@capgo/find-package-manager';
/**
 * Set on the re-exec'd child so the freshly-launched (already-updated) process
 * never re-prompts. Without this, a brief npm-registry propagation lag — where
 * the new version isn't yet visible to the child's own check — could cause an
 * infinite update → relaunch → update loop.
 */
export declare const SKIP_UPDATE_ENV = "CAPGO_SKIP_UPDATE_PROMPT";
type DependencySection = 'dependencies' | 'devDependencies' | 'optionalDependencies';
export interface CliDependencyDeclaration {
    packageJsonPath: string;
    section: DependencySection;
    range: string;
}
/**
 * Walk up from `startDir` (inclusive) to `rootDir` (inclusive) and return the
 * first package.json that declares @capgo/cli, with its section + range.
 *
 * In a monorepo this finds the app sub-package's declaration when present,
 * otherwise the workspace root's. Returns null when nothing on that path
 * declares the CLI — i.e. it was launched ephemerally (npx/bunx/dlx), so there
 * is no on-disk dependency to update.
 */
export declare function findCliDeclaration(startDir: string, rootDir: string): CliDependencyDeclaration | null;
/**
 * Resolve the on-disk entry script of the installed @capgo/cli by walking up
 * node_modules from `startDir` (hoisting-aware, so it finds the workspace-root
 * install in a monorepo). Returns the absolute path to the package's bin entry,
 * or null when the CLI isn't installed anywhere up the tree.
 */
export declare function resolveInstalledCliEntry(startDir: string): string | null;
/**
 * Bump a semver range to `latest` while preserving the caret/tilde prefix.
 * Dist-tag ranges ("latest"/"next"/"*"), workspace protocols, and anything
 * without a digit are returned unchanged — reinstalling already re-resolves
 * those, and we must not clobber an intentional tag with a pinned version.
 */
export declare function bumpRange(oldRange: string, latest: string): string;
/**
 * Pure transform: set @capgo/cli in `section` to the bumped range within the
 * given package.json text. Preserves 2-space indentation and the trailing
 * newline. Returns null when nothing changed (already at target / a tag range).
 */
export declare function applyCliBump(packageJsonText: string, section: DependencySection, latest: string): string | null;
export interface SpawnCommand {
    cmd: string;
    args: string[];
}
/**
 * Ephemeral re-exec (Path B): fetch + run the latest CLI through the project's
 * package-manager runner. npx needs `-y` to skip its "Ok to proceed?" install
 * prompt (which would deadlock an automated re-exec); bunx/pnpm dlx/yarn dlx
 * install non-interactively. The flag must precede the package spec so the
 * runner consumes it instead of forwarding it to `capgo`.
 */
export declare function buildEphemeralReexec(pm: PackageManagerType, forwardArgs: string[]): SpawnCommand;
/** `<pm> install`, run at the workspace root for Path A (reconciles the
 * lockfile after the package.json bump for npm/yarn/pnpm/bun workspaces). */
export declare function buildInstallCommand(pm: PackageManagerType): SpawnCommand;
export type UpdateStrategy = {
    kind: 'project';
    declaration: CliDependencyDeclaration;
    installRoot: string;
    entry: string;
} | {
    kind: 'ephemeral';
};
/**
 * Decide how to update based on how the running process resolved. Path A
 * (project) requires BOTH a declared dependency AND a resolvable local entry,
 * so we can re-exec the exact installed binary after `<pm> install`. Anything
 * else — including "declared but not installed" — falls back to Path B.
 */
export declare function classifyUpdateStrategy(opts: {
    installRoot: string;
    declaration: CliDependencyDeclaration | null;
    entry: string | null;
}): UpdateStrategy;
/**
 * Check whether a newer @capgo/cli is published, capped by a timeout so a slow
 * registry can't stall the wizard. Returns the version pair when an update is
 * available, or null when up to date / timed out / re-exec'd (the SKIP env is
 * set on the relaunched child to avoid an update→relaunch loop).
 *
 * The decision UI lives in the Ink wizard (ui/update-prompt.tsx) — this only
 * resolves the data the prompt needs. The install + re-exec is
 * runUpdateAndReexec, run AFTER Ink tears down.
 */
export declare function checkForCliUpdate(): Promise<{
    currentVersion: string;
    latestVersion: string;
} | null>;
export declare function runUpdateAndReexec(latest: string): void;
/**
 * Runner-aware "update manually" hint (e.g. `npx -y @capgo/cli@latest build
 * init`, `pnpm dlx @capgo/cli@latest build init`) for the fallback shown when
 * an accepted auto-update fails — so the suggested command matches the user's
 * package manager rather than hardcoding npx.
 */
export declare function manualUpdateHint(): string;
export {};
