import { type FilesystemPathIdentityContext } from "../../internal/projectInputPathIdentity";
interface ResolveResult {
    url: string;
    format?: string | null;
    shortCircuit?: boolean;
}
/**
 * The compiler options that decide the emit format of a file, as declared by
 * the project that emitted it. Both fields matter: tsgo derives the module kind
 * from `target` whenever `module` is absent, so carrying only `module` cannot
 * reproduce its decision.
 */
export interface OwningModuleOptions {
    module?: string;
    target?: string;
}
/**
 * Lowest Node.js the ttsx source runtime supports. The synchronous
 * `module.registerHooks` (Node 22.15.0) is the highest floor among the runtime
 * APIs these hooks depend on — `stripTypeScriptTypes` (22.13.0) and the child's
 * `--disable-warning` flag (20.11.0) are both lower — so it sets the effective
 * minimum. Kept in sync with `packages/ttsc/package.json#engines.node` and the
 * documented requirement in `website/src/content/docs/development/index.mdx`.
 */
export declare const TTSX_MINIMUM_NODE_VERSION = "22.15.0";
/**
 * Report why the running (or a candidate) Node.js version cannot execute the
 * ttsx source runtime, or `null` when it can. Returning an actionable message —
 * rather than letting the child die with an internal `TypeError` on the missing
 * `registerHooks`, or Node 18 rejecting `--disable-warning` with exit 9 — is
 * what turns an opaque internal failure into a clear version diagnostic.
 *
 * Exported for direct exercise by the ttsx e2e suite: the built launcher can
 * only be spawned under the Node version running the tests, so the boundary
 * around the floor cannot otherwise be pinned on CI.
 */
export declare function checkNodeRuntimeSupport(version: string): string | null;
/**
 * Install the source-loading hooks on the current (main) thread. Idempotent:
 * the bootstrap installs them for the entry process, and `NODE_OPTIONS`
 * re-imports the installer in every child process the program spawns — both may
 * run in the same process.
 *
 * Two hooks are needed, because `module.registerHooks` does not intercept a
 * `require()` made from inside a CommonJS module that was itself reached
 * through an ESM `import` (the interop translator loads it on the raw CJS
 * path). The ESM graph goes through `registerHooks`; the CommonJS `require`
 * graph goes through `Module._extensions` — the canonical loader extension
 * point `ts-node`/`tsx` use for the same reason.
 */
export declare function installRuntimeHooks(): void;
/**
 * The module format of the entry source file, derived from the entry project's
 * compiler options (via the runtime manifest) the same way the served files are
 * classified. The bootstrap uses it to load the entry through a CommonJS
 * `require` or an ESM `import`.
 */
export declare function entryModuleFormat(entryFile: string): "module" | "commonjs";
/**
 * Restore a `node:` builtin URL when affected Node releases return the exact
 * prefix-stripped spelling from their synchronous CommonJS resolver.
 *
 * Every other result passes through unchanged. In particular, a user hook that
 * intentionally remaps a `node:` specifier to another URL retains ownership of
 * that mapping, while ordinary and ESM builtin results already carrying the
 * scheme avoid an unnecessary copy.
 */
export declare function restoreStrippedNodeBuiltinScheme(specifier: string, result: ResolveResult): ResolveResult;
/** Cache of built projects keyed by owning tsconfig path. */
interface BuiltProject {
    emitDir: string;
    rootDir: string;
    emittedFiles?: readonly string[];
    moduleOptions: OwningModuleOptions;
}
/** Narrow a resolved project's compiler options to the emit-format pair. */
export declare function projectModuleOptions(compilerOptions: Record<string, unknown>): OwningModuleOptions;
/**
 * True when `real` is `directory` itself or sits beneath it. Handles a root
 * `directory` (`/`, `C:\`): naively appending a separator would yield `//`,
 * which no path starts with, so a root `rootDir` project would serve nothing.
 * Both sides are normalized to native separators first: a manifest `rootDir`
 * arrives slash-normalized from the synthesized tsconfig (`C:/` on Windows)
 * while `real` paths are native, and a raw prefix comparison across the two
 * forms silently never matches. Filesystem identity preserves ordinary Windows
 * aliases while keeping case-distinct paths under an opted-in directory
 * separate. Exported for direct exercise by the ttsx e2e suite — spawned runs
 * cannot pin both Windows case-semantics branches on CI.
 */
export declare function isWithin(real: string, directory: string, identities?: FilesystemPathIdentityContext): boolean;
/**
 * Reuse a dependency another process (or an earlier import) already built.
 *
 * The completion marker names the exact emit generation, so this reads metadata
 * and emit as one unit: it returns a hit only when the marker parses to a valid
 * generation AND that generation's directory holds emitted JavaScript. A reader
 * that runs while a replacement build is populating a DIFFERENT generation
 * directory keeps returning the previous complete generation until the atomic
 * marker swap points at the new one — never a mix of old metadata and a partial
 * new emit.
 *
 * Exported for the ttsx dependency-cache regressions.
 */
export declare function readDependencyCache(cacheDir: string, metaPath: string): BuiltProject | null;
/** Ownership token returned only to the process that acquired `current`. */
export type DependencyBuildLockLease = {
    generation: string;
};
/** Opaque identity of one observed lock generation. */
export type DependencyBuildLockFence = {
    generation: string;
};
/**
 * Atomically acquire the current generation of a dependency build lock, or
 * `null` when another process already holds it. Exported for the deterministic
 * multi-process cache regressions.
 */
export declare function acquireDependencyBuildLock(lockDir: string): DependencyBuildLockLease | null;
/** Retire a held generation during the holder's `finally`. */
export declare function releaseDependencyBuildLock(lockDir: string, lease: DependencyBuildLockLease): boolean;
/**
 * Retire exactly the generation carried by an abandoned observation. Exported
 * for the deterministic multi-process cache regressions.
 */
export declare function reclaimDependencyBuildLock(lockDir: string, fence: DependencyBuildLockFence): boolean;
/** One observation of a dependency build lock's state. */
export type DependencyBuildLockObservation = {
    state: "active";
    owner: string;
    fence: DependencyBuildLockFence;
} | {
    state: "abandoned";
    reason: string;
    fence: DependencyBuildLockFence;
} | {
    state: "released";
};
/**
 * Classify the current state of a dependency build lock directory. Exported for
 * the deterministic multi-process cache regressions.
 */
export declare function inspectDependencyBuildLock(lockDir: string, now: number): DependencyBuildLockObservation;
/**
 * The physical path, in the same spelling the launcher decided on.
 *
 * `realpathSync.native` first, because the plain implementation resolves
 * reparse points but leaves a Windows 8.3 component alone — and `TEMP` is
 * `C:\Users\RUNNER~1\...` on a GitHub Windows runner. The launcher resolves the
 * entry through `fs.realpathSync.native`, so answering here with the short name
 * would put a `..` in `path.relative(rootDir, real)`, drop the exact-mirror
 * lane, and leave the entry to whatever the trailing-stem matcher picks.
 */
export declare function realPath(target: string): string;
export {};
