import type { Scope, TypeAliasEntry, VariableType } from "../../types.js";
import type { CompilationUnit } from "../../compilationUnit.js";
/**
 * Owns the lexical scope stack and answers scope-related queries.
 *
 * The TypeScriptBuilder pushes a new scope every time it descends into a
 * function, graph node, or block body, and pops on exit. This class
 * centralises that bookkeeping plus the read-only queries that depend on
 * the current scope (return type, visible type aliases, scope-key for
 * symbol lookups, …) so callers can use a declarative API instead of
 * touching a raw array.
 *
 * `inSafeFunction` is tracked here because "safety" is a property of the
 * function currently being emitted, which conceptually belongs to the
 * scope stack.
 */
export declare class ScopeManager {
    private readonly compilationUnit;
    private stack;
    private _inSafeFunction;
    constructor(compilationUnit: CompilationUnit);
    push(scope: Scope): void;
    pop(): void;
    current(): Scope;
    /** Stable string key for the current scope (used for symbol/type-alias lookups). */
    currentKey(): string;
    /** Function, node, or block name; empty string for global. */
    currentName(): string;
    get inSafeFunction(): boolean;
    set inSafeFunction(value: boolean);
    visibleTypeAliases(): Record<string, VariableType>;
    /**
     * Full TypeAliasEntry-form alias registry for callers (resolveTypeDeep)
     * that need type-parameter metadata to substitute user-defined generic
     * aliases.
     */
    visibleTypeAliasesFull(): Record<string, TypeAliasEntry>;
    /**
     * Declared return type of the currently-executing function or graph node,
     * or `undefined` for global scope, a function with no annotation, or a
     * block scope.
     *
     * Block scopes (`fork(...) as item { ... }`, `guard(cost: $X) as { ... }`,
     * any `as { ... }` body) currently return `undefined` because we don't
     * carry the block's declared return type onto `Scope.block`. The only
     * caller that matters is `processLlmCall` for a `return llm(...)` inside
     * a block — and `processLlmCall` already defaults `undefined` to
     * `string` for structured-output inference. So today, a bare
     * `return llm(...)` from a block is always typed as `string`.
     *
     * Propagating the block's declared return type (from the enclosing
     * function's block-parameter signature) into the builder would require
     * either threading the parameter type through every `scopes.push({
     * type: "block", ... })` site or looking it up via the typechecker —
     * both substantial. Documented in docs/site/guide/llm.md as a known
     * limitation; users who want a non-string structured type should
     * assign the call: `const x: Foo = llm(...); return x`.
     */
    returnType(): VariableType | undefined;
    /** Whether the surrounding function/node opted-in to runtime return-type validation. */
    returnTypeValidated(): boolean;
}
